xref: /linux/arch/x86/include/asm/acrn.h (revision 4b99990cdf9560e8a071640baf19f312e6ae02f4)
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