KVM: arm: Implement software vGICv2 emulation
cover KVM: arm: Implement software vGICv2 emulation
Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks functional vGIC registers. This series introduces software vGIC emulation for such machines, allowing to fully use virtualization capabilities
Pavel Fedin (3):
KVM: arm: Add basic infrastructure for software vGIC emulation
KVM: arm: Introduce software emulation of vGICv2 CPU interface
KVM: arm: Enable vGICv2 software emulation
include/kvm/arm_vgic.h | 4 ++ virt/kvm/arm/vgic-v2-emul.c | 60 +++++++++++++++-- virt/kvm/arm/vgic-v2.c | 29 ++++---- virt/kvm/arm/vgic.c | 159 +++++++++++++++++++++++++++++++++----------- virt/kvm/arm/vgic.h | 3 + 5 files changed, 196 insertions(+), 59 deletions(-)
Signature · 1 line
2.1.4
PATCH 1/3 KVM: arm: Add basic infrastructure for software vGIC emulation
Two main functions (vgic_get_pending_irq() and vgic_clear_pending_irq()) are responsible for ACK and EOI respectively. Maintenance code path refactored in order to accommodate these changes. The main problem is that __kvm_vgic_sync_hwstate() is called before I/O emulation takes place, therefore vgic_process_maintenance() cannot be reused.
--- include/kvm/arm_vgic.h | 3 + virt/kvm/arm/vgic.c | 149 ++++++++++++++++++++++++++++++++++++++----------- virt/kvm/arm/vgic.h | 3 + 3 files changed, 121 insertions(+), 34 deletions(-)
include/kvm/arm_vgic.h +3 -0
@@ -160,6 +160,9 @@ struct vgic_dist {bool in_kernel;bool ready; +/* Use software emulation of CPU interface */ +bool sw_cpuif; +/* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */ u32 vgic_model;
virt/kvm/arm/vgic.c +115 -34
183 lines not on this page · raw message
virt/kvm/arm/vgic.h +3 -0
@@ -59,6 +59,9 @@ void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);bool vgic_queue_irq (struct kvm_vcpu *vcpu,u8 sgi_source_id,int irq);void vgic_unqueue_irqs (struct kvm_vcpu *vcpu); +int vgic_get_pending_irq (struct kvm_vcpu *vcpu); +void vgic_clear_pending_irq (struct kvm_vcpu *vcpu,int irq); +struct kvm_exit_mmio {phys_addr_t phys_addr;void *data;
Signature · 1 line
2.1.4
PATCH 2/3 KVM: arm: Introduce software emulation of vGICv2 CPU interface
In reply to Pavel FedinThe emulation code is activated by setting params->vcpu_base to zero
--- include/kvm/arm_vgic.h | 1 + virt/kvm/arm/vgic-v2-emul.c | 60 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 6 deletions(-)
include/kvm/arm_vgic.h +1 -0
@@ -254,6 +254,7 @@ struct vgic_dist {struct vgic_vm_ops vm_ops;struct vgic_io_device dist_iodev; +struct vgic_io_device cpu_iodev;struct vgic_io_device *redist_iodevs; };
virt/kvm/arm/vgic-v2-emul.c +54 -6
84 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 3/3 KVM: arm: Enable vGICv2 software emulation
In reply to Pavel FedinThe emulation code is automatically enabled when one of vGIC resources is missing from the device tree
--- virt/kvm/arm/vgic-v2.c | 29 ++++++++++++++--------------- virt/kvm/arm/vgic.c | 10 ++++++---- 2 files changed, 20 insertions(+), 19 deletions(-)
virt/kvm/arm/vgic-v2.c +14 -15
@@ -180,22 +180,27 @@ int vgic_v2_probe(struct device_node *vgic_node,const struct vgic_ops **ops, const struct vgic_params **params) { - int ret; + int ret = 0;struct resource vctrl_res;struct resource vcpu_res;struct vgic_params *vgic = &vgic_v2_params; + vgic->nr_lr =VGIC_V2_MAX_LRS ; + vgic->maint_irq =irq_of_parse_and_map (vgic_node,0 );if (!vgic->maint_irq) {kvm_err ("error getting vgic maintenance irq from DT\n" ); - ret = -ENXIO ; - goto out; + goto sw_emul; } - ret =of_address_to_resource (vgic_node,2 , &vctrl_res); -if (ret) { +if (of_address_to_resource (vgic_node,2 , &vctrl_res)) {kvm_err ("Cannot obtain GICH resource\n" ); - goto out; + goto sw_emul; + } + +if (of_address_to_resource (vgic_node,3 , &vcpu_res)) { +kvm_err ("Cannot obtain GICV resource\n" ); + goto sw_emul; } vgic->vctrl_base =of_iomap (vgic_node,2 );
@@ -216,12 +221,6 @@ int vgic_v2_probe(struct device_node *vgic_node, goto out_unmap; } -if (of_address_to_resource (vgic_node,3 , &vcpu_res)) { -kvm_err ("Cannot obtain GICV resource\n" ); - ret = -ENXIO ; - goto out_unmap; - } -if (!PAGE_ALIGNED (vcpu_res.start)) {kvm_err ("GICV physical address 0x%llx not page aligned\n" , (unsigned long long )vcpu_res.start);
@@ -237,13 +236,13 @@ int vgic_v2_probe(struct device_node *vgic_node, goto out_unmap; } - vgic->can_emulate_gicv2 = true; -kvm_register_device_ops (&kvm_arm_vgic_v2_ops,KVM_DEV_TYPE_ARM_VGIC_V2 ); - vgic->vcpu_base = vcpu_res.start;kvm_info ("%s@%llx IRQ%d\n" , vgic_node->name, vctrl_res.start, vgic->maint_irq); +sw_emul: + vgic->can_emulate_gicv2 = true; +kvm_register_device_ops (&kvm_arm_vgic_v2_ops,KVM_DEV_TYPE_ARM_VGIC_V2 ); vgic->type =VGIC_V2 ; vgic->max_gic_vcpus =VGIC_V2_MAX_CPUS ;
virt/kvm/arm/vgic.c +6 -4
@@ -2196,11 +2196,13 @@ int kvm_vgic_hyp_init(void)if (ret)return ret; - ret =request_percpu_irq (vgic->maint_irq, vgic_maintenance_handler, +if (vgic->maint_irq) { + ret =request_percpu_irq (vgic->maint_irq, vgic_maintenance_handler,"vgic" ,kvm_get_running_vcpus ()); -if (ret) { -kvm_err ("Cannot register interrupt %d\n" , vgic->maint_irq); -return ret; +if (ret) { +kvm_err ("Cannot register interrupt %d\n" , vgic->maint_irq); +return ret; + } } ret =__register_cpu_notifier (&vgic_cpu_nb);
Signature · 1 line
2.1.4
Re: [PATCH 3/3] KVM: arm: Enable vGICv2 software emulation
Quoted 2 lines · Pavel Fedin
The emulation code is automatically enabled when one of vGIC resources is missing from the device tree
Hold on a second. In your cover letter, your saying "RPi-2". The RPi-2 doesn't have a GIC at all, so I'd really like to know *how* you end-up in the GICv2 probe function?
Thanks,
M.
Quoted 98 lines
Signed-off-by Pavel Fedin <[email protected]>--- virt/kvm/arm/vgic-v2.c | 29 ++++++++++++++--------------- virt/kvm/arm/vgic.c | 10 ++++++---- 2 files changed, 20 insertions(+), 19 deletions(-)virt/kvm/arm/vgic-v2.c +14
-15@@ -180,22 +180,27 @@ int vgic_v2_probe(struct device_node *vgic_node,const struct vgic_ops **ops, const struct vgic_params **params) { - int ret; + int ret = 0;struct resource vctrl_res;struct resource vcpu_res;struct vgic_params *vgic = &vgic_v2_params; + vgic->nr_lr =VGIC_V2_MAX_LRS ; + vgic->maint_irq =irq_of_parse_and_map (vgic_node,0 );if (!vgic->maint_irq) {kvm_err ("error getting vgic maintenance irq from DT\n" ); - ret = -ENXIO ; - goto out; + goto sw_emul; } - ret =of_address_to_resource (vgic_node,2 , &vctrl_res); -if (ret) { +if (of_address_to_resource (vgic_node,2 , &vctrl_res)) {kvm_err ("Cannot obtain GICH resource\n" ); - goto out; + goto sw_emul; + } + +if (of_address_to_resource (vgic_node,3 , &vcpu_res)) { +kvm_err ("Cannot obtain GICV resource\n" ); + goto sw_emul; } vgic->vctrl_base =of_iomap (vgic_node,2 );@@ -216,12 +221,6 @@ int vgic_v2_probe(struct device_node *vgic_node, goto out_unmap; } -if (of_address_to_resource (vgic_node,3 , &vcpu_res)) { -kvm_err ("Cannot obtain GICV resource\n" ); - ret = -ENXIO ; - goto out_unmap; - } -if (!PAGE_ALIGNED (vcpu_res.start)) {kvm_err ("GICV physical address 0x%llx not page aligned\n" , (unsigned long long )vcpu_res.start);@@ -237,13 +236,13 @@ int vgic_v2_probe(struct device_node *vgic_node, goto out_unmap; } - vgic->can_emulate_gicv2 = true; -kvm_register_device_ops (&kvm_arm_vgic_v2_ops,KVM_DEV_TYPE_ARM_VGIC_V2 ); - vgic->vcpu_base = vcpu_res.start;kvm_info ("%s@%llx IRQ%d\n" , vgic_node->name, vctrl_res.start, vgic->maint_irq); +sw_emul: + vgic->can_emulate_gicv2 = true; +kvm_register_device_ops (&kvm_arm_vgic_v2_ops,KVM_DEV_TYPE_ARM_VGIC_V2 ); vgic->type =VGIC_V2 ; vgic->max_gic_vcpus =VGIC_V2_MAX_CPUS ;virt/kvm/arm/vgic.c +6
-4@@ -2196,11 +2196,13 @@ int kvm_vgic_hyp_init(void)if (ret)return ret; - ret =request_percpu_irq (vgic->maint_irq, vgic_maintenance_handler, +if (vgic->maint_irq) { + ret =request_percpu_irq (vgic->maint_irq, vgic_maintenance_handler,"vgic" ,kvm_get_running_vcpus ()); -if (ret) { -kvm_err ("Cannot register interrupt %d\n" , vgic->maint_irq); -return ret; +if (ret) { +kvm_err ("Cannot register interrupt %d\n" , vgic->maint_irq); +return ret; + } } ret =__register_cpu_notifier (&vgic_cpu_nb);
Signature · 1 line
Jazz is not dead. It just smells funny...
RE: [PATCH 3/3] KVM: arm: Enable vGICv2 software emulation
Hello!
Quoted 3 lines
Hold on a second. In your cover letter, your saying "RPi-2". The RPi-2 doesn't have a GIC at all, so I'd really like to know *how* you end-up in the GICv2 probe function?
I'm not on RPi-2. I am on some Samsung's proprietary hardware which suffers from this problem.
Actually it has "weird GIC", similar to Exynos-4 (every CPU accesses GIC at its own base), thus hardware vGIC is unusable.
I learned about RPi-2 when i was discussing some related things earlier with Andre over private
mail and we suggested that it could be useful there.
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia
Re: [PATCH 3/3] KVM: arm: Enable vGICv2 software emulation
Quoted 10 lines · Pavel Fedin
Hello!
Quoted 3 lines
Hold on a second. In your cover letter, your saying "RPi-2". The RPi-2 doesn't have a GIC at all, so I'd really like to know *how* you end-up in the GICv2 probe function?
I'm not on RPi-2. I am on some Samsung's proprietary hardware which suffers from this problem. Actually it has "weird GIC", similar to Exynos-4 (every CPU accesses GIC at its own base), thus hardware vGIC is unusable.
Well, I'm sorry you have to work with such broken designs, but this is simply not suitable for KVM. The Franken-GIC has caused us a lot of pain in the past, and papering over it only gives people an incentive to push for more broken HW.
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny...
Hi Pavel,
Quoted 3 lines · Pavel Fedin
Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks functional vGIC registers. This series introduces software vGIC emulation for such machines, allowing to fully use virtualization capabilities
I'm really not keen on any of this. The RPi-2 is mostly unsupported in mainline, and not only lacks the vGIC, but doesn't have a GIC at all. This would break ongoing developments (inability to properly support EOImode=1, to preserve the active state for shared devices like timers).
As far as I'm concerned, this hardware is not architecturally compliant and the solution is to use userspace emulation (QEMU provides a GIC model). Taking these patches would keep us stuck in the past.
I'm sure whoever maintains the RPi kernel will be glad to take these patches on top of the pile of stuff they keep out of tree.
Thanks,
M.
Quoted 12 lines
Pavel Fedin (3):
KVM: arm: Add basic infrastructure for software vGIC emulation
KVM: arm: Introduce software emulation of vGICv2 CPU interface
KVM: arm: Enable vGICv2 software emulationinclude/kvm/arm_vgic.h | 4 ++ virt/kvm/arm/vgic-v2-emul.c | 60 +++++++++++++++-- virt/kvm/arm/vgic-v2.c | 29 ++++---- virt/kvm/arm/vgic.c | 159 +++++++++++++++++++++++++++++++++----------- virt/kvm/arm/vgic.h | 3 + 5 files changed, 196 insertions(+), 59 deletions(-)
Signature · 1 line
Jazz is not dead. It just smells funny...
Hi Pavel,
[Please cc the kvm/arm list for such patches according to the MAINTAINERS file in the future]
Quoted 3 lines · Pavel Fedin
Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks functional vGIC registers. This series introduces software vGIC emulation for such machines, allowing to fully use virtualization capabilities
Is this rather esoteric use case really worth the extra code in the kernel? I really feel that pure emulation should happen in userspace unless there's a very good reason for doing it in the kernel, such as a clearly measureable difference in performance, etc.
I would much rather see a version of this where a userspace provided GIC works with the in-kernel arch timers support.
-Christoffer
Hi,
Quoted 5 lines · Christoffer Dall
Hi Pavel,
[Please cc the kvm/arm list for such patches according to the
MAINTAINERSfile in the future]
Quoted 7 lines
Quoted 3 lines · Pavel Fedin
Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks functional vGIC registers. This series introduces software vGIC emulation for such machines, allowing to fully use virtualization capabilities
Is this rather esoteric use case really worth the extra code in the kernel?
I wonder if these patches would pave the way to support running GICv2 guests on GICv3s without compat support? Admittedly not a really compelling use case either, but at least worth discussing, I think.
Also if this will make the hack needed to enable KVM on RPi2 smaller, I'd rather embrace this one than letting any random hacks appear on that RPi kernel tree (patches which I have seen already on some other repo). If I get this correctly, there are some efforts currently to get closer to mainline with the RPi tree.
Pavel, is this "broken" GIC you are talking about going to appear in a publicly available SoC? If yes, you could either state this right now or send it later once you can talk publicly.
Marc, Christoffer:
So is this GICv2 CPU interface emulation totally out of question for us or is it worth at least commenting on the patches?
Cheers,
Andre.
Quoted 9 lines
I really feel that pure emulation should happen in userspace unless there's a very good reason for doing it in the kernel, such as a clearly measureable difference in performance, etc.
I would much rather see a version of this where a userspace provided GIC works with the in-kernel arch timers support.
-Christoffer
Quoted 26 lines · Andre Przywara
Hi,
Quoted 5 lines · Christoffer Dall
Hi Pavel,
[Please cc the kvm/arm list for such patches according to the
MAINTAINERSfile in the future]Quoted 7 lines
Quoted 3 lines · Pavel Fedin
Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks functional vGIC registers. This series introduces software vGIC emulation for such machines, allowing to fully use virtualization capabilities
Is this rather esoteric use case really worth the extra code in the kernel?
I wonder if these patches would pave the way to support running GICv2 guests on GICv3s without compat support? Admittedly not a really compelling use case either, but at least worth discussing, I think.
Also if this will make the hack needed to enable KVM on RPi2 smaller, I'd rather embrace this one than letting any random hacks appear on that RPi kernel tree (patches which I have seen already on some other repo). If I get this correctly, there are some efforts currently to get closer to mainline with the RPi tree.
Quoted 8 lines
Pavel, is this "broken" GIC you are talking about going to appear in a publicly available SoC? If yes, you could either state this right now or send it later once you can talk publicly.
Marc, Christoffer:
So is this GICv2 CPU interface emulation totally out of question for us or is it worth at least commenting on the patches?
Well, I certainly have a lot of seemingly higher-priority things to look at currently.
I'd like some numbers for the performance benefit of putting this in the kernel before I entertain the idea.
-Christoffer
Quoted 13 lines · Andre Przywara
Hi,
Quoted 10 lines · Christoffer Dall
Hi Pavel,
[Please cc the kvm/arm list for such patches according to the
MAINTAINERSfile in the future]Quoted 3 lines · Pavel Fedin
Some hardware (like Raspberry Pi 2) is capable of running KVM, however lacks functional vGIC registers. This series introduces software vGIC emulation for such machines, allowing to fully use virtualization capabilities
Quoted 6 lines
Quoted 2 lines
Is this rather esoteric use case really worth the extra code in the kernel?
I wonder if these patches would pave the way to support running GICv2 guests on GICv3s without compat support? Admittedly not a really compelling use case either, but at least worth discussing, I think.
Let's face it: arm64 has no legacy to support. So if you're on a pure GICv3 system, you run a GICv3 guest (oddly enough, pure GICv3 systems are also pure AArch64 systems - see a pattern?). We've made sure the software was available in a timely manner.
Quoted 5 lines
Also if this will make the hack needed to enable KVM on RPi2 smaller, I'd rather embrace this one than letting any random hacks appear on that RPi kernel tree (patches which I have seen already on some other repo). If I get this correctly, there are some efforts currently to get closer to mainline with the RPi tree.
Whatever the RPi people do in their tree is their problem. I don't care. I'm interested in supporting *compliant hardware*, and not doing a quick hack on the side.
Even if RPi-2 was fully supported in mainline, this code would actively prevent us from supporting proper timer deactivation, for example.
Quoted 7 lines
Pavel, is this "broken" GIC you are talking about going to appear in a publicly available SoC? If yes, you could either state this right now or send it later once you can talk publicly.
Marc, Christoffer:
So is this GICv2 CPU interface emulation totally out of question for us or is it worth at least commenting on the patches?
As long as this code is there to support a platform that doesn't exist in a mainline tree, I'm not interested. We have much bigger fish to fry, and supporting what is effectively a broken platform is not exactly high on the agenda.
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny...
Hello!
Quoted 2 lines
I wonder if these patches would pave the way to support running GICv2 guests on GICv3s without compat support?
Yes, it does. I haven't implemented GICv3 bit for this time, but - yes. And it will be a very small
addition.
Quoted 2 lines
Pavel, is this "broken" GIC you are talking about going to appear in a publicly available SoC?
In kernel documentation it's known as "FrankenGIC".
First of all, it's Exynos 4 (however i don't know whether it implements virtualization extensions). Second, it is present in many consumer electronics products (does this count as "publicly
available"? But you can learn this fact from Samsung's opensource releases). I use one of these boards for my tests because we have lots of them here :)
Third, this code doesn't really depend on hardware GIC, and can be reused on RPi-2 with a little
more hacking.
Fourth, there is at least of one ARM64 machine with broken vGICv3. And you can buy it. I have it
here. And it would also benefit from this code (yes, with GICv3 CPU interface emulation added, which becomes trivial).
Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia