xref: /aosp_15_r20/external/ltp/testcases/kernel/kvm/include/kvm_x86.h (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2021 SUSE LLC <[email protected]>
4  *
5  * x86-specific KVM helper functions and structures
6  */
7 
8 #ifndef KVM_X86_H_
9 #define KVM_X86_H_
10 
11 #include "kvm_test.h"
12 
13 #define PAGESIZE 0x1000
14 #define KVM_GDT_SIZE 32
15 
16 /* Interrupts */
17 #define X86_INTR_COUNT 256
18 
19 #define INTR_ZERODIV 0
20 #define INTR_DEBUG 1
21 #define INTR_NMI 2
22 #define INTR_BREAKPOINT 3
23 #define INTR_OVERFLOW 4
24 #define INTR_BOUND_RANGE_EXC 5
25 #define INTR_BAD_OPCODE 6
26 #define INTR_DEVICE_ERROR 7
27 #define INTR_DOUBLE_FAULT 8
28 #define INTR_INVALID_TSS 10
29 #define INTR_SEGFAULT 11
30 #define INTR_STACK_FAULT 12
31 #define INTR_GPF 13
32 #define INTR_PAGE_FAULT 14
33 #define INTR_FPU_ERROR 16
34 #define INTR_ALIGNMENT_ERROR 17
35 #define INTR_MACHINE_CHECK 18
36 #define INTR_SIMD_ERROR 19
37 #define INTR_VIRT_ERROR 20
38 #define INTR_CPE 21
39 #define INTR_HV_INJECTION 28
40 #define INTR_VMM_COMM 29
41 #define INTR_SECURITY_ERROR 30
42 
43 
44 /* Segment descriptor flags */
45 #define SEGTYPE_LDT 0x02
46 #define SEGTYPE_TSS 0x09
47 #define SEGTYPE_TSS_BUSY 0x0b
48 #define SEGTYPE_CALL_GATE 0x0c
49 #define SEGTYPE_INTR_GATE 0x0e
50 #define SEGTYPE_TRAP_GATE 0x0f
51 #define SEGTYPE_RODATA 0x10
52 #define SEGTYPE_RWDATA 0x12
53 #define SEGTYPE_STACK 0x16
54 #define SEGTYPE_CODE 0x1a
55 #define SEGTYPE_MASK 0x1f
56 
57 #define SEGFLAG_NSYSTEM 0x10
58 #define SEGFLAG_PRESENT 0x80
59 #define SEGFLAG_CODE64 0x200
60 #define SEGFLAG_32BIT 0x400
61 #define SEGFLAG_PAGE_LIMIT 0x800
62 
63 
64 /* CPUID constants */
65 #define CPUID_GET_INPUT_RANGE 0x80000000
66 #define CPUID_GET_EXT_FEATURES 0x80000001
67 #define CPUID_GET_SVM_FEATURES 0x8000000a
68 
69 
70 /* Model-specific CPU register constants */
71 #define MSR_SYSENTER_CS 0x174
72 #define MSR_SYSENTER_ESP 0x175
73 #define MSR_SYSENTER_EIP 0x176
74 #define MSR_EFER 0xc0000080
75 #define MSR_STAR 0xc0000081
76 #define MSR_LSTAR 0xc0000082
77 #define MSR_CSTAR 0xc0000083
78 #define MSR_SFMASK 0xc0000084
79 #define MSR_FS_BASE 0xc0000100
80 #define MSR_GS_BASE 0xc0000101
81 #define MSR_KERNEL_GS_BASE 0xc0000102
82 #define MSR_VM_CR 0xc0010114
83 #define MSR_VM_HSAVE_PA 0xc0010117
84 
85 #define EFER_SCE (1 << 0)	/* SYSCALL/SYSRET instructions enabled */
86 #define EFER_LME (1 << 8)	/* CPU is running in 64bit mode */
87 #define EFER_LMA (1 << 10)	/* CPU uses 64bit memory paging (read-only) */
88 #define EFER_NXE (1 << 11)	/* Execute disable bit active */
89 #define EFER_SVME (1 << 12)	/* AMD SVM instructions enabled */
90 
91 #define VM_CR_DPD (1 << 0)
92 #define VM_CR_R_INIT (1 << 1)
93 #define VM_CR_DIS_A20M (1 << 2)
94 #define VM_CR_LOCK (1 << 3)
95 #define VM_CR_SVMDIS (1 << 4)
96 
97 /* Control register constants */
98 #define CR4_VME (1 << 0)
99 #define CR4_PVI (1 << 1)
100 #define CR4_TSD (1 << 2)
101 #define CR4_DE (1 << 3)
102 #define CR4_PSE (1 << 4)
103 #define CR4_PAE (1 << 5)
104 #define CR4_MCE (1 << 6)
105 #define CR4_PGE (1 << 7)
106 #define CR4_PCE (1 << 8)
107 #define CR4_OSFXSR (1 << 9)
108 #define CR4_OSXMMEXCPT (1 << 10)
109 #define CR4_UMIP (1 << 11)
110 #define CR4_LA57 (1 << 12)
111 #define CR4_VMXE (1 << 13)
112 #define CR4_SMXE (1 << 14)
113 #define CR4_FSGSBASE (1 << 16)
114 #define CR4_PCIDE (1 << 17)
115 #define CR4_OSXSAVE (1 << 18)
116 #define CR4_KL (1 << 19)
117 #define CR4_SMEP (1 << 20)
118 #define CR4_SMAP (1 << 21)
119 #define CR4_PKE (1 << 22)
120 #define CR4_CET (1 << 23)
121 #define CR4_PKS (1 << 24)
122 
123 struct intr_descriptor {
124 	uint16_t offset_lo;
125 	uint16_t selector;
126 	uint8_t ist;
127 	uint8_t flags;
128 #if defined(__x86_64__)
129 	uint64_t offset_hi; /* top 16 bits must be set to 0 */
130 	uint16_t padding;
131 #else /* defined(__x86_64__) */
132 	uint16_t offset_hi;
133 #endif /* defined(__x86_64__) */
134 } __attribute__((__packed__));
135 
136 struct segment_descriptor {
137 	unsigned int limit_lo : 16;
138 	unsigned int baseaddr_lo : 24;
139 	unsigned int flags_lo : 8;
140 	unsigned int limit_hi : 4;
141 	unsigned int flags_hi : 4;
142 	unsigned int baseaddr_hi : 8;
143 } __attribute__((__packed__));
144 
145 struct segment_descriptor64 {
146 	unsigned int limit_lo : 16;
147 	unsigned int baseaddr_lo : 24;
148 	unsigned int flags_lo : 8;
149 	unsigned int limit_hi : 4;
150 	unsigned int flags_hi : 4;
151 	uint64_t baseaddr_hi : 40;
152 	uint32_t reserved;
153 } __attribute__((__packed__));
154 
155 struct page_table_entry_pae {
156 	unsigned int present: 1;
157 	unsigned int writable: 1;
158 	unsigned int user_access: 1;
159 	unsigned int write_through: 1;
160 	unsigned int disable_cache: 1;
161 	unsigned int accessed: 1;
162 	unsigned int dirty: 1;
163 	unsigned int page_type: 1;
164 	unsigned int global: 1;
165 	unsigned int padding: 3;
166 	uint64_t address: 40;
167 	unsigned int padding2: 7;
168 	unsigned int prot_key: 4;
169 	unsigned int noexec: 1;
170 } __attribute__((__packed__));
171 
172 struct kvm_cpuid {
173 	unsigned int eax, ebx, ecx, edx;
174 };
175 
176 struct kvm_cregs {
177 	unsigned long cr0, cr2, cr3, cr4;
178 };
179 
180 struct kvm_sregs {
181 	uint16_t cs, ds, es, fs, gs, ss;
182 };
183 
184 struct kvm_regs64 {
185 	uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp;
186 	uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
187 };
188 
189 extern struct page_table_entry_pae kvm_pagetable[];
190 extern struct intr_descriptor kvm_idt[X86_INTR_COUNT];
191 extern struct segment_descriptor kvm_gdt[KVM_GDT_SIZE];
192 
193 /* Page table helper functions */
194 uintptr_t kvm_get_page_address_pae(const struct page_table_entry_pae *entry);
195 
196 /* Segment descriptor table functions */
197 void kvm_set_segment_descriptor(struct segment_descriptor *dst,
198 	uint64_t baseaddr, uint32_t limit, unsigned int flags);
199 void kvm_parse_segment_descriptor(struct segment_descriptor *src,
200 	uint64_t *baseaddr, uint32_t *limit, unsigned int *flags);
201 int kvm_find_free_descriptor(const struct segment_descriptor *table,
202 	size_t size);
203 unsigned int kvm_create_stack_descriptor(struct segment_descriptor *table,
204 	size_t tabsize, void *stack_base);
205 
206 /* Functions for querying CPU info and status */
207 void kvm_get_cpuid(unsigned int eax, unsigned int ecx, struct kvm_cpuid *buf);
208 void kvm_read_cregs(struct kvm_cregs *buf);
209 void kvm_read_sregs(struct kvm_sregs *buf);
210 uint64_t kvm_rdmsr(unsigned int msr);
211 void kvm_wrmsr(unsigned int msr, uint64_t value);
212 
213 /* Low-level interrupt handlers, DO NOT call directly */
214 void kvm_handle_bad_exception(void);
215 void kvm_handle_zerodiv(void);
216 void kvm_handle_debug(void);
217 void kvm_handle_nmi(void);
218 void kvm_handle_breakpoint(void);
219 void kvm_handle_overflow(void);
220 void kvm_handle_bound_range_exc(void);
221 void kvm_handle_bad_opcode(void);
222 void kvm_handle_device_error(void);
223 void kvm_handle_double_fault(void);
224 void kvm_handle_invalid_tss(void);
225 void kvm_handle_segfault(void);
226 void kvm_handle_stack_fault(void);
227 void kvm_handle_gpf(void);
228 void kvm_handle_page_fault(void);
229 void kvm_handle_fpu_error(void);
230 void kvm_handle_alignment_error(void);
231 void kvm_handle_machine_check(void);
232 void kvm_handle_simd_error(void);
233 void kvm_handle_virt_error(void);
234 void kvm_handle_cpe(void);
235 void kvm_handle_hv_injection(void);
236 void kvm_handle_vmm_comm(void);
237 void kvm_handle_security_error(void);
238 
239 #endif /* KVM_X86_H_ */
240