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>
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 = ¤t->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 = ¤t->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;