[PATCH 32/33] KVM: PPC: Handle NV registers in emulated critical sections

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When we emulate instructions during our critical section emulation we may
overwrite non-volatile registers that the looping code would need to load
back in.

Notify the callers of prepare_to_enter() when we emulated code, so that they
can set enable NV restoration on their exit path.

Signed-off-by: Alexander Graf <agraf@xxxxxxx>
---
 arch/powerpc/kvm/book3s_pr.c | 16 +++++++++++++---
 arch/powerpc/kvm/booke.c     |  3 +++
 arch/powerpc/kvm/powerpc.c   |  6 +++++-
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 3b82e86..8cce531 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1174,10 +1174,20 @@ program_interrupt:
 		 * again due to a host external interrupt.
 		 */
 		s = kvmppc_prepare_to_enter(vcpu);
-		if (s <= 0)
+		switch (s) {
+		case -EINTR:
 			r = s;
-		else {
-			/* interrupts now hard-disabled */
+			break;
+		case 0:
+			/* Exit_reason is set, go to host */
+			r = RESUME_HOST;
+			break;
+		case 2:
+			/* Registers modified, reload then enter */
+			r = RESUME_GUEST_NV;
+			/* fall through */
+		case 1:
+			/* Interrupts now hard-disabled, enter guest */
 			kvmppc_fix_ee_before_entry();
 		}
 
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index c0a71ce..66718d4 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1216,6 +1216,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 		if (s <= 0)
 			r = (s << 2) | RESUME_HOST | (r & RESUME_FLAG_NV);
 		else {
+			if (s == 2)
+				r = RESUME_GUEST_NV;
+
 			/* interrupts now hard-disabled */
 			kvmppc_fix_ee_before_entry();
 		}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 0a326e1..6757c47 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -103,12 +103,14 @@ static bool kvmppc_needs_emulation(struct kvm_vcpu *vcpu)
  *
  * returns:
  *
+ * == 2 if we're ready to go into guest state with NV registers restored
  * == 1 if we're ready to go into guest state
  * <= 0 if we need to go back to the host with return value
  */
 int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
 {
 	int r;
+	int enter_level = 1;
 
 	WARN_ON(irqs_disabled());
 	hard_irq_disable();
@@ -163,13 +165,15 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
 			r = kvmppc_emulate_any_instruction(vcpu);
 			if (r == EMULATE_DO_MMIO)
 				return 0;
+			if (r == EMULATE_DONE)
+				enter_level = 2;
 
 			hard_irq_disable();
 			continue;
 		}
 
 		kvm_guest_enter();
-		return 1;
+		return enter_level;
 	}
 
 	/* return to host */
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux