ia64/xen-unstable

changeset 11829:edcd3a25a2bd

[HVM] Fix PIC IO intercept: addresses are physical, not virtual.

Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
Signed-off-by: Xin Li <xin.b.li@intel.com>
author kfraser@localhost.localdomain
date Sun Oct 15 09:15:51 2006 +0100 (2006-10-15)
parents 7da100019e00
children e321f036f603
files xen/arch/x86/hvm/i8259.c xen/arch/x86/hvm/platform.c
line diff
     1.1 --- a/xen/arch/x86/hvm/i8259.c	Fri Oct 13 18:04:33 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/i8259.c	Sun Oct 15 09:15:51 2006 +0100
     1.3 @@ -498,19 +498,19 @@ void pic_init(struct hvm_virpic *s, void
     1.4  
     1.5  static int intercept_pic_io(ioreq_t *p)
     1.6  {
     1.7 -    struct hvm_virpic  *pic;
     1.8 -    struct vcpu *v = current;
     1.9 +    struct hvm_virpic *pic;
    1.10      uint32_t data;
    1.11      unsigned long flags;
    1.12 -    
    1.13 -    if ( p->size != 1 || p->count != 1) {
    1.14 +
    1.15 +    if ( p->size != 1 || p->count != 1 ) {
    1.16          printk("PIC_IO wrong access size %d!\n", (int)p->size);
    1.17          return 1;
    1.18      }
    1.19 -    pic = &v->domain->arch.hvm_domain.vpic;
    1.20 -    if ( p->dir == 0 ) {
    1.21 -        if (p->pdata_valid) 
    1.22 -            (void)hvm_copy_from_guest_virt(
    1.23 +
    1.24 +    pic = &current->domain->arch.hvm_domain.vpic;
    1.25 +    if ( p->dir == IOREQ_WRITE ) {
    1.26 +        if ( p->pdata_valid )
    1.27 +            (void)hvm_copy_from_guest_phys(
    1.28                  &data, (unsigned long)p->u.pdata, p->size);
    1.29          else
    1.30              data = p->u.data;
    1.31 @@ -524,10 +524,10 @@ static int intercept_pic_io(ioreq_t *p)
    1.32          data = pic_ioport_read(
    1.33              (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr);
    1.34          spin_unlock_irqrestore(&pic->lock, flags);
    1.35 -        if (p->pdata_valid) 
    1.36 -            (void)hvm_copy_to_guest_virt(
    1.37 +        if ( p->pdata_valid )
    1.38 +            (void)hvm_copy_to_guest_phys(
    1.39                  (unsigned long)p->u.pdata, &data, p->size);
    1.40 -        else 
    1.41 +        else
    1.42              p->u.data = (u64)data;
    1.43      }
    1.44      return 1;
    1.45 @@ -535,42 +535,41 @@ static int intercept_pic_io(ioreq_t *p)
    1.46  
    1.47  static int intercept_elcr_io(ioreq_t *p)
    1.48  {
    1.49 -    struct hvm_virpic  *s;
    1.50 -    struct vcpu *v = current;
    1.51 +    struct hvm_virpic *s;
    1.52      uint32_t data;
    1.53      unsigned long flags;
    1.54 -    
    1.55 +
    1.56      if ( p->size != 1 || p->count != 1 ) {
    1.57          printk("PIC_IO wrong access size %d!\n", (int)p->size);
    1.58          return 1;
    1.59      }
    1.60  
    1.61 -    s = &v->domain->arch.hvm_domain.vpic;
    1.62 -    if ( p->dir == 0 ) {
    1.63 -        if (p->pdata_valid) 
    1.64 -            (void)hvm_copy_from_guest_virt(
    1.65 +    s = &current->domain->arch.hvm_domain.vpic;
    1.66 +    if ( p->dir == IOREQ_WRITE ) {
    1.67 +        if ( p->pdata_valid )
    1.68 +            (void)hvm_copy_from_guest_phys(
    1.69                  &data, (unsigned long)p->u.pdata, p->size);
    1.70          else
    1.71              data = p->u.data;
    1.72          spin_lock_irqsave(&s->lock, flags);
    1.73          elcr_ioport_write((void*)&s->pics[p->addr&1],
    1.74                  (uint32_t) p->addr, (uint32_t)( data & 0xff));
    1.75 -        get_sp(current->domain)->sp_global.pic_elcr = 
    1.76 +        get_sp(current->domain)->sp_global.pic_elcr =
    1.77              s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
    1.78          spin_unlock_irqrestore(&s->lock, flags);
    1.79      }
    1.80      else {
    1.81          data = (u64) elcr_ioport_read(
    1.82                  (void*)&s->pics[p->addr&1], (uint32_t) p->addr);
    1.83 -        if (p->pdata_valid) 
    1.84 -            (void)hvm_copy_to_guest_virt(
    1.85 +        if ( p->pdata_valid )
    1.86 +            (void)hvm_copy_to_guest_phys(
    1.87                  (unsigned long)p->u.pdata, &data, p->size);
    1.88 -        else 
    1.89 +        else
    1.90              p->u.data = (u64)data;
    1.91 -
    1.92      }
    1.93      return 1;
    1.94  }
    1.95 +
    1.96  void register_pic_io_hook (void)
    1.97  {
    1.98      register_portio_handler(0x20, 2, intercept_pic_io);
     2.1 --- a/xen/arch/x86/hvm/platform.c	Fri Oct 13 18:04:33 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/platform.c	Sun Oct 15 09:15:51 2006 +0100
     2.3 @@ -730,13 +730,13 @@ void send_pio_req(struct cpu_user_regs *
     2.4      vcpu_iodata_t *vio;
     2.5      ioreq_t *p;
     2.6  
     2.7 -    if (size == 0 || count == 0) {
     2.8 +    if ( size == 0 || count == 0 ) {
     2.9          printf("null pio request? port %lx, count %lx, size %d, value %lx, dir %d, pvalid %d.\n",
    2.10                 port, count, size, value, dir, pvalid);
    2.11      }
    2.12  
    2.13      vio = get_vio(v->domain, v->vcpu_id);
    2.14 -    if (vio == NULL) {
    2.15 +    if ( vio == NULL ) {
    2.16          printk("bad shared page: %lx\n", (unsigned long) vio);
    2.17          domain_crash_synchronous();
    2.18      }
    2.19 @@ -745,6 +745,7 @@ void send_pio_req(struct cpu_user_regs *
    2.20      if ( p->state != STATE_INVALID )
    2.21          printk("WARNING: send pio with something already pending (%d)?\n",
    2.22                 p->state);
    2.23 +
    2.24      p->dir = dir;
    2.25      p->pdata_valid = pvalid;
    2.26  
    2.27 @@ -752,19 +753,20 @@ void send_pio_req(struct cpu_user_regs *
    2.28      p->size = size;
    2.29      p->addr = port;
    2.30      p->count = count;
    2.31 -    p->df = regs->eflags & EF_DF ? 1 : 0;
    2.32 +    p->df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
    2.33  
    2.34      p->io_count++;
    2.35  
    2.36 -    if (pvalid) {
    2.37 -        if (hvm_paging_enabled(current))
    2.38 -            p->u.data = shadow_gva_to_gpa(current, value);
    2.39 +    if ( pvalid )   /* get physical address of data */
    2.40 +    {
    2.41 +        if ( hvm_paging_enabled(current) )
    2.42 +            p->u.pdata = (void *)shadow_gva_to_gpa(current, value);
    2.43          else
    2.44 -            p->u.pdata = (void *) value; /* guest VA == guest PA */
    2.45 -    } else
    2.46 +            p->u.pdata = (void *)value; /* guest VA == guest PA */
    2.47 +    } else if ( dir == IOREQ_WRITE )
    2.48          p->u.data = value;
    2.49  
    2.50 -    if (hvm_portio_intercept(p)) {
    2.51 +    if ( hvm_portio_intercept(p) ) {
    2.52          p->state = STATE_IORESP_READY;
    2.53          hvm_io_assist(v);
    2.54          return;