[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [PATCH] vmx-mmio-2pages.patch



ChangeSet 1.1633, 2005/06/02 09:12:25+01:00, arun.sharma@xxxxxxxxx

        [PATCH] vmx-mmio-2pages.patch
        
        Handle the case where the MMIO instruction crosses a page boundary.
        
        Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>



 vmx_platform.c |   42 ++++++++++++++++++++++++++++--------------
 1 files changed, 28 insertions(+), 14 deletions(-)


diff -Nru a/xen/arch/x86/vmx_platform.c b/xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c       2005-06-02 05:03:14 -04:00
+++ b/xen/arch/x86/vmx_platform.c       2005-06-02 05:03:14 -04:00
@@ -406,35 +406,49 @@
     return DECODE_failure;
 }
 
-int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int 
inst_len)
+int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
+                         int inst_len)
 {
     l1_pgentry_t gpte;
     unsigned long mfn;
     unsigned long ma;
     unsigned char * inst_start;
+    int remaining = 0;
         
     if (inst_len > MAX_INST_LEN || inst_len <= 0) {
         return 0;
     }
 
-    if ((guest_eip & PAGE_MASK) == ((guest_eip + inst_len) & PAGE_MASK)) {
-        if (vmx_paging_enabled(current)) {
-                gpte = gva_to_gpte(guest_eip);
-                mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
-        } else {
-                mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT);
+    if (vmx_paging_enabled(current)) {
+        gpte = gva_to_gpte(guest_eip);
+        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        /* Does this cross a page boundary ? */
+        if ((guest_eip & PAGE_MASK) != ((guest_eip + inst_len) & PAGE_MASK)) {
+            remaining = (guest_eip + inst_len) & ~PAGE_MASK;
+            inst_len -= remaining;
         }
-        ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
+
+    } else {
+        mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT);
+    }
+    ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
+    inst_start = (unsigned char *)map_domain_mem(ma);
+                
+    memcpy((char *)buf, inst_start, inst_len);
+    unmap_domain_mem(inst_start);
+
+    if (remaining) {
+        gpte = gva_to_gpte(guest_eip+inst_len+remaining);
+        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+
+        ma = (mfn << PAGE_SHIFT);
         inst_start = (unsigned char *)map_domain_mem(ma);
                 
-        memcpy((char *)buf, inst_start, inst_len);
+        memcpy((char *)buf+inst_len, inst_start, remaining);
         unmap_domain_mem(inst_start);
-    } else {
-        // Todo: In two page frames
-        BUG();
+
     }
-        
-    return inst_len;
+    return inst_len+remaining;
 }
 
 static void init_instruction(struct instruction *mmio_inst)

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.