[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>
This commit is contained in:
kfraser@localhost.localdomain committed 2006-10-15 09:15:51 +01:00
1 parent ad5b45d12e
commit b2e0105ec9
2 files changed
+33 -32

No files matched your search

+22 -23
View File
@@ -498,19 +498,19 @@ void pic_init(struct hvm_virpic *s, void (*irq_request)(void *, int),
static int intercept_pic_io(ioreq_t *p)
{
struct hvm_virpic *pic;
struct vcpu *v = current;
struct hvm_virpic *pic;
uint32_t data;
unsigned long flags;
if ( p->size != 1 || p->count != 1) {
if ( p->size != 1 || p->count != 1 ) {
printk("PIC_IO wrong access size %d!\n", (int)p->size);
return 1;
}
pic = &v->domain->arch.hvm_domain.vpic;
if ( p->dir == 0 ) {
if (p->pdata_valid)
(void)hvm_copy_from_guest_virt(
pic = &current->domain->arch.hvm_domain.vpic;
if ( p->dir == IOREQ_WRITE ) {
if ( p->pdata_valid )
(void)hvm_copy_from_guest_phys(
&data, (unsigned long)p->u.pdata, p->size);
else
data = p->u.data;
@@ -524,10 +524,10 @@ 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)
(void)hvm_copy_to_guest_virt(
if ( p->pdata_valid )
(void)hvm_copy_to_guest_phys(
(unsigned long)p->u.pdata, &data, p->size);
else
else
p->u.data = (u64)data;
}
return 1;
@@ -535,42 +535,41 @@ static int intercept_pic_io(ioreq_t *p)
static int intercept_elcr_io(ioreq_t *p)
{
struct hvm_virpic *s;
struct vcpu *v = current;
struct hvm_virpic *s;
uint32_t data;
unsigned long flags;
if ( p->size != 1 || p->count != 1 ) {
printk("PIC_IO wrong access size %d!\n", (int)p->size);
return 1;
}
s = &v->domain->arch.hvm_domain.vpic;
if ( p->dir == 0 ) {
if (p->pdata_valid)
(void)hvm_copy_from_guest_virt(
s = &current->domain->arch.hvm_domain.vpic;
if ( p->dir == IOREQ_WRITE ) {
if ( p->pdata_valid )
(void)hvm_copy_from_guest_phys(
&data, (unsigned long)p->u.pdata, p->size);
else
data = p->u.data;
spin_lock_irqsave(&s->lock, flags);
elcr_ioport_write((void*)&s->pics[p->addr&1],
(uint32_t) p->addr, (uint32_t)( data & 0xff));
get_sp(current->domain)->sp_global.pic_elcr =
get_sp(current->domain)->sp_global.pic_elcr =
s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
spin_unlock_irqrestore(&s->lock, flags);
}
else {
data = (u64) elcr_ioport_read(
(void*)&s->pics[p->addr&1], (uint32_t) p->addr);
if (p->pdata_valid)
(void)hvm_copy_to_guest_virt(
if ( p->pdata_valid )
(void)hvm_copy_to_guest_phys(
(unsigned long)p->u.pdata, &data, p->size);
else
else
p->u.data = (u64)data;
}
return 1;
}
void register_pic_io_hook (void)
{
register_portio_handler(0x20, 2, intercept_pic_io);
+11 -9
View File
@@ -730,13 +730,13 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
vcpu_iodata_t *vio;
ioreq_t *p;
if (size == 0 || count == 0) {
if ( size == 0 || count == 0 ) {
printf("null pio request? port %lx, count %lx, size %d, value %lx, dir %d, pvalid %d.\n",
port, count, size, value, dir, pvalid);
}
vio = get_vio(v->domain, v->vcpu_id);
if (vio == NULL) {
if ( vio == NULL ) {
printk("bad shared page: %lx\n", (unsigned long) vio);
domain_crash_synchronous();
}
@@ -745,6 +745,7 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
if ( p->state != STATE_INVALID )
printk("WARNING: send pio with something already pending (%d)?\n",
p->state);
p->dir = dir;
p->pdata_valid = pvalid;
@@ -752,19 +753,20 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
p->size = size;
p->addr = port;
p->count = count;
p->df = regs->eflags & EF_DF ? 1 : 0;
p->df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
p->io_count++;
if (pvalid) {
if (hvm_paging_enabled(current))
p->u.data = shadow_gva_to_gpa(current, value);
if ( pvalid ) /* get physical address of data */
{
if ( hvm_paging_enabled(current) )
p->u.pdata = (void *)shadow_gva_to_gpa(current, value);
else
p->u.pdata = (void *) value; /* guest VA == guest PA */
} else
p->u.pdata = (void *)value; /* guest VA == guest PA */
} else if ( dir == IOREQ_WRITE )
p->u.data = value;
if (hvm_portio_intercept(p)) {
if ( hvm_portio_intercept(p) ) {
p->state = STATE_IORESP_READY;
hvm_io_assist(v);
return;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.