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] [XEN] Clean up page-fault propagation whe

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Clean up page-fault propagation when acessing guest addresses.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 13 Jul 2006 16:20:15 +0000
Delivery-date: Thu, 13 Jul 2006 09:22:31 -0700
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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID af9809f51f81a3c43f276f00c81a52ef558afda4
# Parent  a70c4f9657cc2a9606ea37650b351e222527d72f
[XEN] Clean up page-fault propagation when acessing guest addresses.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm.c          |    8 ++--
 xen/arch/x86/traps.c       |   87 +++++++++++++++++++++++----------------------
 xen/arch/x86/x86_emulate.c |   19 ++++++---
 3 files changed, 63 insertions(+), 51 deletions(-)

diff -r a70c4f9657cc -r af9809f51f81 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Jul 12 19:16:14 2006 +0100
+++ b/xen/arch/x86/mm.c Thu Jul 13 09:55:14 2006 +0100
@@ -3386,13 +3386,13 @@ static int ptwr_emulated_update(
     if ( bytes != sizeof(paddr_t) )
     {
         paddr_t      full;
-        unsigned int offset = addr & (sizeof(paddr_t)-1);
+        unsigned int rc, offset = addr & (sizeof(paddr_t)-1);
 
         /* Align address; read full word. */
         addr &= ~(sizeof(paddr_t)-1);
-        if ( copy_from_user(&full, (void *)addr, sizeof(paddr_t)) )
-        {
-            propagate_page_fault(addr, 0); /* read fault */
+        if ( (rc = copy_from_user(&full, (void *)addr, sizeof(paddr_t))) != 0 )
+        {
+            propagate_page_fault(addr+sizeof(paddr_t)-rc, 0); /* read fault */
             return X86EMUL_PROPAGATE_FAULT;
         }
         /* Mask out bits provided by caller. */
diff -r a70c4f9657cc -r af9809f51f81 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Jul 12 19:16:14 2006 +0100
+++ b/xen/arch/x86/traps.c      Thu Jul 13 09:55:14 2006 +0100
@@ -403,16 +403,16 @@ static inline int do_trap(int trapnr, ch
     return 0;
 }
 
-#define DO_ERROR_NOCODE(trapnr, str, name) \
-asmlinkage int do_##name(struct cpu_user_regs *regs) \
-{ \
-    return do_trap(trapnr, str, regs, 0); \
-}
-
-#define DO_ERROR(trapnr, str, name) \
-asmlinkage int do_##name(struct cpu_user_regs *regs) \
-{ \
-    return do_trap(trapnr, str, regs, 1); \
+#define DO_ERROR_NOCODE(trapnr, str, name)              \
+asmlinkage int do_##name(struct cpu_user_regs *regs)    \
+{                                                       \
+    return do_trap(trapnr, str, regs, 0);               \
+}
+
+#define DO_ERROR(trapnr, str, name)                     \
+asmlinkage int do_##name(struct cpu_user_regs *regs)    \
+{                                                       \
+    return do_trap(trapnr, str, regs, 1);               \
 }
 
 DO_ERROR_NOCODE( 0, "divide error", divide_error)
@@ -449,9 +449,9 @@ int cpuid_hypervisor_leaves(
 
 static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
 {
-    char signature[5], instr[2];
+    char sig[5], instr[2];
     uint32_t a, b, c, d;
-    unsigned long eip;
+    unsigned long eip, rc;
 
     a = regs->eax;
     b = regs->ebx;
@@ -460,14 +460,22 @@ static int emulate_forced_invalid_op(str
     eip = regs->eip;
 
     /* Check for forced emulation signature: ud2 ; .ascii "xen". */
-    if ( copy_from_user(signature, (char *)eip, sizeof(signature)) ||
-         memcmp(signature, "\xf\xbxen", sizeof(signature)) )
+    if ( (rc = copy_from_user(sig, (char *)eip, sizeof(sig))) != 0 )
+    {
+        propagate_page_fault(eip + sizeof(sig) - rc, 0);
+        return EXCRET_fault_fixed;
+    }
+    if ( memcmp(sig, "\xf\xbxen", sizeof(sig)) )
         return 0;
-    eip += sizeof(signature);
+    eip += sizeof(sig);
 
     /* We only emulate CPUID. */
-    if ( copy_from_user(instr, (char *)eip, sizeof(instr)) ||
-         memcmp(instr, "\xf\xa2", sizeof(instr)) )
+    if ( ( rc = copy_from_user(instr, (char *)eip, sizeof(instr))) != 0 )
+    {
+        propagate_page_fault(eip + sizeof(instr) - rc, 0);
+        return EXCRET_fault_fixed;
+    }
+    if ( memcmp(instr, "\xf\xa2", sizeof(instr)) )
         return 0;
     eip += sizeof(instr);
 
@@ -923,17 +931,14 @@ static inline int admin_io_okay(
 #define outl_user(_v, _p, _d, _r) \
     (admin_io_okay(_p, 4, _d, _r) ? outl(_v, _p) : ((void)0))
 
-/* Propagate a fault back to the guest kernel. */
-#define PAGE_FAULT(_faultaddr, _errcode)        \
-({  propagate_page_fault(_faultaddr, _errcode); \
-    return EXCRET_fault_fixed;                  \
-})
-
-/* Isntruction fetch with error handling. */
-#define insn_fetch(_type, _size, _ptr)          \
-({  unsigned long _x;                           \
-    if ( get_user(_x, (_type *)eip) )           \
-        PAGE_FAULT(eip, 0); /* read fault */    \
+/* Instruction fetch with error handling. */
+#define insn_fetch(_type, _size, _ptr)                                      \
+({  unsigned long _rc, _x;                                                  \
+    if ( (_rc = copy_from_user(&_x, (_type *)eip, sizeof(_type))) != 0 )    \
+    {                                                                       \
+        propagate_page_fault(eip + sizeof(_type) - _rc, 0);                 \
+        return EXCRET_fault_fixed;                                          \
+    }                                                                       \
     eip += _size; (_type)_x; })
 
 static int emulate_privileged_op(struct cpu_user_regs *regs)
@@ -941,7 +946,7 @@ static int emulate_privileged_op(struct 
     struct vcpu *v = current;
     unsigned long *reg, eip = regs->eip, res;
     u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0;
-    unsigned int port, i, op_bytes = 4, data;
+    unsigned int port, i, op_bytes = 4, data, rc;
     u32 l, h;
 
     /* Legacy prefixes. */
@@ -1001,19 +1006,19 @@ static int emulate_privileged_op(struct 
             {
             case 1:
                 data = (u8)inb_user((u16)regs->edx, v, regs);
-                if ( put_user((u8)data, (u8 *)regs->edi) )
-                    PAGE_FAULT(regs->edi, PGERR_write_access);
                 break;
             case 2:
                 data = (u16)inw_user((u16)regs->edx, v, regs);
-                if ( put_user((u16)data, (u16 *)regs->edi) )
-                    PAGE_FAULT(regs->edi, PGERR_write_access);
                 break;
             case 4:
                 data = (u32)inl_user((u16)regs->edx, v, regs);
-                if ( put_user((u32)data, (u32 *)regs->edi) )
-                    PAGE_FAULT(regs->edi, PGERR_write_access);
                 break;
+            }
+            if ( (rc = copy_to_user((void *)regs->edi, &data, op_bytes)) != 0 )
+            {
+                propagate_page_fault(regs->edi + op_bytes - rc,
+                                     PGERR_write_access);
+                return EXCRET_fault_fixed;
             }
             regs->edi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes);
             break;
@@ -1023,21 +1028,21 @@ static int emulate_privileged_op(struct 
         case 0x6f: /* OUTSW/OUTSL */
             if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) )
                 goto fail;
+            rc = copy_from_user(&data, (void *)regs->esi, op_bytes);
+            if ( rc != 0 )
+            {
+                propagate_page_fault(regs->esi + op_bytes - rc, 0);
+                return EXCRET_fault_fixed;
+            }
             switch ( op_bytes )
             {
             case 1:
-                if ( get_user(data, (u8 *)regs->esi) )
-                    PAGE_FAULT(regs->esi, 0); /* read fault */
                 outb_user((u8)data, (u16)regs->edx, v, regs);
                 break;
             case 2:
-                if ( get_user(data, (u16 *)regs->esi) )
-                    PAGE_FAULT(regs->esi, 0); /* read fault */
                 outw_user((u16)data, (u16)regs->edx, v, regs);
                 break;
             case 4:
-                if ( get_user(data, (u32 *)regs->esi) )
-                    PAGE_FAULT(regs->esi, 0); /* read fault */
                 outl_user((u32)data, (u16)regs->edx, v, regs);
                 break;
             }
diff -r a70c4f9657cc -r af9809f51f81 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Wed Jul 12 19:16:14 2006 +0100
+++ b/xen/arch/x86/x86_emulate.c        Thu Jul 13 09:55:14 2006 +0100
@@ -1138,12 +1138,16 @@ x86_emulate_read_std(
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
+    unsigned int rc;
+
     *val = 0;
-    if ( copy_from_user((void *)val, (void *)addr, bytes) )
-    {
-        propagate_page_fault(addr, 0); /* read fault */
+
+    if ( (rc = copy_from_user((void *)val, (void *)addr, bytes)) != 0 )
+    {
+        propagate_page_fault(addr + bytes - rc, 0); /* read fault */
         return X86EMUL_PROPAGATE_FAULT;
     }
+
     return X86EMUL_CONTINUE;
 }
 
@@ -1154,11 +1158,14 @@ x86_emulate_write_std(
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
-    if ( copy_to_user((void *)addr, (void *)&val, bytes) )
-    {
-        propagate_page_fault(addr, PGERR_write_access); /* write fault */
+    unsigned int rc;
+
+    if ( (rc = copy_to_user((void *)addr, (void *)&val, bytes)) != 0 )
+    {
+        propagate_page_fault(addr + bytes - rc, PGERR_write_access);
         return X86EMUL_PROPAGATE_FAULT;
     }
+
     return X86EMUL_CONTINUE;
 }
 

_______________________________________________
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] [XEN] Clean up page-fault propagation when acessing guest addresses., Xen patchbot-unstable <=