diff options
author | Laurent Vivier <Laurent.Vivier@bull.net> | 2008-05-30 10:05:53 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-20 05:42:30 -0400 |
commit | 92760499d01ef91518119908eb9b8798b6c9bd3f (patch) | |
tree | a6bd80fbad82589eb5aa98f81edda4537bc1f625 /arch/x86/kvm/x86.c | |
parent | 131d82791b628d4aeafd94ddc74a9b68f3d15a83 (diff) |
KVM: kvm_io_device: extend in_range() to manage len and write attribute
Modify member in_range() of structure kvm_io_device to pass length and the type
of the I/O (write or read).
This modification allows to use kvm_io_device with coalesced MMIO.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4c94fad7f01e..ab3f5552d694 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1797,13 +1797,14 @@ static void kvm_init_msr_list(void) | |||
1797 | * Only apic need an MMIO device hook, so shortcut now.. | 1797 | * Only apic need an MMIO device hook, so shortcut now.. |
1798 | */ | 1798 | */ |
1799 | static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, | 1799 | static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, |
1800 | gpa_t addr) | 1800 | gpa_t addr, int len, |
1801 | int is_write) | ||
1801 | { | 1802 | { |
1802 | struct kvm_io_device *dev; | 1803 | struct kvm_io_device *dev; |
1803 | 1804 | ||
1804 | if (vcpu->arch.apic) { | 1805 | if (vcpu->arch.apic) { |
1805 | dev = &vcpu->arch.apic->dev; | 1806 | dev = &vcpu->arch.apic->dev; |
1806 | if (dev->in_range(dev, addr)) | 1807 | if (dev->in_range(dev, addr, len, is_write)) |
1807 | return dev; | 1808 | return dev; |
1808 | } | 1809 | } |
1809 | return NULL; | 1810 | return NULL; |
@@ -1811,13 +1812,15 @@ static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, | |||
1811 | 1812 | ||
1812 | 1813 | ||
1813 | static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, | 1814 | static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, |
1814 | gpa_t addr) | 1815 | gpa_t addr, int len, |
1816 | int is_write) | ||
1815 | { | 1817 | { |
1816 | struct kvm_io_device *dev; | 1818 | struct kvm_io_device *dev; |
1817 | 1819 | ||
1818 | dev = vcpu_find_pervcpu_dev(vcpu, addr); | 1820 | dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write); |
1819 | if (dev == NULL) | 1821 | if (dev == NULL) |
1820 | dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); | 1822 | dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, |
1823 | is_write); | ||
1821 | return dev; | 1824 | return dev; |
1822 | } | 1825 | } |
1823 | 1826 | ||
@@ -1885,7 +1888,7 @@ mmio: | |||
1885 | * Is this MMIO handled locally? | 1888 | * Is this MMIO handled locally? |
1886 | */ | 1889 | */ |
1887 | mutex_lock(&vcpu->kvm->lock); | 1890 | mutex_lock(&vcpu->kvm->lock); |
1888 | mmio_dev = vcpu_find_mmio_dev(vcpu, gpa); | 1891 | mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0); |
1889 | if (mmio_dev) { | 1892 | if (mmio_dev) { |
1890 | kvm_iodevice_read(mmio_dev, gpa, bytes, val); | 1893 | kvm_iodevice_read(mmio_dev, gpa, bytes, val); |
1891 | mutex_unlock(&vcpu->kvm->lock); | 1894 | mutex_unlock(&vcpu->kvm->lock); |
@@ -1940,7 +1943,7 @@ mmio: | |||
1940 | * Is this MMIO handled locally? | 1943 | * Is this MMIO handled locally? |
1941 | */ | 1944 | */ |
1942 | mutex_lock(&vcpu->kvm->lock); | 1945 | mutex_lock(&vcpu->kvm->lock); |
1943 | mmio_dev = vcpu_find_mmio_dev(vcpu, gpa); | 1946 | mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1); |
1944 | if (mmio_dev) { | 1947 | if (mmio_dev) { |
1945 | kvm_iodevice_write(mmio_dev, gpa, bytes, val); | 1948 | kvm_iodevice_write(mmio_dev, gpa, bytes, val); |
1946 | mutex_unlock(&vcpu->kvm->lock); | 1949 | mutex_unlock(&vcpu->kvm->lock); |
@@ -2317,9 +2320,10 @@ static void pio_string_write(struct kvm_io_device *pio_dev, | |||
2317 | } | 2320 | } |
2318 | 2321 | ||
2319 | static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, | 2322 | static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, |
2320 | gpa_t addr) | 2323 | gpa_t addr, int len, |
2324 | int is_write) | ||
2321 | { | 2325 | { |
2322 | return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr); | 2326 | return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write); |
2323 | } | 2327 | } |
2324 | 2328 | ||
2325 | int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | 2329 | 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, | |||
2351 | 2355 | ||
2352 | kvm_x86_ops->skip_emulated_instruction(vcpu); | 2356 | kvm_x86_ops->skip_emulated_instruction(vcpu); |
2353 | 2357 | ||
2354 | pio_dev = vcpu_find_pio_dev(vcpu, port); | 2358 | pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in); |
2355 | if (pio_dev) { | 2359 | if (pio_dev) { |
2356 | kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data); | 2360 | kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data); |
2357 | complete_pio(vcpu); | 2361 | complete_pio(vcpu); |
@@ -2433,7 +2437,9 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
2433 | } | 2437 | } |
2434 | } | 2438 | } |
2435 | 2439 | ||
2436 | pio_dev = vcpu_find_pio_dev(vcpu, port); | 2440 | pio_dev = vcpu_find_pio_dev(vcpu, port, |
2441 | vcpu->arch.pio.cur_count, | ||
2442 | !vcpu->arch.pio.in); | ||
2437 | if (!vcpu->arch.pio.in) { | 2443 | if (!vcpu->arch.pio.in) { |
2438 | /* string PIO write */ | 2444 | /* string PIO write */ |
2439 | ret = pio_copy_data(vcpu); | 2445 | ret = pio_copy_data(vcpu); |