File tree Expand file tree Collapse file tree 4 files changed +41
-8
lines changed Expand file tree Collapse file tree 4 files changed +41
-8
lines changed Original file line number Diff line number Diff line change 44
44
45
45
#define KVM_REQ_SLEEP \
46
46
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
47
- #define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
48
- #define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
49
- #define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
50
- #define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
51
- #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
52
- #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6)
53
- #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7)
54
- #define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8)
47
+ #define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
48
+ #define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
49
+ #define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
50
+ #define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
51
+ #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
52
+ #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6)
53
+ #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7)
54
+ #define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8)
55
+ #define KVM_REQ_GUEST_HYP_IRQ_PENDING KVM_ARCH_REQ(9)
55
56
56
57
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
57
58
KVM_DIRTY_LOG_INITIALLY_SET)
Original file line number Diff line number Diff line change @@ -1148,6 +1148,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
1148
1148
* preserved on VMID roll-over if the task was preempted,
1149
1149
* making a thread's VMID inactive. So we need to call
1150
1150
* kvm_arm_vmid_update() in non-premptible context.
1151
+ *
1152
+ * Note that this must happen after the check_vcpu_request()
1153
+ * call to pick the correct s2_mmu structure, as a pending
1154
+ * nested exception (IRQ, for example) can trigger a change
1155
+ * in translation regime.
1151
1156
*/
1152
1157
if (kvm_arm_vmid_update (& vcpu -> arch .hw_mmu -> vmid ) &&
1153
1158
has_vhe ())
Original file line number Diff line number Diff line change @@ -1318,4 +1318,8 @@ void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
1318
1318
}
1319
1319
write_unlock (& vcpu -> kvm -> mmu_lock );
1320
1320
}
1321
+
1322
+ /* Must be last, as may switch context! */
1323
+ if (kvm_check_request (KVM_REQ_GUEST_HYP_IRQ_PENDING , vcpu ))
1324
+ kvm_inject_nested_irq (vcpu );
1321
1325
}
Original file line number Diff line number Diff line change @@ -906,6 +906,29 @@ static inline void vgic_restore_state(struct kvm_vcpu *vcpu)
906
906
/* Flush our emulation state into the GIC hardware before entering the guest. */
907
907
void kvm_vgic_flush_hwstate (struct kvm_vcpu * vcpu )
908
908
{
909
+ /*
910
+ * If in a nested state, we must return early. Two possibilities:
911
+ *
912
+ * - If we have any pending IRQ for the guest and the guest
913
+ * expects IRQs to be handled in its virtual EL2 mode (the
914
+ * virtual IMO bit is set) and it is not already running in
915
+ * virtual EL2 mode, then we have to emulate an IRQ
916
+ * exception to virtual EL2.
917
+ *
918
+ * We do that by placing a request to ourselves which will
919
+ * abort the entry procedure and inject the exception at the
920
+ * beginning of the run loop.
921
+ *
922
+ * - Otherwise, do exactly *NOTHING*. The guest state is
923
+ * already loaded, and we can carry on with running it.
924
+ */
925
+ if (vgic_state_is_nested (vcpu )) {
926
+ if (kvm_vgic_vcpu_pending_irq (vcpu ))
927
+ kvm_make_request (KVM_REQ_GUEST_HYP_IRQ_PENDING , vcpu );
928
+
929
+ return ;
930
+ }
931
+
909
932
/*
910
933
* If there are no virtual interrupts active or pending for this
911
934
* VCPU, then there is no work to do and we can bail out without
You can’t perform that action at this time.
0 commit comments