1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_X86_ACRN_H 3 #define _ASM_X86_ACRN_H 4 5 #include <asm/cpuid/api.h> 6 7 /* 8 * This CPUID returns feature bitmaps in EAX. 9 * Guest VM uses this to detect the appropriate feature bit. 10 */ 11 #define ACRN_CPUID_FEATURES 0x40000001 12 /* Bit 0 indicates whether guest VM is privileged */ 13 #define ACRN_FEATURE_PRIVILEGED_VM BIT(0) 14 15 /* 16 * Timing Information. 17 * This leaf returns the current TSC frequency in kHz. 18 * 19 * EAX: (Virtual) TSC frequency in kHz. 20 * EBX, ECX, EDX: RESERVED (reserved fields are set to zero). 21 */ 22 #define ACRN_CPUID_TIMING_INFO 0x40000010 23 24 void acrn_setup_intr_handler(void (*handler)(void)); 25 void acrn_remove_intr_handler(void); 26 27 static inline u32 acrn_cpuid_base(void) 28 { 29 if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) 30 return cpuid_base_hypervisor("ACRNACRNACRN", 0); 31 32 return 0; 33 } 34 35 static inline unsigned long acrn_get_tsc_khz(void) 36 { 37 return cpuid_eax(ACRN_CPUID_TIMING_INFO); 38 } 39 40 /* 41 * Hypercalls for ACRN 42 * 43 * - VMCALL instruction is used to implement ACRN hypercalls. 44 * - ACRN hypercall ABI: 45 * - Hypercall number is passed in R8 register. 46 * - Up to 2 arguments are passed in RDI, RSI. 47 * - Return value will be placed in RAX. 48 * 49 * Because GCC doesn't support R8 register as direct register constraints, use 50 * supported constraint as input with a explicit MOV to R8 in beginning of asm. 51 */ 52 static inline long acrn_hypercall0(unsigned long hcall_id) 53 { 54 long result; 55 56 asm volatile("movl %1, %%r8d\n\t" 57 "vmcall\n\t" 58 : "=a" (result) 59 : "g" (hcall_id) 60 : "r8", "memory"); 61 62 return result; 63 } 64 65 static inline long acrn_hypercall1(unsigned long hcall_id, 66 unsigned long param1) 67 { 68 long result; 69 70 asm volatile("movl %1, %%r8d\n\t" 71 "vmcall\n\t" 72 : "=a" (result) 73 : "g" (hcall_id), "D" (param1) 74 : "r8", "memory"); 75 76 return result; 77 } 78 79 static inline long acrn_hypercall2(unsigned long hcall_id, 80 unsigned long param1, 81 unsigned long param2) 82 { 83 long result; 84 85 asm volatile("movl %1, %%r8d\n\t" 86 "vmcall\n\t" 87 : "=a" (result) 88 : "g" (hcall_id), "D" (param1), "S" (param2) 89 : "r8", "memory"); 90 91 return result; 92 } 93 94 #endif /* _ASM_X86_ACRN_H */ 95