Skip to content

Commit bda9020

Browse files
mstsirkinavikivity
authored andcommitted
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 <[email protected]> Signed-off-by: Avi Kivity <[email protected]>
1 parent 6c47469 commit bda9020

File tree

10 files changed

+152
-208
lines changed

10 files changed

+152
-208
lines changed

arch/ia64/kvm/kvm-ia64.c

+8-20
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,6 @@ int kvm_dev_ioctl_check_extension(long ext)
210210

211211
}
212212

213-
static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
214-
gpa_t addr, int len, int is_write)
215-
{
216-
struct kvm_io_device *dev;
217-
218-
dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write);
219-
220-
return dev;
221-
}
222-
223213
static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
224214
{
225215
kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
@@ -231,6 +221,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
231221
{
232222
struct kvm_mmio_req *p;
233223
struct kvm_io_device *mmio_dev;
224+
int r;
234225

235226
p = kvm_get_vcpu_ioreq(vcpu);
236227

@@ -247,16 +238,13 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
247238
kvm_run->exit_reason = KVM_EXIT_MMIO;
248239
return 0;
249240
mmio:
250-
mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir);
251-
if (mmio_dev) {
252-
if (!p->dir)
253-
kvm_iodevice_write(mmio_dev, p->addr, p->size,
254-
&p->data);
255-
else
256-
kvm_iodevice_read(mmio_dev, p->addr, p->size,
257-
&p->data);
258-
259-
} else
241+
if (p->dir)
242+
r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr,
243+
p->size, &p->data);
244+
else
245+
r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr,
246+
p->size, &p->data);
247+
if (r)
260248
printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
261249
p->state = STATE_IORESP_READY;
262250

arch/x86/kvm/i8254.c

+26-23
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,23 @@ static inline struct kvm_pit *speaker_to_pit(struct kvm_io_device *dev)
358358
return container_of(dev, struct kvm_pit, speaker_dev);
359359
}
360360

361-
static void pit_ioport_write(struct kvm_io_device *this,
362-
gpa_t addr, int len, const void *data)
361+
static inline int pit_in_range(gpa_t addr)
362+
{
363+
return ((addr >= KVM_PIT_BASE_ADDRESS) &&
364+
(addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
365+
}
366+
367+
static int pit_ioport_write(struct kvm_io_device *this,
368+
gpa_t addr, int len, const void *data)
363369
{
364370
struct kvm_pit *pit = dev_to_pit(this);
365371
struct kvm_kpit_state *pit_state = &pit->pit_state;
366372
struct kvm *kvm = pit->kvm;
367373
int channel, access;
368374
struct kvm_kpit_channel_state *s;
369375
u32 val = *(u32 *) data;
376+
if (!pit_in_range(addr))
377+
return -EOPNOTSUPP;
370378

371379
val &= 0xff;
372380
addr &= KVM_PIT_CHANNEL_MASK;
@@ -429,16 +437,19 @@ static void pit_ioport_write(struct kvm_io_device *this,
429437
}
430438

431439
mutex_unlock(&pit_state->lock);
440+
return 0;
432441
}
433442

434-
static void pit_ioport_read(struct kvm_io_device *this,
435-
gpa_t addr, int len, void *data)
443+
static int pit_ioport_read(struct kvm_io_device *this,
444+
gpa_t addr, int len, void *data)
436445
{
437446
struct kvm_pit *pit = dev_to_pit(this);
438447
struct kvm_kpit_state *pit_state = &pit->pit_state;
439448
struct kvm *kvm = pit->kvm;
440449
int ret, count;
441450
struct kvm_kpit_channel_state *s;
451+
if (!pit_in_range(addr))
452+
return -EOPNOTSUPP;
442453

443454
addr &= KVM_PIT_CHANNEL_MASK;
444455
s = &pit_state->channels[addr];
@@ -493,37 +504,36 @@ static void pit_ioport_read(struct kvm_io_device *this,
493504
memcpy(data, (char *)&ret, len);
494505

495506
mutex_unlock(&pit_state->lock);
507+
return 0;
496508
}
497509

498-
static int pit_in_range(struct kvm_io_device *this, gpa_t addr,
499-
int len, int is_write)
500-
{
501-
return ((addr >= KVM_PIT_BASE_ADDRESS) &&
502-
(addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
503-
}
504-
505-
static void speaker_ioport_write(struct kvm_io_device *this,
506-
gpa_t addr, int len, const void *data)
510+
static int speaker_ioport_write(struct kvm_io_device *this,
511+
gpa_t addr, int len, const void *data)
507512
{
508513
struct kvm_pit *pit = speaker_to_pit(this);
509514
struct kvm_kpit_state *pit_state = &pit->pit_state;
510515
struct kvm *kvm = pit->kvm;
511516
u32 val = *(u32 *) data;
517+
if (addr != KVM_SPEAKER_BASE_ADDRESS)
518+
return -EOPNOTSUPP;
512519

513520
mutex_lock(&pit_state->lock);
514521
pit_state->speaker_data_on = (val >> 1) & 1;
515522
pit_set_gate(kvm, 2, val & 1);
516523
mutex_unlock(&pit_state->lock);
524+
return 0;
517525
}
518526

519-
static void speaker_ioport_read(struct kvm_io_device *this,
520-
gpa_t addr, int len, void *data)
527+
static int speaker_ioport_read(struct kvm_io_device *this,
528+
gpa_t addr, int len, void *data)
521529
{
522530
struct kvm_pit *pit = speaker_to_pit(this);
523531
struct kvm_kpit_state *pit_state = &pit->pit_state;
524532
struct kvm *kvm = pit->kvm;
525533
unsigned int refresh_clock;
526534
int ret;
535+
if (addr != KVM_SPEAKER_BASE_ADDRESS)
536+
return -EOPNOTSUPP;
527537

528538
/* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
529539
refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1;
@@ -535,12 +545,7 @@ static void speaker_ioport_read(struct kvm_io_device *this,
535545
len = sizeof(ret);
536546
memcpy(data, (char *)&ret, len);
537547
mutex_unlock(&pit_state->lock);
538-
}
539-
540-
static int speaker_in_range(struct kvm_io_device *this, gpa_t addr,
541-
int len, int is_write)
542-
{
543-
return (addr == KVM_SPEAKER_BASE_ADDRESS);
548+
return 0;
544549
}
545550

546551
void kvm_pit_reset(struct kvm_pit *pit)
@@ -574,13 +579,11 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
574579
static const struct kvm_io_device_ops pit_dev_ops = {
575580
.read = pit_ioport_read,
576581
.write = pit_ioport_write,
577-
.in_range = pit_in_range,
578582
};
579583

580584
static const struct kvm_io_device_ops speaker_dev_ops = {
581585
.read = speaker_ioport_read,
582586
.write = speaker_ioport_write,
583-
.in_range = speaker_in_range,
584587
};
585588

586589
/* Caller must have writers lock on slots_lock */

arch/x86/kvm/i8259.c

+12-8
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,7 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1)
430430
return s->elcr;
431431
}
432432

433-
static int picdev_in_range(struct kvm_io_device *this, gpa_t addr,
434-
int len, int is_write)
433+
static int picdev_in_range(gpa_t addr)
435434
{
436435
switch (addr) {
437436
case 0x20:
@@ -451,16 +450,18 @@ static inline struct kvm_pic *to_pic(struct kvm_io_device *dev)
451450
return container_of(dev, struct kvm_pic, dev);
452451
}
453452

454-
static void picdev_write(struct kvm_io_device *this,
453+
static int picdev_write(struct kvm_io_device *this,
455454
gpa_t addr, int len, const void *val)
456455
{
457456
struct kvm_pic *s = to_pic(this);
458457
unsigned char data = *(unsigned char *)val;
458+
if (!picdev_in_range(addr))
459+
return -EOPNOTSUPP;
459460

460461
if (len != 1) {
461462
if (printk_ratelimit())
462463
printk(KERN_ERR "PIC: non byte write\n");
463-
return;
464+
return 0;
464465
}
465466
pic_lock(s);
466467
switch (addr) {
@@ -476,18 +477,21 @@ static void picdev_write(struct kvm_io_device *this,
476477
break;
477478
}
478479
pic_unlock(s);
480+
return 0;
479481
}
480482

481-
static void picdev_read(struct kvm_io_device *this,
482-
gpa_t addr, int len, void *val)
483+
static int picdev_read(struct kvm_io_device *this,
484+
gpa_t addr, int len, void *val)
483485
{
484486
struct kvm_pic *s = to_pic(this);
485487
unsigned char data = 0;
488+
if (!picdev_in_range(addr))
489+
return -EOPNOTSUPP;
486490

487491
if (len != 1) {
488492
if (printk_ratelimit())
489493
printk(KERN_ERR "PIC: non byte read\n");
490-
return;
494+
return 0;
491495
}
492496
pic_lock(s);
493497
switch (addr) {
@@ -504,6 +508,7 @@ static void picdev_read(struct kvm_io_device *this,
504508
}
505509
*(unsigned char *)val = data;
506510
pic_unlock(s);
511+
return 0;
507512
}
508513

509514
/*
@@ -526,7 +531,6 @@ static void pic_irq_request(void *opaque, int level)
526531
static const struct kvm_io_device_ops picdev_ops = {
527532
.read = picdev_read,
528533
.write = picdev_write,
529-
.in_range = picdev_in_range,
530534
};
531535

532536
struct kvm_pic *kvm_create_pic(struct kvm *kvm)

arch/x86/kvm/lapic.c

+20-24
Original file line numberDiff line numberDiff line change
@@ -546,18 +546,27 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
546546
return container_of(dev, struct kvm_lapic, dev);
547547
}
548548

549-
static void apic_mmio_read(struct kvm_io_device *this,
550-
gpa_t address, int len, void *data)
549+
static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
550+
{
551+
return apic_hw_enabled(apic) &&
552+
addr >= apic->base_address &&
553+
addr < apic->base_address + LAPIC_MMIO_LENGTH;
554+
}
555+
556+
static int apic_mmio_read(struct kvm_io_device *this,
557+
gpa_t address, int len, void *data)
551558
{
552559
struct kvm_lapic *apic = to_lapic(this);
553560
unsigned int offset = address - apic->base_address;
554561
unsigned char alignment = offset & 0xf;
555562
u32 result;
563+
if (!apic_mmio_in_range(apic, address))
564+
return -EOPNOTSUPP;
556565

557566
if ((alignment + len) > 4) {
558567
printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d",
559568
(unsigned long)address, len);
560-
return;
569+
return 0;
561570
}
562571
result = __apic_read(apic, offset & ~0xf);
563572

@@ -574,6 +583,7 @@ static void apic_mmio_read(struct kvm_io_device *this,
574583
"should be 1,2, or 4 instead\n", len);
575584
break;
576585
}
586+
return 0;
577587
}
578588

579589
static void update_divide_count(struct kvm_lapic *apic)
@@ -629,13 +639,15 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
629639
apic->vcpu->kvm->arch.vapics_in_nmi_mode--;
630640
}
631641

632-
static void apic_mmio_write(struct kvm_io_device *this,
633-
gpa_t address, int len, const void *data)
642+
static int apic_mmio_write(struct kvm_io_device *this,
643+
gpa_t address, int len, const void *data)
634644
{
635645
struct kvm_lapic *apic = to_lapic(this);
636646
unsigned int offset = address - apic->base_address;
637647
unsigned char alignment = offset & 0xf;
638648
u32 val;
649+
if (!apic_mmio_in_range(apic, address))
650+
return -EOPNOTSUPP;
639651

640652
/*
641653
* APIC register must be aligned on 128-bits boundary.
@@ -646,7 +658,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
646658
/* Don't shout loud, $infamous_os would cause only noise. */
647659
apic_debug("apic write: bad size=%d %lx\n",
648660
len, (long)address);
649-
return;
661+
return 0;
650662
}
651663

652664
val = *(u32 *) data;
@@ -729,7 +741,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
729741
hrtimer_cancel(&apic->lapic_timer.timer);
730742
apic_set_reg(apic, APIC_TMICT, val);
731743
start_apic_timer(apic);
732-
return;
744+
return 0;
733745

734746
case APIC_TDCR:
735747
if (val & 4)
@@ -743,22 +755,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
743755
offset);
744756
break;
745757
}
746-
747-
}
748-
749-
static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr,
750-
int len, int size)
751-
{
752-
struct kvm_lapic *apic = to_lapic(this);
753-
int ret = 0;
754-
755-
756-
if (apic_hw_enabled(apic) &&
757-
(addr >= apic->base_address) &&
758-
(addr < (apic->base_address + LAPIC_MMIO_LENGTH)))
759-
ret = 1;
760-
761-
return ret;
758+
return 0;
762759
}
763760

764761
void kvm_free_lapic(struct kvm_vcpu *vcpu)
@@ -938,7 +935,6 @@ static struct kvm_timer_ops lapic_timer_ops = {
938935
static const struct kvm_io_device_ops apic_mmio_ops = {
939936
.read = apic_mmio_read,
940937
.write = apic_mmio_write,
941-
.in_range = apic_mmio_range,
942938
};
943939

944940
int kvm_create_lapic(struct kvm_vcpu *vcpu)

0 commit comments

Comments
 (0)