ia64/xen-unstable

changeset 11677:058f4a2a8642

[HVM] Clean up hvm_copy interface to be more like copy_to/from_user.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Sep 29 11:10:14 2006 +0100 (2006-09-29)
parents 412fc1c1bd7a
children e5cdebf9d8ef
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/i8259.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/mm/shadow/common.c xen/include/asm-x86/hvm/support.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Sep 29 10:30:18 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Sep 29 11:10:14 2006 +0100
     1.3 @@ -393,9 +393,9 @@ void hvm_hlt(unsigned long rflags)
     1.4   *  @buf  = hypervisor buffer
     1.5   *  @addr = guest virtual or physical address to copy to/from
     1.6   *  @size = number of bytes to copy
     1.7 - *  @dir  = HVM_COPY_IN / HVM_COPY_OUT
     1.8 - *  @phy  = interpret addr as physical or virtual address?
     1.9 - * Returns TRUE on success.
    1.10 + *  @dir  = copy *to* guest (TRUE) or *from* guest (FALSE)?
    1.11 + *  @phy  = interpret addr as physical (TRUE) or virtual (FALSE) address?
    1.12 + * Returns number of bytes failed to copy (0 == complete success).
    1.13   */
    1.14  static int __hvm_copy(
    1.15      void *buf, unsigned long addr, int size, int dir, int phy)
    1.16 @@ -403,43 +403,54 @@ static int __hvm_copy(
    1.17      struct vcpu *v = current;
    1.18      unsigned long mfn;
    1.19      char *p;
    1.20 -    int count;
    1.21 +    int count, todo;
    1.22  
    1.23 -    while ( size > 0 )
    1.24 +    todo = size;
    1.25 +    while ( todo > 0 )
    1.26      {
    1.27 -        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), size);
    1.28 +        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo);
    1.29  
    1.30          mfn = phy ? 
    1.31              get_mfn_from_gpfn(addr >> PAGE_SHIFT) :
    1.32              mfn_x(sh_vcpu_gfn_to_mfn(v, shadow_gva_to_gfn(v, addr)));
    1.33          if ( mfn == INVALID_MFN )
    1.34 -            return 0;
    1.35 +            return todo;
    1.36  
    1.37          p = (char *)map_domain_page(mfn) + (addr & ~PAGE_MASK);
    1.38  
    1.39 -        if ( dir == HVM_COPY_IN )
    1.40 -            memcpy(buf, p, count);
    1.41 +        if ( dir )
    1.42 +            memcpy(p, buf, count); /* dir == TRUE:  *to* guest */
    1.43          else
    1.44 -            memcpy(p, buf, count);
    1.45 +            memcpy(buf, p, count); /* dir == FALSE: *from guest */
    1.46  
    1.47          unmap_domain_page(p);
    1.48  
    1.49          addr += count;
    1.50          buf  += count;
    1.51 -        size -= count;
    1.52 +        todo -= count;
    1.53      }
    1.54  
    1.55 -    return 1;
    1.56 +    return 0;
    1.57  }
    1.58  
    1.59 -int hvm_copy_phy(void *buf, unsigned long paddr, int size, int dir)
    1.60 +int hvm_copy_to_guest_phys(unsigned long paddr, void *buf, int size)
    1.61  {
    1.62 -    return __hvm_copy(buf, paddr, size, dir, 1);
    1.63 +    return __hvm_copy(buf, paddr, size, 1, 1);
    1.64  }
    1.65  
    1.66 -int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
    1.67 +int hvm_copy_from_guest_phys(void *buf, unsigned long paddr, int size)
    1.68  {
    1.69 -    return __hvm_copy(buf, vaddr, size, dir, 0);
    1.70 +    return __hvm_copy(buf, paddr, size, 0, 1);
    1.71 +}
    1.72 +
    1.73 +int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size)
    1.74 +{
    1.75 +    return __hvm_copy(buf, vaddr, size, 1, 0);
    1.76 +}
    1.77 +
    1.78 +int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size)
    1.79 +{
    1.80 +    return __hvm_copy(buf, vaddr, size, 0, 0);
    1.81  }
    1.82  
    1.83  /*
     2.1 --- a/xen/arch/x86/hvm/i8259.c	Fri Sep 29 10:30:18 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/i8259.c	Fri Sep 29 11:10:14 2006 +0100
     2.3 @@ -497,8 +497,9 @@ static int intercept_pic_io(ioreq_t *p)
     2.4      }
     2.5      pic = &v->domain->arch.hvm_domain.vpic;
     2.6      if ( p->dir == 0 ) {
     2.7 -        if(p->pdata_valid) 
     2.8 -            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
     2.9 +        if (p->pdata_valid) 
    2.10 +            (void)hvm_copy_from_guest_virt(
    2.11 +                &data, (unsigned long)p->u.pdata, p->size);
    2.12          else
    2.13              data = p->u.data;
    2.14          spin_lock_irqsave(&pic->lock, flags);
    2.15 @@ -511,8 +512,9 @@ static int intercept_pic_io(ioreq_t *p)
    2.16          data = pic_ioport_read(
    2.17              (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
    2.18          spin_unlock_irqrestore(&pic->lock, flags);
    2.19 -        if(p->pdata_valid) 
    2.20 -            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
    2.21 +        if (p->pdata_valid) 
    2.22 +            (void)hvm_copy_to_guest_virt(
    2.23 +                (unsigned long)p->u.pdata, &data, p->size);
    2.24          else 
    2.25              p->u.data = (u64)data;
    2.26      }
    2.27 @@ -533,8 +535,9 @@ static int intercept_elcr_io(ioreq_t *p)
    2.28  
    2.29      s = &v->domain->arch.hvm_domain.vpic;
    2.30      if ( p->dir == 0 ) {
    2.31 -        if(p->pdata_valid) 
    2.32 -            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_IN);
    2.33 +        if (p->pdata_valid) 
    2.34 +            (void)hvm_copy_from_guest_virt(
    2.35 +                &data, (unsigned long)p->u.pdata, p->size);
    2.36          else
    2.37              data = p->u.data;
    2.38          spin_lock_irqsave(&s->lock, flags);
    2.39 @@ -547,8 +550,9 @@ static int intercept_elcr_io(ioreq_t *p)
    2.40      else {
    2.41          data = (u64) elcr_ioport_read(
    2.42                  (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
    2.43 -        if(p->pdata_valid) 
    2.44 -            hvm_copy(&data, (unsigned long)p->u.pdata, p->size, HVM_COPY_OUT);
    2.45 +        if (p->pdata_valid) 
    2.46 +            (void)hvm_copy_to_guest_virt(
    2.47 +                (unsigned long)p->u.pdata, &data, p->size);
    2.48          else 
    2.49              p->u.data = (u64)data;
    2.50  
     3.1 --- a/xen/arch/x86/hvm/intercept.c	Fri Sep 29 10:30:18 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/intercept.c	Fri Sep 29 11:10:14 2006 +0100
     3.3 @@ -90,17 +90,17 @@ static inline void hvm_mmio_access(struc
     3.4                      data = read_handler(v,
     3.5                        req->addr + (sign * i * req->size),
     3.6                        req->size);
     3.7 -                    hvm_copy(&data,
     3.8 -                      (unsigned long)p->u.pdata + (sign * i * req->size),
     3.9 -                      p->size,
    3.10 -                      HVM_COPY_OUT);
    3.11 +                    (void)hvm_copy_to_guest_virt(
    3.12 +                        (unsigned long)p->u.pdata + (sign * i * req->size),
    3.13 +                        &data,
    3.14 +                        p->size);
    3.15                  }
    3.16              } else {                  /* !req->dir == IOREQ_READ */
    3.17                  for (i = 0; i < req->count; i++) {
    3.18 -                    hvm_copy(&data,
    3.19 -                      (unsigned long)p->u.pdata + (sign * i * req->size),
    3.20 -                      p->size,
    3.21 -                      HVM_COPY_IN);
    3.22 +                    (void)hvm_copy_from_guest_virt(
    3.23 +                        &data,
    3.24 +                        (unsigned long)p->u.pdata + (sign * i * req->size),
    3.25 +                        p->size);
    3.26                      write_handler(v,
    3.27                        req->addr + (sign * i * req->size),
    3.28                        req->size, data);
     4.1 --- a/xen/arch/x86/hvm/io.c	Fri Sep 29 10:30:18 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/io.c	Fri Sep 29 11:10:14 2006 +0100
     4.3 @@ -379,7 +379,7 @@ static void hvm_pio_assist(struct cpu_us
     4.4                      addr += regs->es << 4;
     4.5                  if (sign > 0)
     4.6                      addr -= p->size;
     4.7 -                hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
     4.8 +                (void)hvm_copy_to_guest_virt(addr, &p->u.data, p->size);
     4.9              }
    4.10          }
    4.11          else /* p->dir == IOREQ_WRITE */
    4.12 @@ -493,7 +493,7 @@ static void hvm_mmio_assist(struct cpu_u
    4.13  
    4.14              if (sign > 0)
    4.15                  addr -= p->size;
    4.16 -            hvm_copy(&p->u.data, addr, p->size, HVM_COPY_OUT);
    4.17 +            (void)hvm_copy_to_guest_virt(addr, &p->u.data, p->size);
    4.18          }
    4.19  
    4.20          if (mmio_opp->flags & REPZ)
     5.1 --- a/xen/arch/x86/hvm/platform.c	Fri Sep 29 10:30:18 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/platform.c	Fri Sep 29 11:10:14 2006 +0100
     5.3 @@ -689,7 +689,7 @@ int inst_copy_from_guest(unsigned char *
     5.4  {
     5.5      if (inst_len > MAX_INST_LEN || inst_len <= 0)
     5.6          return 0;
     5.7 -    if (!hvm_copy(buf, guest_eip, inst_len, HVM_COPY_IN))
     5.8 +    if (hvm_copy_from_guest_virt(buf, guest_eip, inst_len))
     5.9          return 0;
    5.10      return inst_len;
    5.11  }
    5.12 @@ -953,7 +953,7 @@ void handle_mmio(unsigned long va, unsig
    5.13              regs->eip -= inst_len; /* do not advance %eip */
    5.14  
    5.15              if (dir == IOREQ_WRITE)
    5.16 -                hvm_copy(&value, addr, size, HVM_COPY_IN);
    5.17 +                (void)hvm_copy_from_guest_virt(&value, addr, size);
    5.18              send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
    5.19          } else {
    5.20              if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) & PAGE_MASK)) {
    5.21 @@ -1094,7 +1094,7 @@ unsigned long copy_to_user_hvm(void *to,
    5.22          return 0;
    5.23      }
    5.24  
    5.25 -    return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT);
    5.26 +    return hvm_copy_to_guest_virt((unsigned long)to, (void *)from, len);
    5.27  }
    5.28  
    5.29  unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
    5.30 @@ -1105,7 +1105,7 @@ unsigned long copy_from_user_hvm(void *t
    5.31          return 0;
    5.32      }
    5.33  
    5.34 -    return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN);
    5.35 +    return hvm_copy_from_guest_virt(to, (unsigned long)from, len);
    5.36  }
    5.37  
    5.38  /*
     6.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Sep 29 10:30:18 2006 +0100
     6.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Sep 29 11:10:14 2006 +0100
     6.3 @@ -1471,7 +1471,7 @@ static void svm_io_instruction(struct vc
     6.4              pio_opp->flags |= OVERLAP;
     6.5  
     6.6              if (dir == IOREQ_WRITE)
     6.7 -                hvm_copy(&value, addr, size, HVM_COPY_IN);
     6.8 +                (void)hvm_copy_from_guest_virt(&value, addr, size);
     6.9  
    6.10              send_pio_req(regs, port, 1, size, value, dir, 0);
    6.11          } 
    6.12 @@ -2325,7 +2325,7 @@ void svm_dump_inst(unsigned long eip)
    6.13      ptr = eip & ~0xff;
    6.14      len = 0;
    6.15  
    6.16 -    if (hvm_copy(opcode, ptr, sizeof(opcode), HVM_COPY_IN))
    6.17 +    if (hvm_copy_from_guest_virt(opcode, ptr, sizeof(opcode)) == 0)
    6.18          len = sizeof(opcode);
    6.19  
    6.20      printf("Code bytes around(len=%d) %lx:", len, eip);
     7.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 29 10:30:18 2006 +0100
     7.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 29 11:10:14 2006 +0100
     7.3 @@ -1164,7 +1164,7 @@ static void vmx_io_instruction(unsigned 
     7.4  
     7.5              pio_opp->flags |= OVERLAP;
     7.6              if (dir == IOREQ_WRITE)
     7.7 -                hvm_copy(&value, addr, size, HVM_COPY_IN);
     7.8 +                (void)hvm_copy_from_guest_virt(&value, addr, size);
     7.9              send_pio_req(regs, port, 1, size, value, dir, 0);
    7.10          } else {
    7.11              if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) {
    7.12 @@ -1371,7 +1371,8 @@ static int vmx_assist(struct vcpu *v, in
    7.13      u32 cp;
    7.14  
    7.15      /* make sure vmxassist exists (this is not an error) */
    7.16 -    if (!hvm_copy_phy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN))
    7.17 +    if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
    7.18 +                                 sizeof(magic)))
    7.19          return 0;
    7.20      if (magic != VMXASSIST_MAGIC)
    7.21          return 0;
    7.22 @@ -1385,20 +1386,20 @@ static int vmx_assist(struct vcpu *v, in
    7.23           */
    7.24      case VMX_ASSIST_INVOKE:
    7.25          /* save the old context */
    7.26 -        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
    7.27 +        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
    7.28              goto error;
    7.29          if (cp != 0) {
    7.30              if (!vmx_world_save(v, &c))
    7.31                  goto error;
    7.32 -            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_OUT))
    7.33 +            if (hvm_copy_to_guest_phys(cp, &c, sizeof(c)))
    7.34                  goto error;
    7.35          }
    7.36  
    7.37          /* restore the new context, this should activate vmxassist */
    7.38 -        if (!hvm_copy_phy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
    7.39 +        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)))
    7.40              goto error;
    7.41          if (cp != 0) {
    7.42 -            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
    7.43 +            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
    7.44                  goto error;
    7.45              if (!vmx_world_restore(v, &c))
    7.46                  goto error;
    7.47 @@ -1412,10 +1413,10 @@ static int vmx_assist(struct vcpu *v, in
    7.48           */
    7.49      case VMX_ASSIST_RESTORE:
    7.50          /* save the old context */
    7.51 -        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
    7.52 +        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
    7.53              goto error;
    7.54          if (cp != 0) {
    7.55 -            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
    7.56 +            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
    7.57                  goto error;
    7.58              if (!vmx_world_restore(v, &c))
    7.59                  goto error;
     8.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Sep 29 10:30:18 2006 +0100
     8.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Sep 29 11:10:14 2006 +0100
     8.3 @@ -80,7 +80,7 @@ sh_x86_emulate_read_std(unsigned long ad
     8.4      //        It entirely ignores the permissions in the page tables.
     8.5      //        In this case, that is only a user vs supervisor access check.
     8.6      //
     8.7 -    if ( hvm_copy(val, addr, bytes, HVM_COPY_IN) )
     8.8 +    if ( hvm_copy_from_guest_virt(val, addr, bytes) == 0 )
     8.9      {
    8.10  #if 0
    8.11          struct vcpu *v = current;
    8.12 @@ -115,7 +115,7 @@ sh_x86_emulate_write_std(unsigned long a
    8.13      //        In this case, that includes user vs supervisor, and
    8.14      //        write access.
    8.15      //
    8.16 -    if ( hvm_copy(&val, addr, bytes, HVM_COPY_OUT) )
    8.17 +    if ( hvm_copy_to_guest_virt(addr, &val, bytes) == 0 )
    8.18          return X86EMUL_CONTINUE;
    8.19  
    8.20      /* If we got here, there was nothing mapped here, or a bad GFN 
     9.1 --- a/xen/include/asm-x86/hvm/support.h	Fri Sep 29 10:30:18 2006 +0100
     9.2 +++ b/xen/include/asm-x86/hvm/support.h	Fri Sep 29 11:10:14 2006 +0100
     9.3 @@ -136,17 +136,18 @@ extern unsigned int opt_hvm_debug_level;
     9.4  
     9.5  extern int hvm_enabled;
     9.6  
     9.7 -enum { HVM_COPY_IN = 0, HVM_COPY_OUT };
     9.8 -extern int hvm_copy(void *buf, unsigned long vaddr, int size, int dir);
     9.9 -extern int hvm_copy_phy(void *buf, unsigned long vaddr, int size, int dir);
    9.10 +int hvm_copy_to_guest_phys(unsigned long paddr, void *buf, int size);
    9.11 +int hvm_copy_from_guest_phys(void *buf, unsigned long paddr, int size);
    9.12 +int hvm_copy_to_guest_virt(unsigned long vaddr, void *buf, int size);
    9.13 +int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size);
    9.14  
    9.15 -extern void hvm_setup_platform(struct domain* d);
    9.16 -extern int hvm_mmio_intercept(ioreq_t *p);
    9.17 -extern int hvm_io_intercept(ioreq_t *p, int type);
    9.18 -extern int hvm_buffered_io_intercept(ioreq_t *p);
    9.19 -extern void hvm_hooks_assist(struct vcpu *v);
    9.20 -extern void hvm_print_line(struct vcpu *v, const char c);
    9.21 -extern void hlt_timer_fn(void *data);
    9.22 +void hvm_setup_platform(struct domain* d);
    9.23 +int hvm_mmio_intercept(ioreq_t *p);
    9.24 +int hvm_io_intercept(ioreq_t *p, int type);
    9.25 +int hvm_buffered_io_intercept(ioreq_t *p);
    9.26 +void hvm_hooks_assist(struct vcpu *v);
    9.27 +void hvm_print_line(struct vcpu *v, const char c);
    9.28 +void hlt_timer_fn(void *data);
    9.29  
    9.30  void hvm_do_hypercall(struct cpu_user_regs *pregs);
    9.31