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