xref: /kvm-unit-tests/x86/taskswitch.c (revision b006d7eb9c64ed1046041c4eb3c4077be11d8a3d)
1 /*
2  * Copyright 2010 Siemens AG
3  * Author: Jan Kiszka
4  *
5  * Released under GPLv2.
6  */
7 
8 #include "libcflat.h"
9 #include "x86/desc.h"
10 
11 #define TSS_RETURN		(FIRST_SPARE_SEL)
12 
13 void fault_entry(void);
14 
15 static __attribute__((used, regparm(1))) void
16 fault_handler(unsigned long error_code)
17 {
18 	print_current_tss_info();
19 	printf("error code %lx\n", error_code);
20 
21 	tss.eip += 2;
22 
23 	gdt32[TSS_MAIN / 8].access &= ~2;
24 
25 	set_gdt_task_gate(TSS_RETURN, tss_intr.prev);
26 }
27 
28 asm (
29 	"fault_entry:\n"
30 	"	mov (%esp),%eax\n"
31 	"	call fault_handler\n"
32 	"	jmp $" xstr(TSS_RETURN) ", $0\n"
33 );
34 
35 int main(int ac, char **av)
36 {
37 	const long invalid_segment = 0x1234;
38 
39 	setup_tss32();
40 	set_intr_task_gate(13, fault_entry);
41 
42 	asm (
43 		"mov %0,%%es\n"
44 		: : "r" (invalid_segment) : "edi"
45 	);
46 
47 	printf("post fault\n");
48 
49 	return 0;
50 }
51