WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Enable compatibility mode operation for H

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Enable compatibility mode operation for HYPERVISOR_mmu_update and
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 05 Jan 2007 12:55:23 -0800
Delivery-date: Fri, 05 Jan 2007 14:02:24 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Enable compatibility mode operation for HYPERVISOR_mmu_update and, Xen patchbot-unstable <=