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 | |
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')
-rw-r--r-- | arch/x86/kvm/i8254.c | 6 | ||||
-rw-r--r-- | arch/x86/kvm/i8259.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 28 |
4 files changed, 25 insertions, 15 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 60074dc66bd7..9e3391e9a1b7 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
@@ -460,7 +460,8 @@ static void pit_ioport_read(struct kvm_io_device *this, | |||
460 | mutex_unlock(&pit_state->lock); | 460 | mutex_unlock(&pit_state->lock); |
461 | } | 461 | } |
462 | 462 | ||
463 | static int pit_in_range(struct kvm_io_device *this, gpa_t addr) | 463 | static int pit_in_range(struct kvm_io_device *this, gpa_t addr, |
464 | int len, int is_write) | ||
464 | { | 465 | { |
465 | return ((addr >= KVM_PIT_BASE_ADDRESS) && | 466 | return ((addr >= KVM_PIT_BASE_ADDRESS) && |
466 | (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); | 467 | (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); |
@@ -501,7 +502,8 @@ static void speaker_ioport_read(struct kvm_io_device *this, | |||
501 | mutex_unlock(&pit_state->lock); | 502 | mutex_unlock(&pit_state->lock); |
502 | } | 503 | } |
503 | 504 | ||
504 | static int speaker_in_range(struct kvm_io_device *this, gpa_t addr) | 505 | static int speaker_in_range(struct kvm_io_device *this, gpa_t addr, |
506 | int len, int is_write) | ||
505 | { | 507 | { |
506 | return (addr == KVM_SPEAKER_BASE_ADDRESS); | 508 | return (addr == KVM_SPEAKER_BASE_ADDRESS); |
507 | } | 509 | } |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index ab29cf2def47..5857f59ad4aa 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -346,7 +346,8 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1) | |||
346 | return s->elcr; | 346 | return s->elcr; |
347 | } | 347 | } |
348 | 348 | ||
349 | static int picdev_in_range(struct kvm_io_device *this, gpa_t addr) | 349 | static int picdev_in_range(struct kvm_io_device *this, gpa_t addr, |
350 | int len, int is_write) | ||
350 | { | 351 | { |
351 | switch (addr) { | 352 | switch (addr) { |
352 | case 0x20: | 353 | case 0x20: |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e48d19394031..180ba7316da5 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -785,7 +785,8 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
785 | 785 | ||
786 | } | 786 | } |
787 | 787 | ||
788 | static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr) | 788 | static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr, |
789 | int len, int size) | ||
789 | { | 790 | { |
790 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | 791 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; |
791 | int ret = 0; | 792 | int ret = 0; |
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); |