aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-08-10 06:28:50 -0400
committerAlexander Graf <agraf@suse.de>2012-10-05 17:38:42 -0400
commit03d25c5bd5c3125055bd36f4813ddb817def19dd (patch)
treeed1135f8862466b9fc9373049f30ce087fb668a8
parent2d8185d4ee22f425001d28d1817fc8d478e6fa02 (diff)
KVM: PPC: Use same kvmppc_prepare_to_enter code for booke and book3s_pr
We need to do the same things when preparing to enter a guest for booke and book3s_pr cores. Fold the generic code into a generic function that both call. Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h3
-rw-r--r--arch/powerpc/kvm/book3s_pr.c22
-rw-r--r--arch/powerpc/kvm/booke.c58
-rw-r--r--arch/powerpc/kvm/powerpc.c57
4 files changed, 67 insertions, 73 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 88de3146838..59b7c87e47f 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -112,6 +112,7 @@ extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn,
112 ulong val); 112 ulong val);
113extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, 113extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn,
114 ulong *val); 114 ulong *val);
115extern void kvmppc_core_check_requests(struct kvm_vcpu *vcpu);
115 116
116extern int kvmppc_booke_init(void); 117extern int kvmppc_booke_init(void);
117extern void kvmppc_booke_exit(void); 118extern void kvmppc_booke_exit(void);
@@ -150,6 +151,8 @@ extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm,
150extern int kvmppc_bookehv_init(void); 151extern int kvmppc_bookehv_init(void);
151extern void kvmppc_bookehv_exit(void); 152extern void kvmppc_bookehv_exit(void);
152 153
154extern int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu);
155
153/* 156/*
154 * Cuts out inst bits with ordering according to spec. 157 * Cuts out inst bits with ordering according to spec.
155 * That means the leftmost bit is zero. All given bits are included. 158 * That means the leftmost bit is zero. All given bits are included.
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 7f0fe6f9e29..cae2defd146 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -88,6 +88,10 @@ void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
88 kvmppc_giveup_ext(vcpu, MSR_VSX); 88 kvmppc_giveup_ext(vcpu, MSR_VSX);
89} 89}
90 90
91void kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
92{
93}
94
91static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu) 95static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
92{ 96{
93 ulong smsr = vcpu->arch.shared->msr; 97 ulong smsr = vcpu->arch.shared->msr;
@@ -815,19 +819,9 @@ program_interrupt:
815 * again due to a host external interrupt. 819 * again due to a host external interrupt.
816 */ 820 */
817 __hard_irq_disable(); 821 __hard_irq_disable();
818 if (signal_pending(current)) { 822 if (kvmppc_prepare_to_enter(vcpu)) {
819 __hard_irq_enable();
820#ifdef EXIT_DEBUG
821 printk(KERN_EMERG "KVM: Going back to host\n");
822#endif
823 vcpu->stat.signal_exits++;
824 run->exit_reason = KVM_EXIT_INTR; 823 run->exit_reason = KVM_EXIT_INTR;
825 r = -EINTR; 824 r = -EINTR;
826 } else {
827 /* In case an interrupt came in that was triggered
828 * from userspace (like DEC), we need to check what
829 * to inject now! */
830 kvmppc_core_prepare_to_enter(vcpu);
831 } 825 }
832 } 826 }
833 827
@@ -1029,8 +1023,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1029 goto out; 1023 goto out;
1030 } 1024 }
1031 1025
1032 kvmppc_core_prepare_to_enter(vcpu);
1033
1034 /* 1026 /*
1035 * Interrupts could be timers for the guest which we have to inject 1027 * Interrupts could be timers for the guest which we have to inject
1036 * again, so let's postpone them until we're in the guest and if we 1028 * again, so let's postpone them until we're in the guest and if we
@@ -1038,9 +1030,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1038 * a host external interrupt. 1030 * a host external interrupt.
1039 */ 1031 */
1040 __hard_irq_disable(); 1032 __hard_irq_disable();
1041 1033 if (kvmppc_prepare_to_enter(vcpu)) {
1042 /* No need to go into the guest when all we do is going out */
1043 if (signal_pending(current)) {
1044 __hard_irq_enable(); 1034 __hard_irq_enable();
1045 kvm_run->exit_reason = KVM_EXIT_INTR; 1035 kvm_run->exit_reason = KVM_EXIT_INTR;
1046 ret = -EINTR; 1036 ret = -EINTR;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 683cbd686d0..4652e0bfa78 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -455,10 +455,8 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
455 return r; 455 return r;
456} 456}
457 457
458static void kvmppc_check_requests(struct kvm_vcpu *vcpu) 458void kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
459{ 459{
460 trace_kvm_check_requests(vcpu);
461
462 if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu)) 460 if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu))
463 update_timer_ints(vcpu); 461 update_timer_ints(vcpu);
464#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC) 462#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC)
@@ -467,60 +465,6 @@ static void kvmppc_check_requests(struct kvm_vcpu *vcpu)
467#endif 465#endif
468} 466}
469 467
470/*
471 * Common checks before entering the guest world. Call with interrupts
472 * disabled.
473 *
474 * returns !0 if a signal is pending and check_signal is true
475 */
476static int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
477{
478 int r = 0;
479
480 WARN_ON_ONCE(!irqs_disabled());
481 while (true) {
482 if (need_resched()) {
483 local_irq_enable();
484 cond_resched();
485 local_irq_disable();
486 continue;
487 }
488
489 if (signal_pending(current)) {
490 r = 1;
491 break;
492 }
493
494 smp_mb();
495 if (vcpu->requests) {
496 /* Make sure we process requests preemptable */
497 local_irq_enable();
498 kvmppc_check_requests(vcpu);
499 local_irq_disable();
500 continue;
501 }
502
503 if (kvmppc_core_prepare_to_enter(vcpu)) {
504 /* interrupts got enabled in between, so we
505 are back at square 1 */
506 continue;
507 }
508
509 if (vcpu->mode == EXITING_GUEST_MODE) {
510 r = 1;
511 break;
512 }
513
514 /* Going into guest context! Yay! */
515 vcpu->mode = IN_GUEST_MODE;
516 smp_wmb();
517
518 break;
519 }
520
521 return r;
522}
523
524int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) 468int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
525{ 469{
526 int ret; 470 int ret;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 45fe433316e..153a26abc91 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -47,6 +47,63 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
47 return 1; 47 return 1;
48} 48}
49 49
50#ifndef CONFIG_KVM_BOOK3S_64_HV
51/*
52 * Common checks before entering the guest world. Call with interrupts
53 * disabled.
54 *
55 * returns !0 if a signal is pending and check_signal is true
56 */
57int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
58{
59 int r = 0;
60
61 WARN_ON_ONCE(!irqs_disabled());
62 while (true) {
63 if (need_resched()) {
64 local_irq_enable();
65 cond_resched();
66 local_irq_disable();
67 continue;
68 }
69
70 if (signal_pending(current)) {
71 r = 1;
72 break;
73 }
74
75 smp_mb();
76 if (vcpu->requests) {
77 /* Make sure we process requests preemptable */
78 local_irq_enable();
79 trace_kvm_check_requests(vcpu);
80 kvmppc_core_check_requests(vcpu);
81 local_irq_disable();
82 continue;
83 }
84
85 if (kvmppc_core_prepare_to_enter(vcpu)) {
86 /* interrupts got enabled in between, so we
87 are back at square 1 */
88 continue;
89 }
90
91 if (vcpu->mode == EXITING_GUEST_MODE) {
92 r = 1;
93 break;
94 }
95
96 /* Going into guest context! Yay! */
97 vcpu->mode = IN_GUEST_MODE;
98 smp_wmb();
99
100 break;
101 }
102
103 return r;
104}
105#endif /* CONFIG_KVM_BOOK3S_64_HV */
106
50int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) 107int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
51{ 108{
52 int nr = kvmppc_get_gpr(vcpu, 11); 109 int nr = kvmppc_get_gpr(vcpu, 11);