xref: /aosp_15_r20/external/ltp/testcases/kernel/kvm/kvm_svm04.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (C) 2023 SUSE LLC <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  */
5*49cdfc7eSAndroid Build Coastguard Worker 
6*49cdfc7eSAndroid Build Coastguard Worker /*\
7*49cdfc7eSAndroid Build Coastguard Worker  * [Description]
8*49cdfc7eSAndroid Build Coastguard Worker  *
9*49cdfc7eSAndroid Build Coastguard Worker  * Functional test for VMSAVE/VMLOAD instructions in KVM environment. Verify
10*49cdfc7eSAndroid Build Coastguard Worker  * that both instructions save/load the CPU state according to CPU
11*49cdfc7eSAndroid Build Coastguard Worker  * documentation.
12*49cdfc7eSAndroid Build Coastguard Worker  */
13*49cdfc7eSAndroid Build Coastguard Worker 
14*49cdfc7eSAndroid Build Coastguard Worker #include "kvm_test.h"
15*49cdfc7eSAndroid Build Coastguard Worker 
16*49cdfc7eSAndroid Build Coastguard Worker #ifdef COMPILE_PAYLOAD
17*49cdfc7eSAndroid Build Coastguard Worker #if defined(__i386__) || defined(__x86_64__)
18*49cdfc7eSAndroid Build Coastguard Worker 
19*49cdfc7eSAndroid Build Coastguard Worker #include "kvm_x86_svm.h"
20*49cdfc7eSAndroid Build Coastguard Worker 
21*49cdfc7eSAndroid Build Coastguard Worker static struct kvm_vmcb *src_vmcb, *dest_vmcb, *msr_vmcb;
22*49cdfc7eSAndroid Build Coastguard Worker static struct kvm_sregs sregs_buf;
23*49cdfc7eSAndroid Build Coastguard Worker 
check_descriptor(const char * name,const struct kvm_vmcb_descriptor * data,const struct kvm_vmcb_descriptor * exp)24*49cdfc7eSAndroid Build Coastguard Worker static int check_descriptor(const char *name,
25*49cdfc7eSAndroid Build Coastguard Worker 	const struct kvm_vmcb_descriptor *data,
26*49cdfc7eSAndroid Build Coastguard Worker 	const struct kvm_vmcb_descriptor *exp)
27*49cdfc7eSAndroid Build Coastguard Worker {
28*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
29*49cdfc7eSAndroid Build Coastguard Worker 
30*49cdfc7eSAndroid Build Coastguard Worker 	if (data->selector != exp->selector) {
31*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s.selector = %hx (expected %hx)",
32*49cdfc7eSAndroid Build Coastguard Worker 			name, data->selector, exp->selector);
33*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
34*49cdfc7eSAndroid Build Coastguard Worker 	}
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker 	if (data->attrib != exp->attrib) {
37*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s.attrib = 0x%hx (expected 0x%hx)",
38*49cdfc7eSAndroid Build Coastguard Worker 			name, data->attrib, exp->attrib);
39*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
40*49cdfc7eSAndroid Build Coastguard Worker 	}
41*49cdfc7eSAndroid Build Coastguard Worker 
42*49cdfc7eSAndroid Build Coastguard Worker 	if (data->limit != exp->limit) {
43*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s.limit = 0x%x (expected 0x%x)",
44*49cdfc7eSAndroid Build Coastguard Worker 			name, data->limit, exp->limit);
45*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
46*49cdfc7eSAndroid Build Coastguard Worker 	}
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker 	if (data->base != exp->base) {
49*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s.base = 0x%llx (expected 0x%llx)",
50*49cdfc7eSAndroid Build Coastguard Worker 			name, data->base, exp->base);
51*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
52*49cdfc7eSAndroid Build Coastguard Worker 	}
53*49cdfc7eSAndroid Build Coastguard Worker 
54*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
55*49cdfc7eSAndroid Build Coastguard Worker }
56*49cdfc7eSAndroid Build Coastguard Worker 
check_value(const char * name,uint64_t val,uint64_t exp,uint64_t backup,uint64_t reg,uint64_t nested_val)57*49cdfc7eSAndroid Build Coastguard Worker static int check_value(const char *name, uint64_t val, uint64_t exp,
58*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t backup, uint64_t reg, uint64_t nested_val)
59*49cdfc7eSAndroid Build Coastguard Worker {
60*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
61*49cdfc7eSAndroid Build Coastguard Worker 
62*49cdfc7eSAndroid Build Coastguard Worker 	if (exp != backup) {
63*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s source was modified (0x%llx != 0x%llx)",
64*49cdfc7eSAndroid Build Coastguard Worker 			name, exp, backup);
65*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
66*49cdfc7eSAndroid Build Coastguard Worker 	}
67*49cdfc7eSAndroid Build Coastguard Worker 
68*49cdfc7eSAndroid Build Coastguard Worker 	if (reg != exp) {
69*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s was not loaded (0x%llx != 0x%llx)",
70*49cdfc7eSAndroid Build Coastguard Worker 			name, reg, exp);
71*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
72*49cdfc7eSAndroid Build Coastguard Worker 	}
73*49cdfc7eSAndroid Build Coastguard Worker 
74*49cdfc7eSAndroid Build Coastguard Worker 	if (val != exp) {
75*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "%s was not saved (0x%llx != 0x%llx)",
76*49cdfc7eSAndroid Build Coastguard Worker 			name, val, exp);
77*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
78*49cdfc7eSAndroid Build Coastguard Worker 	}
79*49cdfc7eSAndroid Build Coastguard Worker 
80*49cdfc7eSAndroid Build Coastguard Worker 	if (val != nested_val) {
81*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "Inconsistent %s on VM exit (0x%llx != 0x%llx)",
82*49cdfc7eSAndroid Build Coastguard Worker 			name, val, nested_val);
83*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
84*49cdfc7eSAndroid Build Coastguard Worker 	}
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	if (!ret)
87*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "%s has correct value 0x%llx", name, val);
88*49cdfc7eSAndroid Build Coastguard Worker 
89*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
90*49cdfc7eSAndroid Build Coastguard Worker }
91*49cdfc7eSAndroid Build Coastguard Worker 
vmsave_copy(void)92*49cdfc7eSAndroid Build Coastguard Worker static int vmsave_copy(void)
93*49cdfc7eSAndroid Build Coastguard Worker {
94*49cdfc7eSAndroid Build Coastguard Worker 	kvm_svm_vmload(src_vmcb);
95*49cdfc7eSAndroid Build Coastguard Worker 	kvm_read_sregs(&sregs_buf);
96*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->star = kvm_rdmsr(MSR_STAR);
97*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->lstar = kvm_rdmsr(MSR_LSTAR);
98*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->cstar = kvm_rdmsr(MSR_CSTAR);
99*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->sfmask = kvm_rdmsr(MSR_SFMASK);
100*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->fs.base = kvm_rdmsr(MSR_FS_BASE);
101*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->gs.base = kvm_rdmsr(MSR_GS_BASE);
102*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->kernel_gs_base = kvm_rdmsr(MSR_KERNEL_GS_BASE);
103*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->sysenter_cs = kvm_rdmsr(MSR_SYSENTER_CS);
104*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->sysenter_esp = kvm_rdmsr(MSR_SYSENTER_ESP);
105*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb->sysenter_eip = kvm_rdmsr(MSR_SYSENTER_EIP);
106*49cdfc7eSAndroid Build Coastguard Worker 	kvm_svm_vmsave(dest_vmcb);
107*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
108*49cdfc7eSAndroid Build Coastguard Worker }
109*49cdfc7eSAndroid Build Coastguard Worker 
check_vmsave_result(struct kvm_vmcb * copy_vmcb,struct kvm_vmcb * nested_vmcb)110*49cdfc7eSAndroid Build Coastguard Worker static int check_vmsave_result(struct kvm_vmcb *copy_vmcb,
111*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_vmcb *nested_vmcb)
112*49cdfc7eSAndroid Build Coastguard Worker {
113*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
114*49cdfc7eSAndroid Build Coastguard Worker 
115*49cdfc7eSAndroid Build Coastguard Worker 	/* Nested VMCB is only compared to dest VMCB, bypass the check */
116*49cdfc7eSAndroid Build Coastguard Worker 	if (!nested_vmcb)
117*49cdfc7eSAndroid Build Coastguard Worker 		nested_vmcb = dest_vmcb;
118*49cdfc7eSAndroid Build Coastguard Worker 
119*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_descriptor("FS", &dest_vmcb->fs, &src_vmcb->fs);
120*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("FS.selector", dest_vmcb->fs.selector,
121*49cdfc7eSAndroid Build Coastguard Worker 		src_vmcb->fs.selector, copy_vmcb->fs.selector,
122*49cdfc7eSAndroid Build Coastguard Worker 		sregs_buf.fs, nested_vmcb->fs.selector) || ret;
123*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_descriptor("GS", &dest_vmcb->gs, &src_vmcb->gs) || ret;
124*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("GS.selector", dest_vmcb->gs.selector,
125*49cdfc7eSAndroid Build Coastguard Worker 		src_vmcb->gs.selector, copy_vmcb->gs.selector,
126*49cdfc7eSAndroid Build Coastguard Worker 		sregs_buf.gs, nested_vmcb->gs.selector) || ret;
127*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_descriptor("LDTR", &dest_vmcb->ldtr, &src_vmcb->ldtr) ||
128*49cdfc7eSAndroid Build Coastguard Worker 		ret;
129*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_descriptor("TR", &dest_vmcb->tr, &src_vmcb->tr) || ret;
130*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("STAR", dest_vmcb->star, src_vmcb->star,
131*49cdfc7eSAndroid Build Coastguard Worker 		copy_vmcb->star, msr_vmcb->star, nested_vmcb->star) || ret;
132*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("LSTAR", dest_vmcb->lstar, src_vmcb->lstar,
133*49cdfc7eSAndroid Build Coastguard Worker 		copy_vmcb->lstar, msr_vmcb->lstar, nested_vmcb->lstar) || ret;
134*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("CSTAR", dest_vmcb->cstar, src_vmcb->cstar,
135*49cdfc7eSAndroid Build Coastguard Worker 		copy_vmcb->cstar, msr_vmcb->cstar, nested_vmcb->cstar) || ret;
136*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("SFMASK", dest_vmcb->sfmask, src_vmcb->sfmask,
137*49cdfc7eSAndroid Build Coastguard Worker 		copy_vmcb->sfmask, msr_vmcb->sfmask, nested_vmcb->sfmask) ||
138*49cdfc7eSAndroid Build Coastguard Worker 		ret;
139*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("FS.base", dest_vmcb->fs.base, src_vmcb->fs.base,
140*49cdfc7eSAndroid Build Coastguard Worker 		copy_vmcb->fs.base, msr_vmcb->fs.base, nested_vmcb->fs.base) ||
141*49cdfc7eSAndroid Build Coastguard Worker 		ret;
142*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("GS.base", dest_vmcb->gs.base, src_vmcb->gs.base,
143*49cdfc7eSAndroid Build Coastguard Worker 		copy_vmcb->gs.base, msr_vmcb->gs.base, nested_vmcb->gs.base) ||
144*49cdfc7eSAndroid Build Coastguard Worker 		ret;
145*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("KernelGSBase", dest_vmcb->kernel_gs_base,
146*49cdfc7eSAndroid Build Coastguard Worker 		src_vmcb->kernel_gs_base, copy_vmcb->kernel_gs_base,
147*49cdfc7eSAndroid Build Coastguard Worker 		msr_vmcb->kernel_gs_base, nested_vmcb->kernel_gs_base) || ret;
148*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("Sysenter_CS", dest_vmcb->sysenter_cs,
149*49cdfc7eSAndroid Build Coastguard Worker 		src_vmcb->sysenter_cs, copy_vmcb->sysenter_cs,
150*49cdfc7eSAndroid Build Coastguard Worker 		msr_vmcb->sysenter_cs, nested_vmcb->sysenter_cs) || ret;
151*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("Sysenter_ESP", dest_vmcb->sysenter_esp,
152*49cdfc7eSAndroid Build Coastguard Worker 		src_vmcb->sysenter_esp, copy_vmcb->sysenter_esp,
153*49cdfc7eSAndroid Build Coastguard Worker 		msr_vmcb->sysenter_esp, nested_vmcb->sysenter_esp) || ret;
154*49cdfc7eSAndroid Build Coastguard Worker 	ret = check_value("Sysenter_EIP", dest_vmcb->sysenter_eip,
155*49cdfc7eSAndroid Build Coastguard Worker 		src_vmcb->sysenter_eip, copy_vmcb->sysenter_eip,
156*49cdfc7eSAndroid Build Coastguard Worker 		msr_vmcb->sysenter_eip, nested_vmcb->sysenter_eip) || ret;
157*49cdfc7eSAndroid Build Coastguard Worker 
158*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
159*49cdfc7eSAndroid Build Coastguard Worker }
160*49cdfc7eSAndroid Build Coastguard Worker 
create_segment_descriptor(uint64_t baseaddr,uint32_t limit,unsigned int flags)161*49cdfc7eSAndroid Build Coastguard Worker static int create_segment_descriptor(uint64_t baseaddr, uint32_t limit,
162*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int flags)
163*49cdfc7eSAndroid Build Coastguard Worker {
164*49cdfc7eSAndroid Build Coastguard Worker 	int ret = kvm_find_free_descriptor(kvm_gdt, KVM_GDT_SIZE);
165*49cdfc7eSAndroid Build Coastguard Worker 
166*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0)
167*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Descriptor table is full");
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 	kvm_set_segment_descriptor(kvm_gdt + ret, baseaddr, limit, flags);
170*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
171*49cdfc7eSAndroid Build Coastguard Worker }
172*49cdfc7eSAndroid Build Coastguard Worker 
dirty_vmcb(struct kvm_vmcb * buf)173*49cdfc7eSAndroid Build Coastguard Worker static void dirty_vmcb(struct kvm_vmcb *buf)
174*49cdfc7eSAndroid Build Coastguard Worker {
175*49cdfc7eSAndroid Build Coastguard Worker 	buf->fs.selector = 0x60;
176*49cdfc7eSAndroid Build Coastguard Worker 	buf->fs.attrib = SEGTYPE_RWDATA | SEGFLAG_PRESENT;
177*49cdfc7eSAndroid Build Coastguard Worker 	buf->fs.limit = 0xffff;
178*49cdfc7eSAndroid Build Coastguard Worker 	buf->fs.base = 0xfff000;
179*49cdfc7eSAndroid Build Coastguard Worker 	buf->gs.selector = 0x68;
180*49cdfc7eSAndroid Build Coastguard Worker 	buf->gs.attrib = SEGTYPE_RWDATA | SEGFLAG_PRESENT;
181*49cdfc7eSAndroid Build Coastguard Worker 	buf->gs.limit = 0xffff;
182*49cdfc7eSAndroid Build Coastguard Worker 	buf->gs.base = 0xfff000;
183*49cdfc7eSAndroid Build Coastguard Worker 	buf->ldtr.selector = 0x70;
184*49cdfc7eSAndroid Build Coastguard Worker 	buf->ldtr.attrib = SEGTYPE_LDT | SEGFLAG_PRESENT;
185*49cdfc7eSAndroid Build Coastguard Worker 	buf->ldtr.limit = 0xffff;
186*49cdfc7eSAndroid Build Coastguard Worker 	buf->ldtr.base = 0xfff000;
187*49cdfc7eSAndroid Build Coastguard Worker 	buf->tr.selector = 0x78;
188*49cdfc7eSAndroid Build Coastguard Worker 	buf->tr.attrib = SEGTYPE_TSS | SEGFLAG_PRESENT;
189*49cdfc7eSAndroid Build Coastguard Worker 	buf->tr.limit = 0xffff;
190*49cdfc7eSAndroid Build Coastguard Worker 	buf->tr.base = 0xfff000;
191*49cdfc7eSAndroid Build Coastguard Worker 	buf->star = 0xffff;
192*49cdfc7eSAndroid Build Coastguard Worker 	buf->lstar = 0xffff;
193*49cdfc7eSAndroid Build Coastguard Worker 	buf->cstar = 0xffff;
194*49cdfc7eSAndroid Build Coastguard Worker 	buf->sfmask = 0xffff;
195*49cdfc7eSAndroid Build Coastguard Worker 	buf->fs.base = 0xffff;
196*49cdfc7eSAndroid Build Coastguard Worker 	buf->gs.base = 0xffff;
197*49cdfc7eSAndroid Build Coastguard Worker 	buf->kernel_gs_base = 0xffff;
198*49cdfc7eSAndroid Build Coastguard Worker 	buf->sysenter_cs = 0xffff;
199*49cdfc7eSAndroid Build Coastguard Worker 	buf->sysenter_esp = 0xffff;
200*49cdfc7eSAndroid Build Coastguard Worker 	buf->sysenter_eip = 0xffff;
201*49cdfc7eSAndroid Build Coastguard Worker }
202*49cdfc7eSAndroid Build Coastguard Worker 
main(void)203*49cdfc7eSAndroid Build Coastguard Worker void main(void)
204*49cdfc7eSAndroid Build Coastguard Worker {
205*49cdfc7eSAndroid Build Coastguard Worker 	uint16_t ss;
206*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t rsp;
207*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_svm_vcpu *vcpu;
208*49cdfc7eSAndroid Build Coastguard Worker 	int data_seg1, data_seg2, ldt_seg, task_seg;
209*49cdfc7eSAndroid Build Coastguard Worker 	struct segment_descriptor *ldt;
210*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_vmcb *backup_vmcb, *zero_vmcb;
211*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int ldt_size = KVM_GDT_SIZE*sizeof(struct segment_descriptor);
212*49cdfc7eSAndroid Build Coastguard Worker 
213*49cdfc7eSAndroid Build Coastguard Worker 	kvm_init_svm();
214*49cdfc7eSAndroid Build Coastguard Worker 
215*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb = kvm_alloc_vmcb();
216*49cdfc7eSAndroid Build Coastguard Worker 	dest_vmcb = kvm_alloc_vmcb();
217*49cdfc7eSAndroid Build Coastguard Worker 	msr_vmcb = kvm_alloc_vmcb();
218*49cdfc7eSAndroid Build Coastguard Worker 	backup_vmcb = kvm_alloc_vmcb();
219*49cdfc7eSAndroid Build Coastguard Worker 	zero_vmcb = kvm_alloc_vmcb();
220*49cdfc7eSAndroid Build Coastguard Worker 
221*49cdfc7eSAndroid Build Coastguard Worker 	vcpu = kvm_create_svm_vcpu(vmsave_copy, 1);
222*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_VMLOAD, 0);
223*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_VMSAVE, 0);
224*49cdfc7eSAndroid Build Coastguard Worker 	/* Save allocated stack for later VM reinit */
225*49cdfc7eSAndroid Build Coastguard Worker 	ss = vcpu->vmcb->ss.selector >> 3;
226*49cdfc7eSAndroid Build Coastguard Worker 	rsp = vcpu->vmcb->rsp;
227*49cdfc7eSAndroid Build Coastguard Worker 
228*49cdfc7eSAndroid Build Coastguard Worker 	ldt = tst_heap_alloc_aligned(ldt_size, 8);
229*49cdfc7eSAndroid Build Coastguard Worker 	memset(ldt, 0, ldt_size);
230*49cdfc7eSAndroid Build Coastguard Worker 	data_seg1 = create_segment_descriptor(0xda7a1000, 0x1000,
231*49cdfc7eSAndroid Build Coastguard Worker 		SEGTYPE_RODATA | SEGFLAG_PRESENT);
232*49cdfc7eSAndroid Build Coastguard Worker 	data_seg2 = create_segment_descriptor(0xda7a2000, 2,
233*49cdfc7eSAndroid Build Coastguard Worker 		SEGTYPE_RWDATA | SEGFLAG_PRESENT | SEGFLAG_PAGE_LIMIT);
234*49cdfc7eSAndroid Build Coastguard Worker 	ldt_seg = create_segment_descriptor((uintptr_t)ldt, ldt_size,
235*49cdfc7eSAndroid Build Coastguard Worker 		SEGTYPE_LDT | SEGFLAG_PRESENT);
236*49cdfc7eSAndroid Build Coastguard Worker 	task_seg = create_segment_descriptor(0x7a53000, 0x1000,
237*49cdfc7eSAndroid Build Coastguard Worker 		SEGTYPE_TSS | SEGFLAG_PRESENT);
238*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_copy_gdt_descriptor(&src_vmcb->fs, data_seg1);
239*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_copy_gdt_descriptor(&src_vmcb->gs, data_seg2);
240*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_copy_gdt_descriptor(&src_vmcb->ldtr, ldt_seg);
241*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_copy_gdt_descriptor(&src_vmcb->tr, task_seg);
242*49cdfc7eSAndroid Build Coastguard Worker 
243*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->star = 0x5742;
244*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->lstar = 0x15742;
245*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->cstar = 0xc5742;
246*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->sfmask = 0xf731;
247*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->fs.base = 0xf000;
248*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->gs.base = 0x10000;
249*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->kernel_gs_base = 0x20000;
250*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->sysenter_cs = 0x595c5;
251*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->sysenter_esp = 0x595e50;
252*49cdfc7eSAndroid Build Coastguard Worker 	src_vmcb->sysenter_eip = 0x595e10;
253*49cdfc7eSAndroid Build Coastguard Worker 
254*49cdfc7eSAndroid Build Coastguard Worker 	memcpy(backup_vmcb, src_vmcb, sizeof(struct kvm_vmcb));
255*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "VMLOAD/VMSAVE non-zero values");
256*49cdfc7eSAndroid Build Coastguard Worker 	vmsave_copy();
257*49cdfc7eSAndroid Build Coastguard Worker 	check_vmsave_result(backup_vmcb, NULL);
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker 	memset(src_vmcb, 0, sizeof(struct kvm_vmcb));
260*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "VMLOAD/VMSAVE zero values");
261*49cdfc7eSAndroid Build Coastguard Worker 	dirty_vmcb(dest_vmcb);
262*49cdfc7eSAndroid Build Coastguard Worker 	vmsave_copy();
263*49cdfc7eSAndroid Build Coastguard Worker 	check_vmsave_result(zero_vmcb, NULL);
264*49cdfc7eSAndroid Build Coastguard Worker 
265*49cdfc7eSAndroid Build Coastguard Worker 	memcpy(src_vmcb, backup_vmcb, sizeof(struct kvm_vmcb));
266*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Nested VMLOAD/VMSAVE non-zero values");
267*49cdfc7eSAndroid Build Coastguard Worker 	dirty_vmcb(vcpu->vmcb);
268*49cdfc7eSAndroid Build Coastguard Worker 	memset(dest_vmcb, 0, sizeof(struct kvm_vmcb));
269*49cdfc7eSAndroid Build Coastguard Worker 	kvm_svm_vmrun(vcpu);
270*49cdfc7eSAndroid Build Coastguard Worker 
271*49cdfc7eSAndroid Build Coastguard Worker 	if (vcpu->vmcb->exitcode != SVM_EXIT_HLT)
272*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Nested VM exited unexpectedly");
273*49cdfc7eSAndroid Build Coastguard Worker 
274*49cdfc7eSAndroid Build Coastguard Worker 	check_vmsave_result(backup_vmcb, vcpu->vmcb);
275*49cdfc7eSAndroid Build Coastguard Worker 
276*49cdfc7eSAndroid Build Coastguard Worker 	memset(src_vmcb, 0, sizeof(struct kvm_vmcb));
277*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Nested VMLOAD/VMSAVE zero values");
278*49cdfc7eSAndroid Build Coastguard Worker 	kvm_init_guest_vmcb(vcpu->vmcb, 1, ss, (void *)rsp, vmsave_copy);
279*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_VMLOAD, 0);
280*49cdfc7eSAndroid Build Coastguard Worker 	kvm_vmcb_set_intercept(vcpu->vmcb, SVM_INTERCEPT_VMSAVE, 0);
281*49cdfc7eSAndroid Build Coastguard Worker 	dirty_vmcb(vcpu->vmcb);
282*49cdfc7eSAndroid Build Coastguard Worker 	kvm_svm_vmrun(vcpu);
283*49cdfc7eSAndroid Build Coastguard Worker 
284*49cdfc7eSAndroid Build Coastguard Worker 	if (vcpu->vmcb->exitcode != SVM_EXIT_HLT)
285*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Nested VM exited unexpectedly");
286*49cdfc7eSAndroid Build Coastguard Worker 
287*49cdfc7eSAndroid Build Coastguard Worker 	check_vmsave_result(zero_vmcb, vcpu->vmcb);
288*49cdfc7eSAndroid Build Coastguard Worker }
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker #else /* defined(__i386__) || defined(__x86_64__) */
291*49cdfc7eSAndroid Build Coastguard Worker TST_TEST_TCONF("Test supported only on x86");
292*49cdfc7eSAndroid Build Coastguard Worker #endif /* defined(__i386__) || defined(__x86_64__) */
293*49cdfc7eSAndroid Build Coastguard Worker 
294*49cdfc7eSAndroid Build Coastguard Worker #else /* COMPILE_PAYLOAD */
295*49cdfc7eSAndroid Build Coastguard Worker 
296*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
297*49cdfc7eSAndroid Build Coastguard Worker 	.test_all = tst_kvm_run,
298*49cdfc7eSAndroid Build Coastguard Worker 	.setup = tst_kvm_setup,
299*49cdfc7eSAndroid Build Coastguard Worker 	.cleanup = tst_kvm_cleanup,
300*49cdfc7eSAndroid Build Coastguard Worker 	.supported_archs = (const char *const []) {
301*49cdfc7eSAndroid Build Coastguard Worker 		"x86_64",
302*49cdfc7eSAndroid Build Coastguard Worker 		"x86",
303*49cdfc7eSAndroid Build Coastguard Worker 		NULL
304*49cdfc7eSAndroid Build Coastguard Worker 	},
305*49cdfc7eSAndroid Build Coastguard Worker };
306*49cdfc7eSAndroid Build Coastguard Worker 
307*49cdfc7eSAndroid Build Coastguard Worker #endif /* COMPILE_PAYLOAD */
308