1c865f654SCornelia Huck #ifndef _X86_SMP_H_ 2c865f654SCornelia Huck #define _X86_SMP_H_ 3e5e3ed09SSean Christopherson 4e5e3ed09SSean Christopherson #include <stddef.h> 5cc47ddc1SAndrew Jones #include <asm/spinlock.h> 67d36db35SAvi Kivity 7e5e3ed09SSean Christopherson /* Offsets into the per-cpu page. */ 8e5e3ed09SSean Christopherson struct percpu_data { 9e5e3ed09SSean Christopherson uint32_t smp_id; 10e5e3ed09SSean Christopherson union { 11e5e3ed09SSean Christopherson struct { 12e5e3ed09SSean Christopherson uint8_t exception_vector; 13e5e3ed09SSean Christopherson uint8_t exception_rflags_rf; 14e5e3ed09SSean Christopherson uint16_t exception_error_code; 15e5e3ed09SSean Christopherson }; 16e5e3ed09SSean Christopherson uint32_t exception_data; 17e5e3ed09SSean Christopherson }; 18*2d18ccd3SSean Christopherson void *apic_ops; 19e5e3ed09SSean Christopherson }; 20e5e3ed09SSean Christopherson 21e5e3ed09SSean Christopherson #define typeof_percpu(name) typeof(((struct percpu_data *)0)->name) 22e5e3ed09SSean Christopherson #define offsetof_percpu(name) offsetof(struct percpu_data, name) 23e5e3ed09SSean Christopherson 24e5e3ed09SSean Christopherson #define BUILD_PERCPU_OP(name) \ 25e5e3ed09SSean Christopherson static inline typeof_percpu(name) this_cpu_read_##name(void) \ 26e5e3ed09SSean Christopherson { \ 27e5e3ed09SSean Christopherson typeof_percpu(name) val; \ 28e5e3ed09SSean Christopherson \ 29e5e3ed09SSean Christopherson switch (sizeof(val)) { \ 30e5e3ed09SSean Christopherson case 1: \ 31e5e3ed09SSean Christopherson asm("movb %%gs:%c1, %0" : "=q" (val) : "i" (offsetof_percpu(name))); \ 32e5e3ed09SSean Christopherson break; \ 33e5e3ed09SSean Christopherson case 2: \ 34e5e3ed09SSean Christopherson asm("movw %%gs:%c1, %0" : "=r" (val) : "i" (offsetof_percpu(name))); \ 35e5e3ed09SSean Christopherson break; \ 36e5e3ed09SSean Christopherson case 4: \ 37e5e3ed09SSean Christopherson asm("movl %%gs:%c1, %0" : "=r" (val) : "i" (offsetof_percpu(name))); \ 38e5e3ed09SSean Christopherson break; \ 39e5e3ed09SSean Christopherson case 8: \ 40e5e3ed09SSean Christopherson asm("movq %%gs:%c1, %0" : "=r" (val) : "i" (offsetof_percpu(name))); \ 41e5e3ed09SSean Christopherson break; \ 42e5e3ed09SSean Christopherson default: \ 43e5e3ed09SSean Christopherson asm volatile("ud2"); \ 44e5e3ed09SSean Christopherson } \ 45e5e3ed09SSean Christopherson return val; \ 46e5e3ed09SSean Christopherson } \ 47e5e3ed09SSean Christopherson static inline void this_cpu_write_##name(typeof_percpu(name) val) \ 48e5e3ed09SSean Christopherson { \ 49e5e3ed09SSean Christopherson switch (sizeof(val)) { \ 50e5e3ed09SSean Christopherson case 1: \ 51e5e3ed09SSean Christopherson asm("movb %0, %%gs:%c1" :: "q" (val), "i" (offsetof_percpu(name))); \ 52e5e3ed09SSean Christopherson break; \ 53e5e3ed09SSean Christopherson case 2: \ 54e5e3ed09SSean Christopherson asm("movw %0, %%gs:%c1" :: "r" (val), "i" (offsetof_percpu(name))); \ 55e5e3ed09SSean Christopherson break; \ 56e5e3ed09SSean Christopherson case 4: \ 57e5e3ed09SSean Christopherson asm("movl %0, %%gs:%c1" :: "r" (val), "i" (offsetof_percpu(name))); \ 58e5e3ed09SSean Christopherson break; \ 59e5e3ed09SSean Christopherson case 8: \ 60e5e3ed09SSean Christopherson asm("movq %0, %%gs:%c1" :: "r" (val), "i" (offsetof_percpu(name))); \ 61e5e3ed09SSean Christopherson break; \ 62e5e3ed09SSean Christopherson default: \ 63e5e3ed09SSean Christopherson asm volatile("ud2"); \ 64e5e3ed09SSean Christopherson } \ 65e5e3ed09SSean Christopherson } 66e5e3ed09SSean Christopherson BUILD_PERCPU_OP(smp_id); 67e5e3ed09SSean Christopherson BUILD_PERCPU_OP(exception_vector); 68e5e3ed09SSean Christopherson BUILD_PERCPU_OP(exception_rflags_rf); 69e5e3ed09SSean Christopherson BUILD_PERCPU_OP(exception_error_code); 70*2d18ccd3SSean Christopherson BUILD_PERCPU_OP(apic_ops); 71e5e3ed09SSean Christopherson 727d36db35SAvi Kivity void smp_init(void); 737d36db35SAvi Kivity 747d36db35SAvi Kivity int cpu_count(void); 757d36db35SAvi Kivity int smp_id(void); 76b73c7c6eSAndrew Jones int cpus_active(void); 777d36db35SAvi Kivity void on_cpu(int cpu, void (*function)(void *data), void *data); 787d36db35SAvi Kivity void on_cpu_async(int cpu, void (*function)(void *data), void *data); 79b73c7c6eSAndrew Jones void on_cpus(void (*function)(void *data), void *data); 8074e79380SPaolo Bonzini void smp_reset_apic(void); 817d36db35SAvi Kivity 827d36db35SAvi Kivity #endif 83