Index: 2007-01-08/xen/arch/x86/traps.c =================================================================== --- 2007-01-08.orig/xen/arch/x86/traps.c 2007-01-25 13:53:38.000000000 +0100 +++ 2007-01-08/xen/arch/x86/traps.c 2007-01-25 16:01:23.000000000 +0100 @@ -1162,7 +1162,9 @@ static int emulate_privileged_op(struct goto fail; op_default = op_bytes = (ar & (_SEGMENT_L|_SEGMENT_DB)) ? 4 : 2; ad_default = ad_bytes = (ar & _SEGMENT_L) ? 8 : op_default; - if ( !(ar & (_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_P)) ) + if ( !(ar & _SEGMENT_S) || + !(ar & _SEGMENT_P) || + !(ar & _SEGMENT_CODE) ) goto fail; /* emulating only opcodes not allowing SS to be default */ @@ -1246,7 +1248,8 @@ static int emulate_privileged_op(struct &data_base, &data_limit, &ar, _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) ) goto fail; - if ( !(ar & (_SEGMENT_S|_SEGMENT_P)) || + if ( !(ar & _SEGMENT_S) || + !(ar & _SEGMENT_P) || (opcode & 2 ? (ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR) : (ar & _SEGMENT_CODE) || !(ar & _SEGMENT_WR)) ) Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S =================================================================== --- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-25 13:53:38.000000000 +0100 +++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-25 16:01:22.000000000 +0100 @@ -23,7 +23,9 @@ ENTRY(compat_hypercall) movq %rsp,%rdi movl $0xDEADBEEF,%eax rep stosq - popq %r9 ; popq %r8 ; popq %rcx; popq %rdx; popq %rsi; popq %rdi + popq %r8 ; popq %r9 ; xchgl %r8d,%r9d + popq %rdx; popq %rcx; xchgl %edx,%ecx + popq %rdi; popq %rsi; xchgl %edi,%esi movl UREGS_rax(%rsp),%eax pushq %rax pushq UREGS_rip+8(%rsp) @@ -31,8 +33,9 @@ ENTRY(compat_hypercall) movl %eax,%eax movl %ebp,%r9d movl %edi,%r8d - xchgl %ecx,%esi + xchgl %ecx,%esi movl UREGS_rbx(%rsp),%edi + movl %edx,%edx #endif leaq compat_hypercall_table(%rip),%r10 PERFC_INCR(PERFC_hypercalls, %rax) Index: 2007-01-08/xen/arch/x86/x86_64/compat/mm.c =================================================================== --- 2007-01-08.orig/xen/arch/x86/x86_64/compat/mm.c 2007-01-12 17:22:50.000000000 +0100 +++ 2007-01-08/xen/arch/x86/x86_64/compat/mm.c 2007-01-10 16:06:16.000000000 +0100 @@ -1,6 +1,7 @@ #ifdef CONFIG_COMPAT #include +#include #include #include @@ -289,20 +290,27 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm if ( err == __HYPERVISOR_mmuext_op ) { struct cpu_user_regs *regs = guest_cpu_user_regs(); - unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED; + struct mc_state *mcs = &this_cpu(mc_state); + unsigned int arg1 = !test_bit(_MCSF_in_multicall, &mcs->flags) + ? regs->ecx + : mcs->call.args[1]; + unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED; - BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED)); + BUG_ON(left == arg1); 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; + BUG_ON(left != arg1); + if (!test_bit(_MCSF_in_multicall, &mcs->flags)) + regs->_ecx += count - i; + else + mcs->compat_call.args[1] += count - i; } else - BUG_ON(rc > 0); + BUG_ON(err > 0); rc = err; } Index: 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h =================================================================== --- 2007-01-08.orig/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 09:49:18.000000000 +0100 +++ 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h 2007-01-25 15:18:37.000000000 +0100 @@ -20,7 +20,8 @@ #define __compat_addr_ok(addr) \ ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(current->domain)) -#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size)) +#define compat_access_ok(addr, size) \ + __compat_addr_ok((unsigned long)(addr) + ((size) ? (size) - 1 : 0)) #define compat_array_access_ok(addr,count,size) \ (likely((count) < (~0U / (size))) && \