Re: [Xen-devel] [PATCH 08/22] mini-os: initialize trap handling for HVMlite
Juergen Gross, on Tue 23 Aug 2016 17:15:54 +0200, wrote: > Trap handling for HVMlite domains requires an initialized IDT. > > Signed-off-by: Juergen GrossReviewed-by: Samuel Thibault > --- > arch/x86/setup.c | 15 -- > arch/x86/traps.c | 88 > +++ > arch/x86/x86_64.S | 4 +++ > include/x86/os.h | 1 + > 4 files changed, 93 insertions(+), 15 deletions(-) > > diff --git a/arch/x86/setup.c b/arch/x86/setup.c > index edc4ca4..efecefb 100644 > --- a/arch/x86/setup.c > +++ b/arch/x86/setup.c > @@ -52,10 +52,6 @@ char stack[2*STACK_SIZE]; > > extern char shared_info[PAGE_SIZE]; > > -/* Assembler interface fns in entry.S. */ > -void hypervisor_callback(void); > -void failsafe_callback(void); > - > #if defined(__x86_64__) > #define __pte(x) ((pte_t) { (x) } ) > #else > @@ -162,17 +158,6 @@ arch_init(void *par) > /* Grab the shared_info pointer and put it in a safe place. */ > HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); > > - /* Set up event and failsafe callback addresses. */ > -#ifdef __i386__ > - HYPERVISOR_set_callbacks( > - __KERNEL_CS, (unsigned long)hypervisor_callback, > - __KERNEL_CS, (unsigned long)failsafe_callback); > -#else > - HYPERVISOR_set_callbacks( > - (unsigned long)hypervisor_callback, > - (unsigned long)failsafe_callback, 0); > -#endif > - > start_kernel(); > } > > diff --git a/arch/x86/traps.c b/arch/x86/traps.c > index 307a14c..3b1fffb 100644 > --- a/arch/x86/traps.c > +++ b/arch/x86/traps.c > @@ -1,10 +1,12 @@ > > #include > #include > +#include > #include > #include > #include > #include > +#include > > /* > * These are assembler stubs in entry.S. > @@ -293,6 +295,11 @@ void do_spurious_interrupt_bug(struct pt_regs * regs) > { > } > > +/* Assembler interface fns in entry.S. */ > +void hypervisor_callback(void); > +void failsafe_callback(void); > + > +#ifdef CONFIG_PARAVIRT > /* > * Submit a virtual IDT to teh hypervisor. This consists of tuples > * (interrupt vector, privilege ring, CS:EIP of handler). > @@ -325,9 +332,90 @@ static trap_info_t trap_table[] = { > void trap_init(void) > { > HYPERVISOR_set_trap_table(trap_table); > + > +#ifdef __i386__ > +HYPERVISOR_set_callbacks( > +__KERNEL_CS, (unsigned long)hypervisor_callback, > +__KERNEL_CS, (unsigned long)failsafe_callback); > +#else > +HYPERVISOR_set_callbacks( > +(unsigned long)hypervisor_callback, > +(unsigned long)failsafe_callback, 0); > +#endif > } > > void trap_fini(void) > { > HYPERVISOR_set_trap_table(NULL); > } > +#else > + > +#define INTR_STACK_SIZE PAGE_SIZE > +static uint8_t intr_stack[INTR_STACK_SIZE] __attribute__((aligned(16))); > + > +hw_tss tss __attribute__((aligned(16))) = > +{ > +#if defined(__i386__) > +.esp0 = (unsigned long)_stack[INTR_STACK_SIZE], > +.ss0 = __KERN_DS, > +#elif defined(__x86_64__) > +.rsp0 = (unsigned long)_stack[INTR_STACK_SIZE], > +#endif > +.iopb = X86_TSS_INVALID_IO_BITMAP, > +}; > + > +static void setup_gate(unsigned int entry, void *addr, unsigned int dpl) > +{ > +idt[entry].offset0 = (unsigned long)addr & 0x; > +idt[entry].selector = __KERN_CS; > +idt[entry]._r0 = 0; > +idt[entry].type = 14; > +idt[entry].s = 0; > +idt[entry].dpl = dpl; > +idt[entry].p = 1; > +idt[entry].offset1 = ((unsigned long)addr >> 16) & 0x; > +#if defined(__x86_64__) > +idt[entry].ist = 0; > +idt[entry].offset2 = ((unsigned long)addr >> 32) & 0xu; > +idt[entry]._r1 = 0; > +#endif > +} > + > +void trap_init(void) > +{ > +setup_gate(TRAP_divide_error, _error, 0); > +setup_gate(TRAP_debug, , 0); > +setup_gate(TRAP_int3, , 3); > +setup_gate(TRAP_overflow, , 3); > +setup_gate(TRAP_bounds, , 0); > +setup_gate(TRAP_invalid_op, _op, 0); > +setup_gate(TRAP_no_device, _not_available, 0); > +setup_gate(TRAP_copro_seg, _segment_overrun, 0); > +setup_gate(TRAP_invalid_tss, _TSS, 0); > +setup_gate(TRAP_no_segment, _not_present, 0); > +setup_gate(TRAP_stack_error, _segment, 0); > +setup_gate(TRAP_gp_fault, _protection, 0); > +setup_gate(TRAP_page_fault, _fault, 0); > +setup_gate(TRAP_spurious_int, _interrupt_bug, 0); > +setup_gate(TRAP_copro_error, _error, 0); > +setup_gate(TRAP_alignment_check, _check, 0); > +setup_gate(TRAP_simd_error, _coprocessor_error, 0); > +setup_gate(TRAP_xen_callback, hypervisor_callback, 0); > + > +asm volatile ("lidt idt_ptr"); > + > +gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89); > +asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8)); > + > +if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, > + (2ULL << 56) | TRAP_xen_callback) ) > +{ > +xprintk("Request for Xen
[Xen-devel] [PATCH 08/22] mini-os: initialize trap handling for HVMlite
Trap handling for HVMlite domains requires an initialized IDT. Signed-off-by: Juergen Gross--- arch/x86/setup.c | 15 -- arch/x86/traps.c | 88 +++ arch/x86/x86_64.S | 4 +++ include/x86/os.h | 1 + 4 files changed, 93 insertions(+), 15 deletions(-) diff --git a/arch/x86/setup.c b/arch/x86/setup.c index edc4ca4..efecefb 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -52,10 +52,6 @@ char stack[2*STACK_SIZE]; extern char shared_info[PAGE_SIZE]; -/* Assembler interface fns in entry.S. */ -void hypervisor_callback(void); -void failsafe_callback(void); - #if defined(__x86_64__) #define __pte(x) ((pte_t) { (x) } ) #else @@ -162,17 +158,6 @@ arch_init(void *par) /* Grab the shared_info pointer and put it in a safe place. */ HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); - /* Set up event and failsafe callback addresses. */ -#ifdef __i386__ - HYPERVISOR_set_callbacks( - __KERNEL_CS, (unsigned long)hypervisor_callback, - __KERNEL_CS, (unsigned long)failsafe_callback); -#else - HYPERVISOR_set_callbacks( - (unsigned long)hypervisor_callback, - (unsigned long)failsafe_callback, 0); -#endif - start_kernel(); } diff --git a/arch/x86/traps.c b/arch/x86/traps.c index 307a14c..3b1fffb 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -1,10 +1,12 @@ #include #include +#include #include #include #include #include +#include /* * These are assembler stubs in entry.S. @@ -293,6 +295,11 @@ void do_spurious_interrupt_bug(struct pt_regs * regs) { } +/* Assembler interface fns in entry.S. */ +void hypervisor_callback(void); +void failsafe_callback(void); + +#ifdef CONFIG_PARAVIRT /* * Submit a virtual IDT to teh hypervisor. This consists of tuples * (interrupt vector, privilege ring, CS:EIP of handler). @@ -325,9 +332,90 @@ static trap_info_t trap_table[] = { void trap_init(void) { HYPERVISOR_set_trap_table(trap_table); + +#ifdef __i386__ +HYPERVISOR_set_callbacks( +__KERNEL_CS, (unsigned long)hypervisor_callback, +__KERNEL_CS, (unsigned long)failsafe_callback); +#else +HYPERVISOR_set_callbacks( +(unsigned long)hypervisor_callback, +(unsigned long)failsafe_callback, 0); +#endif } void trap_fini(void) { HYPERVISOR_set_trap_table(NULL); } +#else + +#define INTR_STACK_SIZE PAGE_SIZE +static uint8_t intr_stack[INTR_STACK_SIZE] __attribute__((aligned(16))); + +hw_tss tss __attribute__((aligned(16))) = +{ +#if defined(__i386__) +.esp0 = (unsigned long)_stack[INTR_STACK_SIZE], +.ss0 = __KERN_DS, +#elif defined(__x86_64__) +.rsp0 = (unsigned long)_stack[INTR_STACK_SIZE], +#endif +.iopb = X86_TSS_INVALID_IO_BITMAP, +}; + +static void setup_gate(unsigned int entry, void *addr, unsigned int dpl) +{ +idt[entry].offset0 = (unsigned long)addr & 0x; +idt[entry].selector = __KERN_CS; +idt[entry]._r0 = 0; +idt[entry].type = 14; +idt[entry].s = 0; +idt[entry].dpl = dpl; +idt[entry].p = 1; +idt[entry].offset1 = ((unsigned long)addr >> 16) & 0x; +#if defined(__x86_64__) +idt[entry].ist = 0; +idt[entry].offset2 = ((unsigned long)addr >> 32) & 0xu; +idt[entry]._r1 = 0; +#endif +} + +void trap_init(void) +{ +setup_gate(TRAP_divide_error, _error, 0); +setup_gate(TRAP_debug, , 0); +setup_gate(TRAP_int3, , 3); +setup_gate(TRAP_overflow, , 3); +setup_gate(TRAP_bounds, , 0); +setup_gate(TRAP_invalid_op, _op, 0); +setup_gate(TRAP_no_device, _not_available, 0); +setup_gate(TRAP_copro_seg, _segment_overrun, 0); +setup_gate(TRAP_invalid_tss, _TSS, 0); +setup_gate(TRAP_no_segment, _not_present, 0); +setup_gate(TRAP_stack_error, _segment, 0); +setup_gate(TRAP_gp_fault, _protection, 0); +setup_gate(TRAP_page_fault, _fault, 0); +setup_gate(TRAP_spurious_int, _interrupt_bug, 0); +setup_gate(TRAP_copro_error, _error, 0); +setup_gate(TRAP_alignment_check, _check, 0); +setup_gate(TRAP_simd_error, _coprocessor_error, 0); +setup_gate(TRAP_xen_callback, hypervisor_callback, 0); + +asm volatile ("lidt idt_ptr"); + +gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89); +asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8)); + +if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, + (2ULL << 56) | TRAP_xen_callback) ) +{ +xprintk("Request for Xen HVM callback vector failed\n"); +do_exit(); +} +} + +void trap_fini(void) +{ +} +#endif diff --git a/arch/x86/x86_64.S b/arch/x86/x86_64.S index 373f400..e725c63 100644 --- a/arch/x86/x86_64.S +++ b/arch/x86/x86_64.S @@ -130,18 +130,22 @@ KERNEL_CS_MASK = 0xfc .endm .macro HYPERVISOR_IRET flag +#ifdef CONFIG_PARAVIRT testl $NMI_MASK,2*8(%rsp) jnz 2f +#endif /* Direct