[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Enable compatibility mode operation for HYPERVISOR_mmu_update and
# HG changeset patch # User Emmanuel Ackaouy <ack@xxxxxxxxxxxxx> # Date 1168018471 0 # Node ID e4088ae584b81959999318c35bd718c21bed69f2 # Parent 244e46e7d021b1942ace91440c0fdab72a6ce5e4 Enable compatibility mode operation for HYPERVISOR_mmu_update and HYPERVISOR_mmuext_op. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- xen/arch/x86/mm.c | 16 ++-- xen/arch/x86/x86_64/compat/entry.S | 4 - xen/arch/x86/x86_64/compat/mm.c | 148 +++++++++++++++++++++++++++++++++++++ xen/common/compat/xlat.c | 4 + xen/include/asm-x86/hypercall.h | 7 + xen/include/xlat.lst | 2 6 files changed, 170 insertions(+), 11 deletions(-) diff -r 244e46e7d021 -r e4088ae584b8 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Jan 05 17:34:31 2007 +0000 +++ b/xen/arch/x86/mm.c Fri Jan 05 17:34:31 2007 +0000 @@ -106,6 +106,7 @@ #include <asm/ldt.h> #include <asm/x86_emulate.h> #include <asm/e820.h> +#include <asm/hypercall.h> #include <public/memory.h> #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a) @@ -118,13 +119,6 @@ #if !defined(NDEBUG) || defined(CONFIG_X86_PAE) #define PTE_UPDATE_WITH_CMPXCHG #endif - -/* - * Both do_mmuext_op() and do_mmu_update(): - * We steal the m.s.b. of the @count parameter to indicate whether this - * invocation of do_mmu_update() is resuming a previously preempted call. - */ -#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) /* Used to defer flushing of memory structures. */ struct percpu_mm_info { @@ -2033,6 +2027,8 @@ int do_mmuext_op( goto pin_page; case MMUEXT_PIN_L4_TABLE: + if ( IS_COMPAT(FOREIGNDOM) ) + break; type = PGT_l4_page_table; pin_page: @@ -2096,7 +2092,11 @@ int do_mmuext_op( #ifdef __x86_64__ case MMUEXT_NEW_USER_BASEPTR: - okay = 1; + if ( IS_COMPAT(FOREIGNDOM) ) + { + okay = 0; + break; + } if (likely(mfn != 0)) { if ( shadow_mode_refcounts(d) ) diff -r 244e46e7d021 -r e4088ae584b8 xen/arch/x86/x86_64/compat/entry.S --- a/xen/arch/x86/x86_64/compat/entry.S Fri Jan 05 17:34:31 2007 +0000 +++ b/xen/arch/x86/x86_64/compat/entry.S Fri Jan 05 17:34:31 2007 +0000 @@ -279,7 +279,6 @@ CFIX14: .section .rodata, "a", @progbits #define compat_set_trap_table domain_crash_synchronous -#define compat_mmu_update domain_crash_synchronous #define compat_set_gdt domain_crash_synchronous #define compat_platform_op domain_crash_synchronous #define compat_multicall domain_crash_synchronous @@ -288,7 +287,6 @@ CFIX14: #define compat_physdev_op_compat domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous #define compat_vcpu_op domain_crash_synchronous -#define compat_mmuext_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous #define compat_arch_sched_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous @@ -299,7 +297,7 @@ CFIX14: ENTRY(compat_hypercall_table) .quad compat_set_trap_table /* 0 */ - .quad compat_mmu_update + .quad do_mmu_update .quad compat_set_gdt .quad do_stack_switch .quad compat_set_callbacks diff -r 244e46e7d021 -r e4088ae584b8 xen/arch/x86/x86_64/compat/mm.c --- a/xen/arch/x86/x86_64/compat/mm.c Fri Jan 05 17:34:31 2007 +0000 +++ b/xen/arch/x86/x86_64/compat/mm.c Fri Jan 05 17:34:31 2007 +0000 @@ -1,6 +1,8 @@ #ifdef CONFIG_COMPAT +#include <xen/event.h> #include <compat/memory.h> +#include <compat/xen.h> int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) { @@ -135,6 +137,152 @@ int compat_update_va_mapping_otherdomain { return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid); } + +DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t); + +int compat_mmuext_op(XEN_GUEST_HANDLE(mmuext_op_compat_t) cmp_uops, + unsigned int count, + XEN_GUEST_HANDLE(uint) pdone, + unsigned int foreigndom) +{ + unsigned int i, preempt_mask; + int rc = 0; + XEN_GUEST_HANDLE(mmuext_op_t) nat_ops; + + preempt_mask = count & MMU_UPDATE_PREEMPTED; + count ^= preempt_mask; + + if ( unlikely(!guest_handle_okay(cmp_uops, count)) ) + return -EFAULT; + + set_xen_guest_handle(nat_ops, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); + + for ( ; count; count -= i ) + { + mmuext_op_t *nat_op = nat_ops.p; + unsigned int limit; + int err; + + if ( hypercall_preempt_check() ) + { + rc = hypercall_create_continuation( + __HYPERVISOR_mmuext_op, "hihi", + cmp_uops, count | MMU_UPDATE_PREEMPTED, pdone, foreigndom); + break; + } + + limit = COMPAT_ARG_XLAT_SIZE / sizeof(*nat_op); + + for ( i = 0; i < min(limit, count); ++i ) + { + mmuext_op_compat_t cmp_op; + enum XLAT_mmuext_op_arg1 arg1; + enum XLAT_mmuext_op_arg2 arg2; + + if ( unlikely(__copy_from_guest(&cmp_op, cmp_uops, 1) != 0) ) + { + rc = -EFAULT; + break; + } + + switch ( cmp_op.cmd ) + { + case MMUEXT_PIN_L1_TABLE: + case MMUEXT_PIN_L2_TABLE: + case MMUEXT_PIN_L3_TABLE: + case MMUEXT_PIN_L4_TABLE: + case MMUEXT_UNPIN_TABLE: + case MMUEXT_NEW_BASEPTR: + arg1 = XLAT_mmuext_op_arg1_mfn; + break; + default: + arg1 = XLAT_mmuext_op_arg1_linear_addr; + break; + case MMUEXT_NEW_USER_BASEPTR: + rc = -EINVAL; + case MMUEXT_TLB_FLUSH_LOCAL: + case MMUEXT_TLB_FLUSH_MULTI: + case MMUEXT_TLB_FLUSH_ALL: + case MMUEXT_FLUSH_CACHE: + arg1 = -1; + break; + } + + if ( rc ) + break; + + switch ( cmp_op.cmd ) + { + case MMUEXT_SET_LDT: + arg2 = XLAT_mmuext_op_arg2_nr_ents; + break; + case MMUEXT_TLB_FLUSH_MULTI: + case MMUEXT_INVLPG_MULTI: + arg2 = XLAT_mmuext_op_arg2_vcpumask; + break; + default: + arg2 = -1; + break; + } + +#define XLAT_mmuext_op_HNDL_arg2_vcpumask(_d_, _s_) \ + do \ + { \ + unsigned int vcpumask; \ + if ( i < --limit ) \ + { \ + (_d_)->arg2.vcpumask.p = (void *)(nat_ops.p + limit); \ + if ( copy_from_compat(&vcpumask, (_s_)->arg2.vcpumask, 1) == 0 ) \ + *(unsigned long *)(_d_)->arg2.vcpumask.p = vcpumask; \ + else \ + rc = -EFAULT; \ + } \ + } while(0) + XLAT_mmuext_op(nat_op, &cmp_op); +#undef XLAT_mmuext_op_HNDL_arg2_vcpumask + + if ( rc || i >= limit ) + break; + + guest_handle_add_offset(cmp_uops, 1); + ++nat_op; + } + + err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom); + + if ( err ) + { + BUILD_BUG_ON(__HYPERVISOR_mmuext_op <= 0); + if ( err == __HYPERVISOR_mmuext_op ) + { + struct cpu_user_regs *regs = guest_cpu_user_regs(); + unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED; + + BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED)); + BUG_ON(left > count); + guest_handle_add_offset(nat_ops, count - left); + BUG_ON(left + i < count); + guest_handle_add_offset(cmp_uops, (signed int)(count - left - i)); + left = 1; + BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops)); + BUG_ON(left != regs->ecx); + regs->ecx += count - i; + } + else + BUG_ON(rc > 0); + rc = err; + } + + if ( rc ) + break; + + /* Force do_mmuext_op() to not start counting from zero again. */ + preempt_mask = MMU_UPDATE_PREEMPTED; + } + + return rc; +} + #endif /* CONFIG_COMPAT */ /* diff -r 244e46e7d021 -r e4088ae584b8 xen/common/compat/xlat.c --- a/xen/common/compat/xlat.c Fri Jan 05 17:34:31 2007 +0000 +++ b/xen/common/compat/xlat.c Fri Jan 05 17:34:31 2007 +0000 @@ -21,6 +21,10 @@ CHECK_dom0_vga_console_info; CHECK_dom0_vga_console_info; #undef dom0_vga_console_info +#define xen_mmu_update mmu_update +CHECK_mmu_update; +#undef xen_mmu_update + #define xen_vcpu_time_info vcpu_time_info CHECK_vcpu_time_info; #undef xen_vcpu_time_info diff -r 244e46e7d021 -r e4088ae584b8 xen/include/asm-x86/hypercall.h --- a/xen/include/asm-x86/hypercall.h Fri Jan 05 17:34:31 2007 +0000 +++ b/xen/include/asm-x86/hypercall.h Fri Jan 05 17:34:31 2007 +0000 @@ -7,6 +7,13 @@ #include <public/physdev.h> #include <xen/types.h> + +/* + * Both do_mmuext_op() and do_mmu_update(): + * We steal the m.s.b. of the @count parameter to indicate whether this + * invocation of do_mmu_update() is resuming a previously preempted call. + */ +#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) extern long do_event_channel_op_compat( diff -r 244e46e7d021 -r e4088ae584b8 xen/include/xlat.lst --- a/xen/include/xlat.lst Fri Jan 05 17:34:31 2007 +0000 +++ b/xen/include/xlat.lst Fri Jan 05 17:34:31 2007 +0000 @@ -2,6 +2,8 @@ # ! - needs translation # ? - needs checking ? dom0_vga_console_info xen.h +? mmu_update xen.h +! mmuext_op xen.h ! start_info xen.h ? vcpu_time_info xen.h ! add_to_physmap memory.h _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |