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