* [PATCH 1/3] kvm: use kmalloc() instead of kzalloc() during iodev register/unregister
@ 2015-08-21 8:03 Jason Wang
2015-08-21 8:03 ` [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses Jason Wang
2015-08-21 8:03 ` [PATCH 3/3] kvm: add tracepoint for fast mmio Jason Wang
0 siblings, 2 replies; 8+ messages in thread
From: Jason Wang @ 2015-08-21 8:03 UTC (permalink / raw)
To: gleb, pbonzini, kvm, linux-kernel; +Cc: Jason Wang, Michael S. Tsirkin
All fields of kvm_io_range were initialized or copied explicitly
afterwards. So switch to use kmalloc().
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
virt/kvm/kvm_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 8b8a444..0d79fe8 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3248,7 +3248,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
if (bus->dev_count - bus->ioeventfd_count > NR_IOBUS_DEVS - 1)
return -ENOSPC;
- new_bus = kzalloc(sizeof(*bus) + ((bus->dev_count + 1) *
+ new_bus = kmalloc(sizeof(*bus) + ((bus->dev_count + 1) *
sizeof(struct kvm_io_range)), GFP_KERNEL);
if (!new_bus)
return -ENOMEM;
@@ -3280,7 +3280,7 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
if (r)
return r;
- new_bus = kzalloc(sizeof(*bus) + ((bus->dev_count - 1) *
+ new_bus = kmalloc(sizeof(*bus) + ((bus->dev_count - 1) *
sizeof(struct kvm_io_range)), GFP_KERNEL);
if (!new_bus)
return -ENOMEM;
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses
2015-08-21 8:03 [PATCH 1/3] kvm: use kmalloc() instead of kzalloc() during iodev register/unregister Jason Wang
@ 2015-08-21 8:03 ` Jason Wang
2015-08-21 9:29 ` Cornelia Huck
2015-08-21 8:03 ` [PATCH 3/3] kvm: add tracepoint for fast mmio Jason Wang
1 sibling, 1 reply; 8+ messages in thread
From: Jason Wang @ 2015-08-21 8:03 UTC (permalink / raw)
To: gleb, pbonzini, kvm, linux-kernel; +Cc: Jason Wang, Michael S. Tsirkin
We register wildcard mmio eventfd on two buses, one for KVM_MMIO_BUS
and another is KVM_FAST_MMIO_BUS. This leads to issue:
- kvm_io_bus_destroy() knows nothing about the devices on two buses
points to a single dev. Which will lead double free [1] during exit.
- wildcard eventfd ignores data len, so it was registered as a
kvm_io_range with zero length. This will fail the binary search in
kvm_io_bus_get_first_dev() when we try to emulate through
KVM_MMIO_BUS. This will cause userspace io emulation request instead
of a eventfd notification (virtqueue kick will be trapped by qemu
instead of vhost in this case).
Fixing this by don't register wildcard mmio eventfd on two
buses. Instead, only register it in KVM_FAST_MMIO_BUS. This fixes the
double free issue of kvm_io_bus_destroy(). For the arch/setups that
does not utilize KVM_FAST_MMIO_BUS, before search KVM_MMIO_BUS, try
KVM_FAST_MMIO_BUS first to see it it has a match.
[1] Panic caused by double free:
CPU: 1 PID: 2894 Comm: qemu-system-x86 Not tainted 3.19.0-26-generic #28-Ubuntu
Hardware name: LENOVO 2356BG6/2356BG6, BIOS G7ET96WW (2.56 ) 09/12/2013
task: ffff88009ae0c4b0 ti: ffff88020e7f0000 task.ti: ffff88020e7f0000
RIP: 0010:[<ffffffffc07e25d8>] [<ffffffffc07e25d8>] ioeventfd_release+0x28/0x60 [kvm]
RSP: 0018:ffff88020e7f3bc8 EFLAGS: 00010292
RAX: dead000000200200 RBX: ffff8801ec19c900 RCX: 000000018200016d
RDX: ffff8801ec19cf80 RSI: ffffea0008bf1d40 RDI: ffff8801ec19c900
RBP: ffff88020e7f3bd8 R08: 000000002fc75a01 R09: 000000018200016d
R10: ffffffffc07df6ae R11: ffff88022fc75a98 R12: ffff88021e7cc000
R13: ffff88021e7cca48 R14: ffff88021e7cca50 R15: ffff8801ec19c880
FS: 00007fc1ee3e6700(0000) GS:ffff88023e240000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f8f389d8000 CR3: 000000023dc13000 CR4: 00000000001427e0
Stack:
ffff88021e7cc000 0000000000000000 ffff88020e7f3be8 ffffffffc07e2622
ffff88020e7f3c38 ffffffffc07df69a ffff880232524160 ffff88020e792d80
0000000000000000 ffff880219b78c00 0000000000000008 ffff8802321686a8
Call Trace:
[<ffffffffc07e2622>] ioeventfd_destructor+0x12/0x20 [kvm]
[<ffffffffc07df69a>] kvm_put_kvm+0xca/0x210 [kvm]
[<ffffffffc07df818>] kvm_vcpu_release+0x18/0x20 [kvm]
[<ffffffff811f69f7>] __fput+0xe7/0x250
[<ffffffff811f6bae>] ____fput+0xe/0x10
[<ffffffff81093f04>] task_work_run+0xd4/0xf0
[<ffffffff81079358>] do_exit+0x368/0xa50
[<ffffffff81082c8f>] ? recalc_sigpending+0x1f/0x60
[<ffffffff81079ad5>] do_group_exit+0x45/0xb0
[<ffffffff81085c71>] get_signal+0x291/0x750
[<ffffffff810144d8>] do_signal+0x28/0xab0
[<ffffffff810f3a3b>] ? do_futex+0xdb/0x5d0
[<ffffffff810b7028>] ? __wake_up_locked_key+0x18/0x20
[<ffffffff810f3fa6>] ? SyS_futex+0x76/0x170
[<ffffffff81014fc9>] do_notify_resume+0x69/0xb0
[<ffffffff817cb9af>] int_signal+0x12/0x17
Code: 5d c3 90 0f 1f 44 00 00 55 48 89 e5 53 48 89 fb 48 83 ec 08 48 8b 7f 20 e8 06 d6 a5 c0 48 8b 43 08 48 8b 13 48 89 df 48 89 42 08 <48> 89 10 48 b8 00 01 10 00 00
RIP [<ffffffffc07e25d8>] ioeventfd_release+0x28/0x60 [kvm]
RSP <ffff88020e7f3bc8>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
virt/kvm/eventfd.c | 18 +++++++++---------
virt/kvm/kvm_main.c | 16 ++++++++++++++--
2 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 9ff4193..834a409 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -838,11 +838,6 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
kvm_iodevice_init(&p->dev, &ioeventfd_ops);
- ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
- &p->dev);
- if (ret < 0)
- goto unlock_fail;
-
/* When length is ignored, MMIO is also put on a separate bus, for
* faster lookups.
*/
@@ -850,9 +845,15 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
ret = kvm_io_bus_register_dev(kvm, KVM_FAST_MMIO_BUS,
p->addr, 0, &p->dev);
if (ret < 0)
- goto register_fail;
+ goto unlock_fail;
+ } else {
+ ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
+ &p->dev);
+ if (ret < 0)
+ goto unlock_fail;
}
+
kvm->buses[bus_idx]->ioeventfd_count++;
list_add_tail(&p->list, &kvm->ioeventfds);
@@ -860,8 +861,6 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
return 0;
-register_fail:
- kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
unlock_fail:
mutex_unlock(&kvm->slots_lock);
@@ -900,10 +899,11 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
if (!p->wildcard && p->datamatch != args->datamatch)
continue;
- kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
if (!p->length) {
kvm_io_bus_unregister_dev(kvm, KVM_FAST_MMIO_BUS,
&p->dev);
+ } else {
+ kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
}
kvm->buses[bus_idx]->ioeventfd_count--;
ioeventfd_release(p);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 0d79fe8..3e3b3bc 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3152,8 +3152,8 @@ static int __kvm_io_bus_write(struct kvm_vcpu *vcpu, struct kvm_io_bus *bus,
}
/* kvm_io_bus_write - called under kvm->slots_lock */
-int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
- int len, const void *val)
+static int kvm_io_bus_write_idx(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx,
+ gpa_t addr, int len, const void *val)
{
struct kvm_io_bus *bus;
struct kvm_io_range range;
@@ -3169,6 +3169,18 @@ int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
return r < 0 ? r : 0;
}
+int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
+ int len, const void *val)
+{
+ int r = 0;
+
+ if (bus_idx != KVM_MMIO_BUS ||
+ kvm_io_bus_write_idx(vcpu, KVM_FAST_MMIO_BUS, addr, 0, NULL) < 0)
+ r = kvm_io_bus_write_idx(vcpu, bus_idx, addr, len, val);
+
+ return r < 0 ? r : 0;
+}
+
/* kvm_io_bus_write_cookie - called under kvm->slots_lock */
int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx,
gpa_t addr, int len, const void *val, long cookie)
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] kvm: add tracepoint for fast mmio
2015-08-21 8:03 [PATCH 1/3] kvm: use kmalloc() instead of kzalloc() during iodev register/unregister Jason Wang
2015-08-21 8:03 ` [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses Jason Wang
@ 2015-08-21 8:03 ` Jason Wang
1 sibling, 0 replies; 8+ messages in thread
From: Jason Wang @ 2015-08-21 8:03 UTC (permalink / raw)
To: gleb, pbonzini, kvm, linux-kernel; +Cc: Jason Wang, Michael S. Tsirkin
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
arch/x86/kvm/trace.h | 17 +++++++++++++++++
arch/x86/kvm/vmx.c | 1 +
arch/x86/kvm/x86.c | 1 +
3 files changed, 19 insertions(+)
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 4eae7c3..2d4e81a 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -128,6 +128,23 @@ TRACE_EVENT(kvm_pio,
__entry->count > 1 ? "(...)" : "")
);
+TRACE_EVENT(kvm_fast_mmio,
+ TP_PROTO(u64 gpa),
+ TP_ARGS(gpa),
+
+ TP_STRUCT__entry(
+ __field(u64, gpa)
+ ),
+
+ TP_fast_assign(
+ __entry->gpa = gpa;
+ ),
+
+ TP_printk("fast mmio at gpa 0x%llx", __entry->gpa)
+);
+
+
+
/*
* Tracepoint for cpuid.
*/
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 83b7b5c..a55d279 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5831,6 +5831,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) {
skip_emulated_instruction(vcpu);
+ trace_kvm_fast_mmio(gpa);
return 1;
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5ef2560..271a0e6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8249,6 +8249,7 @@ bool kvm_arch_has_noncoherent_dma(struct kvm *kvm)
EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_msr);
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses
2015-08-21 8:03 ` [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses Jason Wang
@ 2015-08-21 9:29 ` Cornelia Huck
2015-08-24 3:29 ` Jason Wang
0 siblings, 1 reply; 8+ messages in thread
From: Cornelia Huck @ 2015-08-21 9:29 UTC (permalink / raw)
To: Jason Wang; +Cc: gleb, pbonzini, kvm, linux-kernel, Michael S. Tsirkin
On Fri, 21 Aug 2015 16:03:52 +0800
Jason Wang <jasowang@redhat.com> wrote:
> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
> index 9ff4193..834a409 100644
> --- a/virt/kvm/eventfd.c
> +++ b/virt/kvm/eventfd.c
> @@ -838,11 +838,6 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
>
> kvm_iodevice_init(&p->dev, &ioeventfd_ops);
>
> - ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
> - &p->dev);
> - if (ret < 0)
> - goto unlock_fail;
> -
> /* When length is ignored, MMIO is also put on a separate bus, for
> * faster lookups.
You probably want to change this comment as well?
> */
> @@ -850,9 +845,15 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
Unfortunately snipped by diff, but the check here is on !len && !PIO,
which only does the desired thing as VIRTIO_CCW always uses len == 8.
Should the check be for !len && MMIO instead?
> ret = kvm_io_bus_register_dev(kvm, KVM_FAST_MMIO_BUS,
> p->addr, 0, &p->dev);
> if (ret < 0)
> - goto register_fail;
> + goto unlock_fail;
> + } else {
> + ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
> + &p->dev);
> + if (ret < 0)
> + goto unlock_fail;
> }
Hm... maybe the following would be more obvious:
my_bus = (p->length == 0) && (bus_idx == KVM_MMIO_BUS) ? KVM_FAST_MMIO_BUS : bus_idx;
ret = kvm_io_bus_register_dev(kvm, my_bus, p->addr, p->length, &pdev->dev);
>
> +
> kvm->buses[bus_idx]->ioeventfd_count++;
> list_add_tail(&p->list, &kvm->ioeventfds);
(...)
> @@ -900,10 +899,11 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> if (!p->wildcard && p->datamatch != args->datamatch)
> continue;
>
> - kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
> if (!p->length) {
> kvm_io_bus_unregister_dev(kvm, KVM_FAST_MMIO_BUS,
> &p->dev);
> + } else {
> + kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
> }
Similar comments here... do you want to check for bus_idx ==
KVM_MMIO_BUS as well?
> kvm->buses[bus_idx]->ioeventfd_count--;
> ioeventfd_release(p);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses
2015-08-21 9:29 ` Cornelia Huck
@ 2015-08-24 3:29 ` Jason Wang
2015-08-24 14:05 ` Cornelia Huck
0 siblings, 1 reply; 8+ messages in thread
From: Jason Wang @ 2015-08-24 3:29 UTC (permalink / raw)
To: Cornelia Huck; +Cc: gleb, pbonzini, kvm, linux-kernel, Michael S. Tsirkin
On 08/21/2015 05:29 PM, Cornelia Huck wrote:
> On Fri, 21 Aug 2015 16:03:52 +0800
> Jason Wang <jasowang@redhat.com> wrote:
>
>
>> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
>> index 9ff4193..834a409 100644
>> --- a/virt/kvm/eventfd.c
>> +++ b/virt/kvm/eventfd.c
>> @@ -838,11 +838,6 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
>>
>> kvm_iodevice_init(&p->dev, &ioeventfd_ops);
>>
>> - ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
>> - &p->dev);
>> - if (ret < 0)
>> - goto unlock_fail;
>> -
>> /* When length is ignored, MMIO is also put on a separate bus, for
>> * faster lookups.
> You probably want to change this comment as well?
Yes.
>
>> */
>> @@ -850,9 +845,15 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> Unfortunately snipped by diff, but the check here is on !len && !PIO,
> which only does the desired thing as VIRTIO_CCW always uses len == 8.
> Should the check be for !len && MMIO instead?
I think the answer depends on whether len == 0 is valid for ccw. If not
we can fail the assign earlier. Since even without this patch, if
userspace tries to register a dev with len equals to zero, it will also
be registered to KVM_FAST_MMIO_BUS. If yes, we need check as you
suggested here.
>
>> ret = kvm_io_bus_register_dev(kvm, KVM_FAST_MMIO_BUS,
>> p->addr, 0, &p->dev);
>> if (ret < 0)
>> - goto register_fail;
>> + goto unlock_fail;
>> + } else {
>> + ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
>> + &p->dev);
>> + if (ret < 0)
>> + goto unlock_fail;
>> }
> Hm... maybe the following would be more obvious:
>
> my_bus = (p->length == 0) && (bus_idx == KVM_MMIO_BUS) ? KVM_FAST_MMIO_BUS : bus_idx;
> ret = kvm_io_bus_register_dev(kvm, my_bus, p->addr, p->length, &pdev->dev);
>
>>
>> +
>> kvm->buses[bus_idx]->ioeventfd_count++;
>> list_add_tail(&p->list, &kvm->ioeventfds);
> (...)
>
>> @@ -900,10 +899,11 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
>> if (!p->wildcard && p->datamatch != args->datamatch)
>> continue;
>>
>> - kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
>> if (!p->length) {
>> kvm_io_bus_unregister_dev(kvm, KVM_FAST_MMIO_BUS,
>> &p->dev);
>> + } else {
>> + kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
>> }
> Similar comments here... do you want to check for bus_idx ==
> KVM_MMIO_BUS as well?
Good catch. I think keep the original code as is will be also ok to
solve this. (with changing the bus_idx to KVM_FAST_MMIO_BUS during
registering if it was an wildcard mmio).
>
>> kvm->buses[bus_idx]->ioeventfd_count--;
>> ioeventfd_release(p);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses
2015-08-24 3:29 ` Jason Wang
@ 2015-08-24 14:05 ` Cornelia Huck
2015-08-25 3:04 ` Jason Wang
0 siblings, 1 reply; 8+ messages in thread
From: Cornelia Huck @ 2015-08-24 14:05 UTC (permalink / raw)
To: Jason Wang; +Cc: gleb, pbonzini, kvm, linux-kernel, Michael S. Tsirkin
On Mon, 24 Aug 2015 11:29:29 +0800
Jason Wang <jasowang@redhat.com> wrote:
> On 08/21/2015 05:29 PM, Cornelia Huck wrote:
> > On Fri, 21 Aug 2015 16:03:52 +0800
> > Jason Wang <jasowang@redhat.com> wrote:
> >> @@ -850,9 +845,15 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> > Unfortunately snipped by diff, but the check here is on !len && !PIO,
> > which only does the desired thing as VIRTIO_CCW always uses len == 8.
> > Should the check be for !len && MMIO instead?
>
> I think the answer depends on whether len == 0 is valid for ccw. If not
> we can fail the assign earlier. Since even without this patch, if
> userspace tries to register a dev with len equals to zero, it will also
> be registered to KVM_FAST_MMIO_BUS. If yes, we need check as you
> suggested here.
I don't think len != 8 makes much sense for the way ioeventfd is
defined for ccw (we handle hypercalls with a payload specifying the
device), but we currently don't actively fence it.
But regardless, I'd prefer to decide directly upon whether userspace
actually tried to register for the mmio bus.
>
> >
> >> ret = kvm_io_bus_register_dev(kvm, KVM_FAST_MMIO_BUS,
> >> p->addr, 0, &p->dev);
> >> if (ret < 0)
> >> - goto register_fail;
> >> + goto unlock_fail;
> >> + } else {
> >> + ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
> >> + &p->dev);
> >> + if (ret < 0)
> >> + goto unlock_fail;
> >> }
> > Hm... maybe the following would be more obvious:
> >
> > my_bus = (p->length == 0) && (bus_idx == KVM_MMIO_BUS) ? KVM_FAST_MMIO_BUS : bus_idx;
> > ret = kvm_io_bus_register_dev(kvm, my_bus, p->addr, p->length, &pdev->dev);
> >
> >>
> >> +
> >> kvm->buses[bus_idx]->ioeventfd_count++;
> >> list_add_tail(&p->list, &kvm->ioeventfds);
> > (...)
> >
> >> @@ -900,10 +899,11 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> >> if (!p->wildcard && p->datamatch != args->datamatch)
> >> continue;
> >>
> >> - kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
> >> if (!p->length) {
> >> kvm_io_bus_unregister_dev(kvm, KVM_FAST_MMIO_BUS,
> >> &p->dev);
> >> + } else {
> >> + kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
> >> }
> > Similar comments here... do you want to check for bus_idx ==
> > KVM_MMIO_BUS as well?
>
> Good catch. I think keep the original code as is will be also ok to
> solve this. (with changing the bus_idx to KVM_FAST_MMIO_BUS during
> registering if it was an wildcard mmio).
Do you need to handle the ioeventfd_count changes on the fast mmio bus
as well?
>
> >
> >> kvm->buses[bus_idx]->ioeventfd_count--;
> >> ioeventfd_release(p);
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses
2015-08-24 14:05 ` Cornelia Huck
@ 2015-08-25 3:04 ` Jason Wang
2015-08-25 7:36 ` Jason Wang
0 siblings, 1 reply; 8+ messages in thread
From: Jason Wang @ 2015-08-25 3:04 UTC (permalink / raw)
To: Cornelia Huck; +Cc: gleb, pbonzini, kvm, linux-kernel, Michael S. Tsirkin
On 08/24/2015 10:05 PM, Cornelia Huck wrote:
> On Mon, 24 Aug 2015 11:29:29 +0800
> Jason Wang <jasowang@redhat.com> wrote:
>
>> On 08/21/2015 05:29 PM, Cornelia Huck wrote:
>>> On Fri, 21 Aug 2015 16:03:52 +0800
>>> Jason Wang <jasowang@redhat.com> wrote:
>>>> @@ -850,9 +845,15 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
>>> Unfortunately snipped by diff, but the check here is on !len && !PIO,
>>> which only does the desired thing as VIRTIO_CCW always uses len == 8.
>>> Should the check be for !len && MMIO instead?
>> I think the answer depends on whether len == 0 is valid for ccw. If not
>> we can fail the assign earlier. Since even without this patch, if
>> userspace tries to register a dev with len equals to zero, it will also
>> be registered to KVM_FAST_MMIO_BUS. If yes, we need check as you
>> suggested here.
> I don't think len != 8 makes much sense for the way ioeventfd is
> defined for ccw (we handle hypercalls with a payload specifying the
> device), but we currently don't actively fence it.
>
> But regardless, I'd prefer to decide directly upon whether userspace
> actually tried to register for the mmio bus.
Ok.
>
>>>> ret = kvm_io_bus_register_dev(kvm, KVM_FAST_MMIO_BUS,
>>>> p->addr, 0, &p->dev);
>>>> if (ret < 0)
>>>> - goto register_fail;
>>>> + goto unlock_fail;
>>>> + } else {
>>>> + ret = kvm_io_bus_register_dev(kvm, bus_idx, p->addr, p->length,
>>>> + &p->dev);
>>>> + if (ret < 0)
>>>> + goto unlock_fail;
>>>> }
>>> Hm... maybe the following would be more obvious:
>>>
>>> my_bus = (p->length == 0) && (bus_idx == KVM_MMIO_BUS) ? KVM_FAST_MMIO_BUS : bus_idx;
>>> ret = kvm_io_bus_register_dev(kvm, my_bus, p->addr, p->length, &pdev->dev);
>>>
>>>>
>>>> +
>>>> kvm->buses[bus_idx]->ioeventfd_count++;
>>>> list_add_tail(&p->list, &kvm->ioeventfds);
>>> (...)
>>>
>>>> @@ -900,10 +899,11 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
>>>> if (!p->wildcard && p->datamatch != args->datamatch)
>>>> continue;
>>>>
>>>> - kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
>>>> if (!p->length) {
>>>> kvm_io_bus_unregister_dev(kvm, KVM_FAST_MMIO_BUS,
>>>> &p->dev);
>>>> + } else {
>>>> + kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
>>>> }
>>> Similar comments here... do you want to check for bus_idx ==
>>> KVM_MMIO_BUS as well?
>> Good catch. I think keep the original code as is will be also ok to
>> solve this. (with changing the bus_idx to KVM_FAST_MMIO_BUS during
>> registering if it was an wildcard mmio).
> Do you need to handle the ioeventfd_count changes on the fast mmio bus
> as well?
Yes. So actually, it needs some changes: checking the return value of
kvm_io_bus_unregister_dev() and decide which bus does the device belongs to.
>
>>>> kvm->buses[bus_idx]->ioeventfd_count--;
>>>> ioeventfd_release(p);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses
2015-08-25 3:04 ` Jason Wang
@ 2015-08-25 7:36 ` Jason Wang
0 siblings, 0 replies; 8+ messages in thread
From: Jason Wang @ 2015-08-25 7:36 UTC (permalink / raw)
To: Cornelia Huck; +Cc: gleb, pbonzini, kvm, linux-kernel, Michael S. Tsirkin
On 08/25/2015 11:04 AM, Jason Wang wrote:
[...]
>>>>> @@ -900,10 +899,11 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
>>>>> >>>> if (!p->wildcard && p->datamatch != args->datamatch)
>>>>> >>>> continue;
>>>>> >>>>
>>>>> >>>> - kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
>>>>> >>>> if (!p->length) {
>>>>> >>>> kvm_io_bus_unregister_dev(kvm, KVM_FAST_MMIO_BUS,
>>>>> >>>> &p->dev);
>>>>> >>>> + } else {
>>>>> >>>> + kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
>>>>> >>>> }
>>>> >>> Similar comments here... do you want to check for bus_idx ==
>>>> >>> KVM_MMIO_BUS as well?
>>> >> Good catch. I think keep the original code as is will be also ok to
>>> >> solve this. (with changing the bus_idx to KVM_FAST_MMIO_BUS during
>>> >> registering if it was an wildcard mmio).
>> > Do you need to handle the ioeventfd_count changes on the fast mmio bus
>> > as well?
> Yes. So actually, it needs some changes: checking the return value of
> kvm_io_bus_unregister_dev() and decide which bus does the device belongs to.
>
Looks like it will be more cleaner by just changing
ioeventfd_bus_from_flags() to return KVM_FAST_MMIO_BUS accordingly. Will
post V2 soon.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-08-25 7:36 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-21 8:03 [PATCH 1/3] kvm: use kmalloc() instead of kzalloc() during iodev register/unregister Jason Wang
2015-08-21 8:03 ` [PATCH 2/3] kvm: don't register wildcard MMIO EVENTFD on two buses Jason Wang
2015-08-21 9:29 ` Cornelia Huck
2015-08-24 3:29 ` Jason Wang
2015-08-24 14:05 ` Cornelia Huck
2015-08-25 3:04 ` Jason Wang
2015-08-25 7:36 ` Jason Wang
2015-08-21 8:03 ` [PATCH 3/3] kvm: add tracepoint for fast mmio Jason Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).