diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2009-06-29 15:24:32 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:33:05 -0400 |
commit | bda9020e2463ec94db9f97e8615f3bae22069838 (patch) | |
tree | 48125316d4c0f419a35aefdfbf665d30ad0c55ca /virt/kvm/ioapic.c | |
parent | 6c474694530f377507f9aca438c17206e051e6e7 (diff) |
KVM: remove in_range from io devices
This changes bus accesses to use high-level kvm_io_bus_read/kvm_io_bus_write
functions. in_range now becomes unused so it is removed from device ops in
favor of read/write callbacks performing range checks internally.
This allows aliasing (mostly for in-kernel virtio), as well as better error
handling by making it possible to pass errors up to userspace.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/ioapic.c')
-rw-r--r-- | virt/kvm/ioapic.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 0eca54e06326..ddf6aa998b18 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -227,20 +227,19 @@ static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev) | |||
227 | return container_of(dev, struct kvm_ioapic, dev); | 227 | return container_of(dev, struct kvm_ioapic, dev); |
228 | } | 228 | } |
229 | 229 | ||
230 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr, | 230 | static inline int ioapic_in_range(struct kvm_ioapic *ioapic, gpa_t addr) |
231 | int len, int is_write) | ||
232 | { | 231 | { |
233 | struct kvm_ioapic *ioapic = to_ioapic(this); | ||
234 | |||
235 | return ((addr >= ioapic->base_address && | 232 | return ((addr >= ioapic->base_address && |
236 | (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); | 233 | (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); |
237 | } | 234 | } |
238 | 235 | ||
239 | static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | 236 | static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, |
240 | void *val) | 237 | void *val) |
241 | { | 238 | { |
242 | struct kvm_ioapic *ioapic = to_ioapic(this); | 239 | struct kvm_ioapic *ioapic = to_ioapic(this); |
243 | u32 result; | 240 | u32 result; |
241 | if (!ioapic_in_range(ioapic, addr)) | ||
242 | return -EOPNOTSUPP; | ||
244 | 243 | ||
245 | ioapic_debug("addr %lx\n", (unsigned long)addr); | 244 | ioapic_debug("addr %lx\n", (unsigned long)addr); |
246 | ASSERT(!(addr & 0xf)); /* check alignment */ | 245 | ASSERT(!(addr & 0xf)); /* check alignment */ |
@@ -273,13 +272,16 @@ static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | |||
273 | printk(KERN_WARNING "ioapic: wrong length %d\n", len); | 272 | printk(KERN_WARNING "ioapic: wrong length %d\n", len); |
274 | } | 273 | } |
275 | mutex_unlock(&ioapic->kvm->irq_lock); | 274 | mutex_unlock(&ioapic->kvm->irq_lock); |
275 | return 0; | ||
276 | } | 276 | } |
277 | 277 | ||
278 | static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | 278 | static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, |
279 | const void *val) | 279 | const void *val) |
280 | { | 280 | { |
281 | struct kvm_ioapic *ioapic = to_ioapic(this); | 281 | struct kvm_ioapic *ioapic = to_ioapic(this); |
282 | u32 data; | 282 | u32 data; |
283 | if (!ioapic_in_range(ioapic, addr)) | ||
284 | return -EOPNOTSUPP; | ||
283 | 285 | ||
284 | ioapic_debug("ioapic_mmio_write addr=%p len=%d val=%p\n", | 286 | ioapic_debug("ioapic_mmio_write addr=%p len=%d val=%p\n", |
285 | (void*)addr, len, val); | 287 | (void*)addr, len, val); |
@@ -290,7 +292,7 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | |||
290 | data = *(u32 *) val; | 292 | data = *(u32 *) val; |
291 | else { | 293 | else { |
292 | printk(KERN_WARNING "ioapic: Unsupported size %d\n", len); | 294 | printk(KERN_WARNING "ioapic: Unsupported size %d\n", len); |
293 | return; | 295 | return 0; |
294 | } | 296 | } |
295 | 297 | ||
296 | addr &= 0xff; | 298 | addr &= 0xff; |
@@ -312,6 +314,7 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | |||
312 | break; | 314 | break; |
313 | } | 315 | } |
314 | mutex_unlock(&ioapic->kvm->irq_lock); | 316 | mutex_unlock(&ioapic->kvm->irq_lock); |
317 | return 0; | ||
315 | } | 318 | } |
316 | 319 | ||
317 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic) | 320 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic) |
@@ -329,7 +332,6 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic) | |||
329 | static const struct kvm_io_device_ops ioapic_mmio_ops = { | 332 | static const struct kvm_io_device_ops ioapic_mmio_ops = { |
330 | .read = ioapic_mmio_read, | 333 | .read = ioapic_mmio_read, |
331 | .write = ioapic_mmio_write, | 334 | .write = ioapic_mmio_write, |
332 | .in_range = ioapic_in_range, | ||
333 | }; | 335 | }; |
334 | 336 | ||
335 | int kvm_ioapic_init(struct kvm *kvm) | 337 | int kvm_ioapic_init(struct kvm *kvm) |