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

[Xen-changelog] [xen-unstable] [HVM] Clean up hvm_copy interface to be more like copy_to/from_user.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 058f4a2a864264aea7cc0bd9e95947c9287142f8
# Parent  412fc1c1bd7a8ac70dace63b84bcc075c1fb8e0b
[HVM] Clean up hvm_copy interface to be more like copy_to/from_user.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c            |   63 ++++++++++++++++++++++----------------
 xen/arch/x86/hvm/i8259.c          |   20 +++++++-----
 xen/arch/x86/hvm/intercept.c      |   16 ++++-----
 xen/arch/x86/hvm/io.c             |    4 +-
 xen/arch/x86/hvm/platform.c       |    8 ++--
 xen/arch/x86/hvm/svm/svm.c        |    4 +-
 xen/arch/x86/hvm/vmx/vmx.c        |   17 +++++-----
 xen/arch/x86/mm/shadow/common.c   |    4 +-
 xen/include/asm-x86/hvm/support.h |   21 ++++++------
 9 files changed, 87 insertions(+), 70 deletions(-)

diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Fri Sep 29 11:10:14 2006 +0100
@@ -393,9 +393,9 @@ void hvm_hlt(unsigned long rflags)
  *  @buf  = hypervisor buffer
  *  @addr = guest virtual or physical address to copy to/from
  *  @size = number of bytes to copy
- *  @dir  = HVM_COPY_IN / HVM_COPY_OUT
- *  @phy  = interpret addr as physical or virtual address?
- * Returns TRUE on success.
+ *  @dir  = copy *to* guest (TRUE) or *from* guest (FALSE)?
+ *  @phy  = interpret addr as physical (TRUE) or virtual (FALSE) address?
+ * Returns number of bytes failed to copy (0 == complete success).
  */
 static int __hvm_copy(
     void *buf, unsigned long addr, int size, int dir, int phy)
@@ -403,43 +403,54 @@ static int __hvm_copy(
     struct vcpu *v = current;
     unsigned long mfn;
     char *p;
-    int count;
-
-    while ( size > 0 )
-    {
-        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), size);
+    int count, todo;
+
+    todo = size;
+    while ( todo > 0 )
+    {
+        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo);
 
         mfn = phy ? 
             get_mfn_from_gpfn(addr >> PAGE_SHIFT) :
             mfn_x(sh_vcpu_gfn_to_mfn(v, shadow_gva_to_gfn(v, addr)));
         if ( mfn == INVALID_MFN )
-            return 0;
+            return todo;
 
         p = (char *)map_domain_page(mfn) + (addr & ~PAGE_MASK);
 
-        if ( dir == HVM_COPY_IN )
-            memcpy(buf, p, count);
+        if ( dir )
+            memcpy(p, buf, count); /* dir == TRUE:  *to* guest */
         else
-            memcpy(p, buf, count);
+            memcpy(buf, p, count); /* dir == FALSE: *from guest */
 
         unmap_domain_page(p);
 
         addr += count;
         buf  += count;
-        size -= count;
-    }
-
-    return 1;
-}
-
-int hvm_copy_phy(void *buf, unsigned long paddr, int size, int dir)
-{
-    return __hvm_copy(buf, paddr, size, dir, 1);
-}
-
-int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
-{
-    return __hvm_copy(buf, vaddr, size, dir, 0);
+        todo -= count;
+    }
+
+    return 0;
+}
+
+int hvm_copy_to_guest_phys(unsigned long paddr, void *buf, int size)
+{
+    return __hvm_copy(buf, paddr, size, 1, 1);
+}
+
+int hvm_copy_from_guest_phys(void *buf, unsigned long paddr, int size)
+{
+    return __hvm_copy(buf, paddr, size, 0, 1);
+}
+
+int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size)
+{
+    return __hvm_copy(buf, vaddr, size, 1, 0);
+}
+
+int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size)
+{
+    return __hvm_copy(buf, vaddr, size, 0, 0);
 }
 
 /*
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c  Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/i8259.c  Fri Sep 29 11:10:14 2006 +0100
@@ -497,8 +497,9 @@ static int intercept_pic_io(ioreq_t *p)
     }
     pic = &v->domain->arch.hvm_domain.vpic;
     if ( p->dir == 0 ) {
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
+        if (p->pdata_valid) 
+            (void)hvm_copy_from_guest_virt(
+                &data, (unsigned long)p->u.pdata, p->size);
         else
             data = p->u.data;
         spin_lock_irqsave(&pic->lock, flags);
@@ -511,8 +512,9 @@ static int intercept_pic_io(ioreq_t *p)
         data = pic_ioport_read(
             (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
         spin_unlock_irqrestore(&pic->lock, flags);
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
+        if (p->pdata_valid) 
+            (void)hvm_copy_to_guest_virt(
+                (unsigned long)p->u.pdata, &data, p->size);
         else 
             p->u.data = (u64)data;
     }
@@ -533,8 +535,9 @@ static int intercept_elcr_io(ioreq_t *p)
 
     s = &v->domain->arch.hvm_domain.vpic;
     if ( p->dir == 0 ) {
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
+        if (p->pdata_valid) 
+            (void)hvm_copy_from_guest_virt(
+                &data, (unsigned long)p->u.pdata, p->size);
         else
             data = p->u.data;
         spin_lock_irqsave(&s->lock, flags);
@@ -547,8 +550,9 @@ static int intercept_elcr_io(ioreq_t *p)
     else {
         data = (u64) elcr_ioport_read(
                 (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
-        if(p->pdata_valid) 
-            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
+        if (p->pdata_valid) 
+            (void)hvm_copy_to_guest_virt(
+                (unsigned long)p->u.pdata, &data, p->size);
         else 
             p->u.data = (u64)data;
 
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c      Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/intercept.c      Fri Sep 29 11:10:14 2006 +0100
@@ -90,17 +90,17 @@ static inline void hvm_mmio_access(struc
                     data = read_handler(v,
                       req->addr + (sign * i * req->size),
                       req->size);
-                    hvm_copy(&data,
-                      (unsigned long)p->u.pdata + (sign * i * req->size),
-                      p->size,
-                      HVM_COPY_OUT);
+                    (void)hvm_copy_to_guest_virt(
+                        (unsigned long)p->u.pdata + (sign * i * req->size),
+                        &data,
+                        p->size);
                 }
             } else {                  /* !req->dir == IOREQ_READ */
                 for (i = 0; i < req->count; i++) {
-                    hvm_copy(&data,
-                      (unsigned long)p->u.pdata + (sign * i * req->size),
-                      p->size,
-                      HVM_COPY_IN);
+                    (void)hvm_copy_from_guest_virt(
+                        &data,
+                        (unsigned long)p->u.pdata + (sign * i * req->size),
+                        p->size);
                     write_handler(v,
                       req->addr + (sign * i * req->size),
                       req->size, data);
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/io.c     Fri Sep 29 11:10:14 2006 +0100
@@ -379,7 +379,7 @@ static void hvm_pio_assist(struct cpu_us
                     addr += regs->es << 4;
                 if (sign > 0)
                     addr -= p->size;
-                hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
+                (void)hvm_copy_to_guest_virt(addr, &p->u.data, p->size);
             }
         }
         else /* p->dir == IOREQ_WRITE */
@@ -493,7 +493,7 @@ static void hvm_mmio_assist(struct cpu_u
 
             if (sign > 0)
                 addr -= p->size;
-            hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
+            (void)hvm_copy_to_guest_virt(addr, &p->u.data, p->size);
         }
 
         if (mmio_opp->flags & REPZ)
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/platform.c       Fri Sep 29 11:10:14 2006 +0100
@@ -689,7 +689,7 @@ int inst_copy_from_guest(unsigned char *
 {
     if (inst_len > MAX_INST_LEN || inst_len <= 0)
         return 0;
-    if (!hvm_copy(buf, guest_eip, inst_len, HVM_COPY_IN))
+    if (hvm_copy_from_guest_virt(buf, guest_eip, inst_len))
         return 0;
     return inst_len;
 }
@@ -953,7 +953,7 @@ void handle_mmio(unsigned long va, unsig
             regs->eip -= inst_len; /* do not advance %eip */
 
             if (dir == IOREQ_WRITE)
-                hvm_copy(&value, addr, size, HVM_COPY_IN);
+                (void)hvm_copy_from_guest_virt(&value, addr, size);
             send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
         } else {
             if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) & 
PAGE_MASK)) {
@@ -1094,7 +1094,7 @@ unsigned long copy_to_user_hvm(void *to,
         return 0;
     }
 
-    return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT);
+    return hvm_copy_to_guest_virt((unsigned long)to, (void *)from, len);
 }
 
 unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
@@ -1105,7 +1105,7 @@ unsigned long copy_from_user_hvm(void *t
         return 0;
     }
 
