Index: 2006-10-04/xen/arch/x86/mm.c ==================================================================--- 2006-10-04.orig/xen/arch/x86/mm.c 2006-10-04 15:18:51.000000000 +0200 +++ 2006-10-04/xen/arch/x86/mm.c 2006-10-04 15:18:57.000000000 +0200 @@ -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> #ifdef VERBOSE @@ -125,13 +126,6 @@ #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 { #define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */ @@ -2011,6 +2005,8 @@ int do_mmuext_op( case MMUEXT_PIN_L4_TABLE: type = PGT_l4_page_table; + if ( IS_COMPAT(FOREIGNDOM) ) + break; pin_page: /* Ignore pinning of invalid paging levels. */ @@ -2073,7 +2069,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) ) Index: 2006-10-04/xen/arch/x86/x86_64/compat/entry.S ==================================================================--- 2006-10-04.orig/xen/arch/x86/x86_64/compat/entry.S 2006-10-04 15:18:51.000000000 +0200 +++ 2006-10-04/xen/arch/x86/x86_64/compat/entry.S 2006-10-04 15:18:57.000000000 +0200 @@ -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 Index: 2006-10-04/xen/arch/x86/x86_64/compat/mm.c ==================================================================--- 2006-10-04.orig/xen/arch/x86/x86_64/compat/mm.c 2006-10-04 15:18:51.000000000 +0200 +++ 2006-10-04/xen/arch/x86/x86_64/compat/mm.c 2006-10-04 15:18:57.000000000 +0200 @@ -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) { @@ -115,6 +117,151 @@ 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_UNPIN_TABLE: + case MMUEXT_NEW_BASEPTR: + arg1 = XLAT_mmuext_op_arg1_mfn; + break; + default: + arg1 = XLAT_mmuext_op_arg1_linear_addr; + break; + case MMUEXT_PIN_L4_TABLE: + 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 ( --limit == i ) \ + { \ + --i; \ + continue; \ + } \ + (_d_)->arg2.vcpumask.p = (void *)(nat_ops.p + limit); \ + if ( copy_from_compat(&vcpumask, (_s_)->arg2.vcpumask, 1) == 0 ) \ + *(_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 ) + break; + + guest_handle_add_offset(cmp_uops, 1); + ++nat_op; + } + + err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom); + + if ( err ) + { + unsigned int done = err & ~MMU_UPDATE_PREEMPTED; + + if ( done < i ) + { + /* + * Note that the surrounding conditional is not strictly + * necessary - we are going to leave the function anyway, so + * in case of an error nobody will ever attempt to dereference + * the request handles anymore; only an active continuation + * will result in the compatibility one getting further used. + */ + guest_handle_add_offset(nat_ops, done); + guest_handle_add_offset(cmp_uops, (long)(done - i)); + hypercall_xlat_continuation(0x01, nat_ops, cmp_uops); + } + 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 */ /* Index: 2006-10-04/xen/common/compat/xlat.c ==================================================================--- 2006-10-04.orig/xen/common/compat/xlat.c 2006-10-04 15:11:03.000000000 +0200 +++ 2006-10-04/xen/common/compat/xlat.c 2006-10-04 15:18:57.000000000 +0200 @@ -21,6 +21,10 @@ void xlat_start_info(struct start_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 Index: 2006-10-04/xen/include/asm-x86/hypercall.h ==================================================================--- 2006-10-04.orig/xen/include/asm-x86/hypercall.h 2006-05-02 16:41:35.000000000 +0200 +++ 2006-10-04/xen/include/asm-x86/hypercall.h 2006-10-04 15:18:57.000000000 +0200 @@ -7,6 +7,13 @@ #include <public/physdev.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( XEN_GUEST_HANDLE(evtchn_op_t) uop); Index: 2006-10-04/xen/include/xlat.lst ==================================================================--- 2006-10-04.orig/xen/include/xlat.lst 2006-10-04 15:18:51.000000000 +0200 +++ 2006-10-04/xen/include/xlat.lst 2006-10-04 15:18:57.000000000 +0200 @@ -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-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel