x86_64: system call and exception handling for compatibility mode guest (version 2)
RFC PATCH 2/4 x86_64: system call and exception handling for compatibility mode guest (version 2)
This adds several routines and conditionals to deal with the specifics of compatibility mode guests. Compatibility mode hypercall handlers are being stubbed out to crash the domain for the time being.
Signed-off-by Jan Beulich <[email protected]>
xen/arch/x86/traps.c +6 -0
@@ -137,6 +137,12 @@ static void show_guest_stack(struct cpu_if (hvm_guest (current) )return ; + if ( IS_COMPAT(container_of(regs, struct cpu_info, guest_cpu_user_regs)->current_vcpu->domain) ) + { +compat_show_guest_stack (regs, debug_stack_lines); +return ; + } +if (vm86_mode (regs) ) { stack = (unsigned long *)((regs->ss <<4 ) + (regs->esp &0xffff ));
xen/arch/x86/x86_64/Makefile +6 -0
@@ -1,3 +1,9 @@ obj-y += entry.o obj-y += mm.o obj-y += traps.o + +ifeq ($(CONFIG_COMPAT),y) +# extra dependencies +entry.o: compat/entry.S +traps.o: compat/traps.c +endif
xen/arch/x86/x86_64/asm-offsets.c +5 -0
@@ -53,6 +53,7 @@ void __dummy__(void)BLANK (); OFFSET(VCPU_processor, struct vcpu, processor); + OFFSET(VCPU_domain, struct vcpu, domain); OFFSET(VCPU_vcpu_info, struct vcpu, vcpu_info); OFFSET(VCPU_trap_bounce, struct vcpu, arch.trap_bounce); OFFSET(VCPU_thread_flags, struct vcpu, arch.flags);
@@ -86,6 +87,10 @@ void __dummy__(void) OFFSET(VCPU_vmx_launched, struct vcpu, arch.hvm_vmx.launched);BLANK (); + OFFSET(DOMAIN_domain_flags, struct domain, domain_flags); +DEFINE (_DOMF_compat, _DOMF_compat); +BLANK (); + OFFSET(VMCB_rax, struct vmcb_struct, rax); OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset);BLANK ();
xen/arch/x86/x86_64/compat/entry.S new file +369 -0
369 lines not on this page · raw message
xen/arch/x86/x86_64/compat/traps.c new file +264 -0
264 lines not on this page · raw message
xen/arch/x86/x86_64/entry.S +18 -2
@@ -334,8 +334,15 @@ domain_crash_synchronous: ENTRY(ret_from_intr) GET_CURRENT(%rbx) testb $3,UREGS_cs(%rsp) - jnz test_all_events - jmp restore_all_xen + jz restore_all_xen +#ifndef CONFIG_COMPAT + jmp test_all_events +#else + movq VCPU_domain(%rbx),%rax + btl $_DOMF_compat, DOMAIN_domain_flags(%rax) + jnc test_all_events + jmp compat_test_all_events +#endif ALIGN /* No special register assumptions. */
@@ -353,6 +360,11 @@ handle_exception: testb $3,UREGS_cs(%rsp) jz restore_all_xen leaq VCPU_trap_bounce(%rbx),%rdx +#ifdef CONFIG_COMPAT + movq VCPU_domain(%rbx),%rax + btl $_DOMF_compat, DOMAIN_domain_flags(%rax) + jc compat_post_handle_exception +#endif testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) jz test_all_events call create_bounce_frame
@@ -612,3 +624,7 @@ ENTRY(hypercall_args_table) .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr + +#ifdef CONFIG_COMPAT +#include "compat/entry.S" +#endif
xen/arch/x86/x86_64/traps.c +11 -1
@@ -228,6 +228,7 @@ unsigned long do_iret(void) } asmlinkage void syscall_enter(void); +asmlinkage void compat_hypercall(void);void __init percpu_traps_init (void ) {char *stack_bottom, *stack;
@@ -239,6 +240,11 @@ void __init percpu_traps_init(void)set_intr_gate (TRAP_double_fault, &double_fault); idt_table[TRAP_double_fault].a |=1UL <<32 ;/* IST1 */ idt_table[TRAP_nmi].a |=2UL <<32 ;/* IST2 */ + +#ifdef CONFIG_COMPAT +/* The hypercall entry vector is only accessible from ring 1. */ +_set_gate (idt_table+HYPERCALL_VECTOR ,15 ,1 , &compat_hypercall); +#endif } stack_bottom = (char *)get_stack_bottom ();
@@ -479,12 +485,16 @@ static void hypercall_page_initialise_ri *(u16 *)(p+9 ) =0x050f ;/* syscall */ } +#include "compat/traps.c" +void hypercall_page_initialise (struct domain *d,void *hypercall_page) {if (hvm_guest (d->vcpu[0 ]) )hvm_hypercall_page_initialise (d, hypercall_page); -else +else if ( !IS_COMPAT (d) )hypercall_page_initialise_ring3_kernel (hypercall_page); +else +hypercall_page_initialise_ring1_kernel (hypercall_page); }/*
xen/include/asm-x86/processor.h +6 -0
@@ -558,6 +558,12 @@ void show_execution_state(struct cpu_usevoid show_page_walk (unsigned long addr); asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs); +#ifdef CONFIG_COMPAT +void compat_show_guest_stack (struct cpu_user_regs *,int lines); +#else +#define compat_show_guest_stack (regs, lines) ((void)0) +#endif +/* Dumps current register and stack state. */ #define dump_execution_state () \/* NB. Needs interrupts enabled else we end up in fatal_trap(). */ \
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel