* [PATCH 0/3] Add support for handling IRQs in userspace
@ 2015-12-01 10:19 Pavel Fedin
2015-12-01 10:19 ` [PATCH 1/3] KVM: Introduce KVM_EXIT_IRQ Pavel Fedin
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Pavel Fedin @ 2015-12-01 10:19 UTC (permalink / raw)
To: kvmarm, kvm; +Cc: Marc Zyngier, Gleb Natapov, Paolo Bonzini
This patch series introduces ability to handle IRQs in userspace. This is
currently necessary for ARM KVM in order to be able to use virtual CP15
timer without in-kernel irqchip. This allows to use KVM on machines with
either broken vGIC or custom interrupt controller, like Raspberry Pi 2.
The API is designed to be as much architecture-agnostic is possible.
Currently it actually supports only a single IRQ, but it can be easily
extended to accomodate more.
Pavel Fedin (3):
KVM: Introduce KVM_EXIT_IRQ
KVM: Documentation: Document KVM_EXIT_IRQ
KVM: arm/arm64: Decouple virtual timer from vGIC
Documentation/virtual/kvm/api.txt | 14 ++++++++++++++
arch/arm/kvm/arm.c | 14 +++++++-------
include/linux/kvm_host.h | 7 +++++++
include/uapi/linux/kvm.h | 3 +++
virt/kvm/arm/arch_timer.c | 23 +++++++++++++----------
5 files changed, 44 insertions(+), 17 deletions(-)
--
2.4.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] KVM: Introduce KVM_EXIT_IRQ
2015-12-01 10:19 [PATCH 0/3] Add support for handling IRQs in userspace Pavel Fedin
@ 2015-12-01 10:19 ` Pavel Fedin
2015-12-01 10:19 ` [PATCH 2/3] KVM: Documentation: Document KVM_EXIT_IRQ Pavel Fedin
2015-12-01 10:19 ` [PATCH 3/3] KVM: arm/arm64: Decouple virtual timer from vGIC Pavel Fedin
2 siblings, 0 replies; 4+ messages in thread
From: Pavel Fedin @ 2015-12-01 10:19 UTC (permalink / raw)
To: kvmarm, kvm; +Cc: Marc Zyngier, Gleb Natapov, Paolo Bonzini
This exit code means that this vCPU wants to inject an interrupt using
userspace-emulated controller.
IRQs are signalled by adding pending interrupt descriptors to vcpu
structure. For simplicity, we currently reserve only one pointer for a
single interrupt, which will be used by ARM virtual timer code. This can
be extended in the future if necessary.
The interface is designed to be as much arch-agnostic as possible.
Therefore, it has IRQ number and level as parameters (encoded in
struct kvm_irq_level).
Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
---
arch/arm/kvm/arm.c | 6 ++++++
include/linux/kvm_host.h | 7 +++++++
include/uapi/linux/kvm.h | 3 +++
3 files changed, 16 insertions(+)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 66f90c1..6392a5b 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -585,6 +585,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
if (signal_pending(current)) {
ret = -EINTR;
run->exit_reason = KVM_EXIT_INTR;
+ } else if (vcpu->irq) {
+ ret = 0;
+ run->exit_reason = KVM_EXIT_IRQ;
+ run->irq.irq = vcpu->irq->irq;
+ run->irq.level = vcpu->irq->level;
+ vcpu->irq = NULL;
}
if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index c923350..93f59c5 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -281,6 +281,13 @@ struct kvm_vcpu {
} spin_loop;
#endif
bool preempted;
+
+ /*
+ * IRQ pending to the userspace on this CPU.
+ * Currently we support only one slot, used only by ARM architecture.
+ */
+ const struct kvm_irq_level *irq;
+
struct kvm_vcpu_arch arch;
};
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 03f3618..a717a9b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -184,6 +184,7 @@ struct kvm_s390_skeys {
#define KVM_EXIT_SYSTEM_EVENT 24
#define KVM_EXIT_S390_STSI 25
#define KVM_EXIT_IOAPIC_EOI 26
+#define KVM_EXIT_IRQ 27
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -338,6 +339,8 @@ struct kvm_run {
struct {
__u8 vector;
} eoi;
+ /* KVM_EXIT_IRQ */
+ struct kvm_irq_level irq;
/* Fix the size of the union. */
char padding[256];
};
--
2.4.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] KVM: Documentation: Document KVM_EXIT_IRQ
2015-12-01 10:19 [PATCH 0/3] Add support for handling IRQs in userspace Pavel Fedin
2015-12-01 10:19 ` [PATCH 1/3] KVM: Introduce KVM_EXIT_IRQ Pavel Fedin
@ 2015-12-01 10:19 ` Pavel Fedin
2015-12-01 10:19 ` [PATCH 3/3] KVM: arm/arm64: Decouple virtual timer from vGIC Pavel Fedin
2 siblings, 0 replies; 4+ messages in thread
From: Pavel Fedin @ 2015-12-01 10:19 UTC (permalink / raw)
To: kvmarm, kvm; +Cc: Marc Zyngier, Gleb Natapov, Paolo Bonzini
Add documentation for the new exit code.
Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
---
Documentation/virtual/kvm/api.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 092ee9f..d8aae4c 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3331,6 +3331,20 @@ the userspace IOAPIC should process the EOI and retrigger the interrupt if
it is still asserted. Vector is the LAPIC interrupt vector for which the
EOI was received.
+ /* KVM_EXIT_IRQ */
+ struct kvm_irq_level irq;
+
+Indicates that an interrupt happens, to be processed by irqchip implemented in
+userspace. irq.irq specifies the raw IRQ number, and irq.status is to be
+interpreted according to interrupt type:
+ For level-triggered interrupts irq.status is set to new level of the line, and
+ the exit happens upon level change.
+ For edge-triggered interrupts irq.status is set to active level of the line
+ (low or high), and the exit happens when the line is pulsed.
+
+CPU-private interrupts (like per-CPU timers) belong to the vCPU where the exit
+happened.
+
/* Fix the size of the union. */
char padding[256];
};
--
2.4.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] KVM: arm/arm64: Decouple virtual timer from vGIC
2015-12-01 10:19 [PATCH 0/3] Add support for handling IRQs in userspace Pavel Fedin
2015-12-01 10:19 ` [PATCH 1/3] KVM: Introduce KVM_EXIT_IRQ Pavel Fedin
2015-12-01 10:19 ` [PATCH 2/3] KVM: Documentation: Document KVM_EXIT_IRQ Pavel Fedin
@ 2015-12-01 10:19 ` Pavel Fedin
2 siblings, 0 replies; 4+ messages in thread
From: Pavel Fedin @ 2015-12-01 10:19 UTC (permalink / raw)
To: kvmarm, kvm; +Cc: Marc Zyngier, Gleb Natapov, Paolo Bonzini
Remove dependency on vgic_initialized() and use the newly introduced
infrastructure to send interrupts via the userspace if vGIC is not being
used.
Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
---
arch/arm/kvm/arm.c | 8 +-------
virt/kvm/arm/arch_timer.c | 23 +++++++++++++----------
2 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 6392a5b..e729068 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -468,13 +468,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
return ret;
}
- /*
- * Enable the arch timers only if we have an in-kernel VGIC
- * and it has been properly initialized, since we cannot handle
- * interrupts from the virtual timer with a userspace gic.
- */
- if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
- kvm_timer_enable(kvm);
+ kvm_timer_enable(kvm);
return 0;
}
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 69bca18..90c91b0 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -128,15 +128,17 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
int ret;
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
- BUG_ON(!vgic_initialized(vcpu->kvm));
-
timer->irq.level = new_level;
trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->map->virt_irq,
timer->irq.level);
- ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
- timer->map,
- timer->irq.level);
- WARN_ON(ret);
+ if (irqchip_in_kernel(vcpu->kvm)) {
+ ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
+ timer->map,
+ timer->irq.level);
+ WARN_ON(ret);
+ } else {
+ vcpu->irq = &timer->irq;
+ }
}
/*
@@ -149,12 +151,12 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
/*
* If userspace modified the timer registers via SET_ONE_REG before
- * the vgic was initialized, we mustn't set the timer->irq.level value
+ * the timer was initialized, we mustn't set the timer->irq.level value
* because the guest would never see the interrupt. Instead wait
* until we call this function from kvm_timer_flush_hwstate.
*/
- if (!vgic_initialized(vcpu->kvm))
- return;
+ if (!vcpu->kvm->arch.timer.enabled)
+ return;
if (kvm_timer_should_fire(vcpu) != timer->irq.level)
kvm_timer_update_irq(vcpu, !timer->irq.level);
@@ -237,7 +239,8 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
* to ensure that hardware interrupts from the timer triggers a guest
* exit.
*/
- if (timer->irq.level || kvm_vgic_map_is_active(vcpu, timer->map))
+ if (timer->irq.level || (irqchip_in_kernel(vcpu->kvm) &&
+ kvm_vgic_map_is_active(vcpu, timer->map)))
phys_active = true;
else
phys_active = false;
--
2.4.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-12-01 10:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-01 10:19 [PATCH 0/3] Add support for handling IRQs in userspace Pavel Fedin
2015-12-01 10:19 ` [PATCH 1/3] KVM: Introduce KVM_EXIT_IRQ Pavel Fedin
2015-12-01 10:19 ` [PATCH 2/3] KVM: Documentation: Document KVM_EXIT_IRQ Pavel Fedin
2015-12-01 10:19 ` [PATCH 3/3] KVM: arm/arm64: Decouple virtual timer from vGIC Pavel Fedin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.