[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 08/22] mini-os: initialize trap handling for HVMlite
Trap handling for HVMlite domains requires an initialized IDT. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> --- 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 <mini-os/os.h> #include <mini-os/traps.h> +#include <mini-os/desc.h> #include <mini-os/hypervisor.h> #include <mini-os/mm.h> #include <mini-os/lib.h> #include <mini-os/sched.h> +#include <xen/hvm/params.h> /* * 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)&intr_stack[INTR_STACK_SIZE], + .ss0 = __KERN_DS, +#elif defined(__x86_64__) + .rsp0 = (unsigned long)&intr_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 & 0xffff; + 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) & 0xffff; +#if defined(__x86_64__) + idt[entry].ist = 0; + idt[entry].offset2 = ((unsigned long)addr >> 32) & 0xffffffffu; + idt[entry]._r1 = 0; +#endif +} + +void trap_init(void) +{ + setup_gate(TRAP_divide_error, ÷_error, 0); + setup_gate(TRAP_debug, &debug, 0); + setup_gate(TRAP_int3, &int3, 3); + setup_gate(TRAP_overflow, &overflow, 3); + setup_gate(TRAP_bounds, &bounds, 0); + setup_gate(TRAP_invalid_op, &invalid_op, 0); + setup_gate(TRAP_no_device, &device_not_available, 0); + setup_gate(TRAP_copro_seg, &coprocessor_segment_overrun, 0); + setup_gate(TRAP_invalid_tss, &invalid_TSS, 0); + setup_gate(TRAP_no_segment, &segment_not_present, 0); + setup_gate(TRAP_stack_error, &stack_segment, 0); + setup_gate(TRAP_gp_fault, &general_protection, 0); + setup_gate(TRAP_page_fault, &page_fault, 0); + setup_gate(TRAP_spurious_int, &spurious_interrupt_bug, 0); + setup_gate(TRAP_copro_error, &coprocessor_error, 0); + setup_gate(TRAP_alignment_check, &alignment_check, 0); + setup_gate(TRAP_simd_error, &simd_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)&tss, 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 iret to kernel space. Correct CS and SS. */ orb $3,1*8(%rsp) orb $3,4*8(%rsp) iretq +#ifdef CONFIG_PARAVIRT 2: /* Slow iret via hypervisor. */ andl $~NMI_MASK, 16(%rsp) pushq $\flag jmp hypercall_page + (__HYPERVISOR_iret * 32) +#endif .endm diff --git a/include/x86/os.h b/include/x86/os.h index 7b7869a..db1389a 100644 --- a/include/x86/os.h +++ b/include/x86/os.h @@ -56,6 +56,7 @@ #define TRAP_machine_check 18 #define TRAP_simd_error 19 #define TRAP_deferred_nmi 31 +#define TRAP_xen_callback 32 /* Everything below this point is not included by assembler (.S) files. */ #ifndef __ASSEMBLY__ -- 2.6.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |