@@ -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) ||
@@ -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;
};
@@ -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];
};
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(+)