-    return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN);
+    return hvm_copy_from_guest_virt(to, (unsigned long)from, len);
 }
 
 /*
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Sep 29 11:10:14 2006 +0100
@@ -1471,7 +1471,7 @@ static void svm_io_instruction(struct vc
             pio_opp->flags |= OVERLAP;
 
             if (dir == IOREQ_WRITE)
-                hvm_copy(&value, addr, size, HVM_COPY_IN);
+                (void)hvm_copy_from_guest_virt(&value, addr, size);
 
             send_pio_req(regs, port, 1, size, value, dir, 0);
         } 
@@ -2325,7 +2325,7 @@ void svm_dump_inst(unsigned long eip)
     ptr = eip & ~0xff;
     len = 0;
 
-    if (hvm_copy(opcode, ptr, sizeof(opcode), HVM_COPY_IN))
+    if (hvm_copy_from_guest_virt(opcode, ptr, sizeof(opcode)) == 0)
         len = sizeof(opcode);
 
     printf("Code bytes around(len=%d) %lx:", len, eip);
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Sep 29 11:10:14 2006 +0100
@@ -1164,7 +1164,7 @@ static void vmx_io_instruction(unsigned 
 
             pio_opp->flags |= OVERLAP;
             if (dir == IOREQ_WRITE)
-                hvm_copy(&value, addr, size, HVM_COPY_IN);
+                (void)hvm_copy_from_guest_virt(&value, addr, size);
             send_pio_req(regs, port, 1, size, value, dir, 0);
         } else {
             if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) 
{
@@ -1371,7 +1371,8 @@ static int vmx_assist(struct vcpu *v, in
     u32 cp;
 
     /* make sure vmxassist exists (this is not an error) */
-    if (!hvm_copy_phy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), 
HVM_COPY_IN))
+    if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
+                                 sizeof(magic)))
         return 0;
     if (magic != VMXASSIST_MAGIC)
         return 0;
@@ -1385,20 +1386,20 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_INVOKE:
         /* save the old context */
-        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
             if (!vmx_world_save(v, &c))
                 goto error;
-            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_OUT))
+            if (hvm_copy_to_guest_phys(cp, &c, sizeof(c)))
                 goto error;
         }
 
         /* restore the new context, this should activate vmxassist */
-        if (!hvm_copy_phy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
-            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
+            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
                 goto error;
             if (!vmx_world_restore(v, &c))
                 goto error;
@@ -1412,10 +1413,10 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_RESTORE:
         /* save the old context */
-        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
-            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
+            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
                 goto error;
             if (!vmx_world_restore(v, &c))
                 goto error;
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Fri Sep 29 11:10:14 2006 +0100
@@ -80,7 +80,7 @@ sh_x86_emulate_read_std(unsigned long ad
     //        It entirely ignores the permissions in the page tables.
     //        In this case, that is only a user vs supervisor access check.
     //
-    if ( hvm_copy(val, addr, bytes, HVM_COPY_IN) )
+    if ( hvm_copy_from_guest_virt(val, addr, bytes) == 0 )
     {
 #if 0
         struct vcpu *v = current;
@@ -115,7 +115,7 @@ sh_x86_emulate_write_std(unsigned long a
     //        In this case, that includes user vs supervisor, and
     //        write access.
     //
-    if ( hvm_copy(&val, addr, bytes, HVM_COPY_OUT) )
+    if ( hvm_copy_to_guest_virt(addr, &val, bytes) == 0 )
         return X86EMUL_CONTINUE;
 
     /* If we got here, there was nothing mapped here, or a bad GFN 
diff -r 412fc1c1bd7a -r 058f4a2a8642 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Fri Sep 29 10:30:18 2006 +0100
+++ b/xen/include/asm-x86/hvm/support.h Fri Sep 29 11:10:14 2006 +0100
@@ -136,17 +136,18 @@ extern unsigned int opt_hvm_debug_level;
 
 extern int hvm_enabled;
 
-enum { HVM_COPY_IN = 0, HVM_COPY_OUT };
-extern int hvm_copy(void *buf, unsigned long vaddr, int size, int dir);
-extern int hvm_copy_phy(void *buf, unsigned long vaddr, int size, int dir);
+int hvm_copy_to_guest_phys(unsigned long paddr, void *buf, int size);
+int hvm_copy_from_guest_phys(void *buf, unsigned long paddr, int size);
+int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size);
+int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size);
 
-extern void hvm_setup_platform(struct domain* d);
-extern int hvm_mmio_intercept(ioreq_t *p);
-extern int hvm_io_intercept(ioreq_t *p, int type);
-extern int hvm_buffered_io_intercept(ioreq_t *p);
-extern void hvm_hooks_assist(struct vcpu *v);
-extern void hvm_print_line(struct vcpu *v, const char c);
-extern void hlt_timer_fn(void *data);
+void hvm_setup_platform(struct domain* d);
+int hvm_mmio_intercept(ioreq_t *p);
+int hvm_io_intercept(ioreq_t *p, int type);
+int hvm_buffered_io_intercept(ioreq_t *p);
+void hvm_hooks_assist(struct vcpu *v);
+void hvm_print_line(struct vcpu *v, const char c);
+void hlt_timer_fn(void *data);
 
 void hvm_do_hypercall(struct cpu_user_regs *pregs);
 

_______________________________________________
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®.