|
@@ -1797,13 +1797,14 @@ static void kvm_init_msr_list(void)
|
|
|
* Only apic need an MMIO device hook, so shortcut now..
|
|
|
*/
|
|
|
static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
|
|
|
- gpa_t addr)
|
|
|
+ gpa_t addr, int len,
|
|
|
+ int is_write)
|
|
|
{
|
|
|
struct kvm_io_device *dev;
|
|
|
|
|
|
if (vcpu->arch.apic) {
|
|
|
dev = &vcpu->arch.apic->dev;
|
|
|
- if (dev->in_range(dev, addr))
|
|
|
+ if (dev->in_range(dev, addr, len, is_write))
|
|
|
return dev;
|
|
|
}
|
|
|
return NULL;
|
|
@@ -1811,13 +1812,15 @@ static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
|
|
|
|
|
|
|
|
|
static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
|
|
|
- gpa_t addr)
|
|
|
+ gpa_t addr, int len,
|
|
|
+ int is_write)
|
|
|
{
|
|
|
struct kvm_io_device *dev;
|
|
|
|
|
|
- dev = vcpu_find_pervcpu_dev(vcpu, addr);
|
|
|
+ dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write);
|
|
|
if (dev == NULL)
|
|
|
- dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
|
|
|
+ dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len,
|
|
|
+ is_write);
|
|
|
return dev;
|
|
|
}
|
|
|
|
|
@@ -1885,7 +1888,7 @@ mmio:
|
|
|
* Is this MMIO handled locally?
|
|
|
*/
|
|
|
mutex_lock(&vcpu->kvm->lock);
|
|
|
- mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
|
|
|
+ mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0);
|
|
|
if (mmio_dev) {
|
|
|
kvm_iodevice_read(mmio_dev, gpa, bytes, val);
|
|
|
mutex_unlock(&vcpu->kvm->lock);
|
|
@@ -1940,7 +1943,7 @@ mmio:
|
|
|
* Is this MMIO handled locally?
|
|
|
*/
|
|
|
mutex_lock(&vcpu->kvm->lock);
|
|
|
- mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
|
|
|
+ mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1);
|
|
|
if (mmio_dev) {
|
|
|
kvm_iodevice_write(mmio_dev, gpa, bytes, val);
|
|
|
mutex_unlock(&vcpu->kvm->lock);
|
|
@@ -2317,9 +2320,10 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
|
|
|
}
|
|
|
|
|
|
static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
|
|
|
- gpa_t addr)
|
|
|
+ gpa_t addr, int len,
|
|
|
+ int is_write)
|
|
|
{
|
|
|
- return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr);
|
|
|
+ return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write);
|
|
|
}
|
|
|
|
|
|
int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
|
|
@@ -2351,7 +2355,7 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
|
|
|
|
|
|
kvm_x86_ops->skip_emulated_instruction(vcpu);
|
|
|
|
|
|
- pio_dev = vcpu_find_pio_dev(vcpu, port);
|
|
|
+ pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
|
|
|
if (pio_dev) {
|
|
|
kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
|
|
|
complete_pio(vcpu);
|
|
@@ -2433,7 +2437,9 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pio_dev = vcpu_find_pio_dev(vcpu, port);
|
|
|
+ pio_dev = vcpu_find_pio_dev(vcpu, port,
|
|
|
+ vcpu->arch.pio.cur_count,
|
|
|
+ !vcpu->arch.pio.in);
|
|
|
if (!vcpu->arch.pio.in) {
|
|
|
/* string PIO write */
|
|
|
ret = pio_copy_data(vcpu);
|