xref: /kvm-unit-tests/x86/taskswitch.c (revision 761db0bd0f6c8f3fc7d5a3f7d78ba9e71f4854bd)
17d36db35SAvi Kivity /*
27d36db35SAvi Kivity  * Copyright 2010 Siemens AG
37d36db35SAvi Kivity  * Author: Jan Kiszka
47d36db35SAvi Kivity  *
57d36db35SAvi Kivity  * Released under GPLv2.
67d36db35SAvi Kivity  */
77d36db35SAvi Kivity 
87d36db35SAvi Kivity #include "libcflat.h"
9*761db0bdSAndrew Jones #include "x86/desc.h"
107d36db35SAvi Kivity 
115b0bf08bSPaolo Bonzini #define TSS_RETURN		(FIRST_SPARE_SEL)
127d36db35SAvi Kivity 
137d36db35SAvi Kivity void fault_entry(void);
147d36db35SAvi Kivity 
157d36db35SAvi Kivity static __attribute__((used, regparm(1))) void
167d36db35SAvi Kivity fault_handler(unsigned long error_code)
177d36db35SAvi Kivity {
185b0bf08bSPaolo Bonzini 	print_current_tss_info();
195b0bf08bSPaolo Bonzini 	printf("error code %x\n", error_code);
207d36db35SAvi Kivity 
215b0bf08bSPaolo Bonzini 	tss.eip += 2;
227d36db35SAvi Kivity 
235b0bf08bSPaolo Bonzini 	gdt32[TSS_MAIN / 8].access &= ~2;
247d36db35SAvi Kivity 
255b0bf08bSPaolo Bonzini 	set_gdt_task_gate(TSS_RETURN, tss_intr.prev);
267d36db35SAvi Kivity }
277d36db35SAvi Kivity 
287d36db35SAvi Kivity asm (
297d36db35SAvi Kivity 	"fault_entry:\n"
307d36db35SAvi Kivity 	"	mov (%esp),%eax\n"
317d36db35SAvi Kivity 	"	call fault_handler\n"
325b0bf08bSPaolo Bonzini 	"	jmp $" xstr(TSS_RETURN) ", $0\n"
337d36db35SAvi Kivity );
347d36db35SAvi Kivity 
357d36db35SAvi Kivity int main(int ac, char **av)
367d36db35SAvi Kivity {
377d36db35SAvi Kivity 	const long invalid_segment = 0x1234;
387d36db35SAvi Kivity 
395b0bf08bSPaolo Bonzini 	setup_tss32();
405b0bf08bSPaolo Bonzini 	set_intr_task_gate(13, fault_entry);
417d36db35SAvi Kivity 
427d36db35SAvi Kivity 	asm (
437d36db35SAvi Kivity 		"mov %0,%%es\n"
447d36db35SAvi Kivity 		: : "r" (invalid_segment) : "edi"
457d36db35SAvi Kivity 	);
467d36db35SAvi Kivity 
477d36db35SAvi Kivity 	printf("post fault\n");
487d36db35SAvi Kivity 
497d36db35SAvi Kivity 	return 0;
507d36db35SAvi Kivity }
51