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-devel

[Xen-devel] compat_mmuext_op - continuation code is wrong

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] compat_mmuext_op - continuation code is wrong
From: John Levon <levon@xxxxxxxxxxxxxxxxx>
Date: Wed, 20 Feb 2008 17:21:15 +0000
Delivery-date: Wed, 20 Feb 2008 09:22:02 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.9i
289         err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom);

If preempt_mask is set, we immediately hit a pre-emption, then we get:

2003     if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
2004     {
2005         count &= ~MMU_UPDATE_PREEMPTED;
2006         if ( unlikely(!guest_handle_is_null(pdone)) )
2007             (void)copy_from_guest(&done, pdone, 1);
2008     }

But we never initialised the guest's "pdone" at any point. So we can
copy in an uninit stack value into 'done', add 'i' to it, then copy it
back out. On Solaris, we assert that the success count == what we passed
in, so this breaks Solaris 32/64

I'm running on 3.1 with a couple of fixes from unstable to make it work
at all. The below patch works for us but I'm not confident in its
correctness.

regards
john

diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c
--- a/xen/arch/x86/x86_64/compat/mm.c
+++ b/xen/arch/x86/x86_64/compat/mm.c
@@ -4,6 +4,7 @@
 #include <xen/multicall.h>
 #include <compat/memory.h>
 #include <compat/xen.h>
+#include <xen/config.h>
 
 int compat_set_gdt(XEN_GUEST_HANDLE(uint) frame_list, unsigned int entries)
 {
@@ -180,6 +181,7 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
                      unsigned int foreigndom)
 {
     unsigned int i, preempt_mask;
+    unsigned int origcount;
     int rc = 0;
     XEN_GUEST_HANDLE(mmuext_op_t) nat_ops;
 
@@ -191,6 +193,8 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
 
     set_xen_guest_handle(nat_ops, (void 
*)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id));
 
+    origcount = count;
+
     for ( ; count; count -= i )
     {
         mmuext_op_t *nat_op = nat_ops.p;
@@ -199,6 +203,17 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
 
         if ( hypercall_preempt_check() )
         {
+            /*
+             * If this is the first time around, and we've not
+             * pre-empted before, we must initialise pdone (see start of
+             * do_mmuext_op()).
+             */
+            if (!preempt_mask && origcount == count)
+            {
+                unsigned int zero = 0;
+                (void) copy_to_guest(pdone, &zero, 1);
+            }
+
             rc = hypercall_create_continuation(
                 __HYPERVISOR_mmuext_op, "hihi",
                 cmp_uops, count | MMU_UPDATE_PREEMPTED, pdone, foreigndom);

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>