[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |