History

KVM: arm64: Don't read a HW interrupt pending state in user context

Since 5bfa685e62e9 ("KVM: arm64: vgic: Read HW interrupt pending state from the HW"), we're able to source the pending bit for an interrupt that is stored either on the physical distributor or on a device. However, this state is only available when the vcpu is loaded, and is not intended to be accessed from userspace. Unfortunately, the GICv2 emulation doesn't provide specific userspace accessors, and we fallback with the ones that are intended for the guest, with fatal consequences. Add a new vgic_uaccess_read_pending() accessor for userspace to use, build on top of the existing vgic_mmio_read_pending().

Marc Zyngier committed 4 years ago

Commit 2cdea191 parent e3fe65e3 files · +21 −5Browse files

Unified · Split

3 files
  1. arch/arm64/kvm/vgic/vgic-mmio-v2.c +2 −2
  2. arch/arm64/kvm/vgic/vgic-mmio.c +16 −3
  3. arch/arm64/kvm/vgic/vgic-mmio.h +3 −0
arch/arm64/kvm/vgic/vgic-mmio-v2.c+2−2
@@ -429,11 +429,11 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = { · 428 unmodified lines
429429 VGIC_ACCESS_32bit),
430430 REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_SET,
431431 vgic_mmio_read_pending, vgic_mmio_write_spending,
432− NULL, vgic_uaccess_write_spending, 1,
432+ vgic_uaccess_read_pending, vgic_uaccess_write_spending, 1,
433433 VGIC_ACCESS_32bit),
434434 REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_CLEAR,
435435 vgic_mmio_read_pending, vgic_mmio_write_cpending,
436− NULL, vgic_uaccess_write_cpending, 1,
436+ vgic_uaccess_read_pending, vgic_uaccess_write_cpending, 1,
437437 VGIC_ACCESS_32bit),
438438 REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET,
439439 vgic_mmio_read_active, vgic_mmio_write_sactive,
arch/arm64/kvm/vgic/vgic-mmio.c+16−3
@@ -226,8 +226,9 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, · 225 unmodified lines
226226 return 0;
227227 }
228228
229−unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
230− gpa_t addr, unsigned int len)
229+static unsigned long __read_pending(struct kvm_vcpu *vcpu,
230+ gpa_t addr, unsigned int len,
231+ bool is_user)
231232 {
232233 u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
233234 u32 value = 0;
@@ -248,7 +249,7 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 14 unmodified lines
248249 IRQCHIP_STATE_PENDING,
249250 &val);
250251 WARN_RATELIMIT(err, "IRQ %d", irq->host_irq);
251− } else if (vgic_irq_is_mapped_level(irq)) {
252+ } else if (!is_user && vgic_irq_is_mapped_level(irq)) {
252253 val = vgic_get_phys_line_level(irq);
253254 } else {
254255 val = irq_is_pending(irq);
@@ -263,6 +264,18 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 8 unmodified lines
263264 return value;
264265 }
265266
267+unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
268+ gpa_t addr, unsigned int len)
269+{
270+ return __read_pending(vcpu, addr, len, false);
271+}
272+
273+unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu,
274+ gpa_t addr, unsigned int len)
275+{
276+ return __read_pending(vcpu, addr, len, true);
277+}
278+
266279 static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq)
267280 {
268281 return (vgic_irq_is_sgi(irq->intid) &&
arch/arm64/kvm/vgic/vgic-mmio.h+3−0
@@ -149,6 +149,9 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, · 148 unmodified lines
149149 unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
150150 gpa_t addr, unsigned int len);
151151
152+unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu,
153+ gpa_t addr, unsigned int len);
154+
152155 void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
153156 gpa_t addr, unsigned int len,
154157 unsigned long val);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t