aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_xics.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/book3s_xics.c')
-rw-r--r--arch/powerpc/kvm/book3s_xics.c64
1 files changed, 51 insertions, 13 deletions
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index 1417e65b6bbd..7fd247cbd0d1 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -30,6 +30,9 @@
30#define XICS_DBG(fmt...) trace_printk(fmt) 30#define XICS_DBG(fmt...) trace_printk(fmt)
31#endif 31#endif
32 32
33#define ENABLE_REALMODE true
34#define DEBUG_REALMODE false
35
33/* 36/*
34 * LOCKING 37 * LOCKING
35 * ======= 38 * =======
@@ -220,8 +223,10 @@ static inline bool icp_try_update(struct kvmppc_icp *icp,
220 * in Accept (H_XIRR) and Up_Cppr (H_XPPR). 223 * in Accept (H_XIRR) and Up_Cppr (H_XPPR).
221 * 224 *
222 * We also do not try to figure out whether the EE state has changed, 225 * We also do not try to figure out whether the EE state has changed,
223 * we unconditionally set it if the new state calls for it for the 226 * we unconditionally set it if the new state calls for it. The reason
224 * same reason. 227 * for that is that we opportunistically remove the pending interrupt
228 * flag when raising CPPR, so we need to set it back here if an
229 * interrupt is still pending.
225 */ 230 */
226 if (new.out_ee) { 231 if (new.out_ee) {
227 kvmppc_book3s_queue_irqprio(icp->vcpu, 232 kvmppc_book3s_queue_irqprio(icp->vcpu,
@@ -483,7 +488,7 @@ static void icp_down_cppr(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
483 icp_check_resend(xics, icp); 488 icp_check_resend(xics, icp);
484} 489}
485 490
486static noinline unsigned long h_xirr(struct kvm_vcpu *vcpu) 491static noinline unsigned long kvmppc_h_xirr(struct kvm_vcpu *vcpu)
487{ 492{
488 union kvmppc_icp_state old_state, new_state; 493 union kvmppc_icp_state old_state, new_state;
489 struct kvmppc_icp *icp = vcpu->arch.icp; 494 struct kvmppc_icp *icp = vcpu->arch.icp;
@@ -517,8 +522,8 @@ static noinline unsigned long h_xirr(struct kvm_vcpu *vcpu)
517 return xirr; 522 return xirr;
518} 523}
519 524
520static noinline int h_ipi(struct kvm_vcpu *vcpu, unsigned long server, 525static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
521 unsigned long mfrr) 526 unsigned long mfrr)
522{ 527{
523 union kvmppc_icp_state old_state, new_state; 528 union kvmppc_icp_state old_state, new_state;
524 struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 529 struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
@@ -586,7 +591,7 @@ static noinline int h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
586 return H_SUCCESS; 591 return H_SUCCESS;
587} 592}
588 593
589static noinline void h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr) 594static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
590{ 595{
591 union kvmppc_icp_state old_state, new_state; 596 union kvmppc_icp_state old_state, new_state;
592 struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 597 struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
@@ -643,7 +648,7 @@ static noinline void h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
643 icp_deliver_irq(xics, icp, reject); 648 icp_deliver_irq(xics, icp, reject);
644} 649}
645 650
646static noinline int h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) 651static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
647{ 652{
648 struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 653 struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
649 struct kvmppc_icp *icp = vcpu->arch.icp; 654 struct kvmppc_icp *icp = vcpu->arch.icp;
@@ -693,29 +698,54 @@ static noinline int h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
693 return H_SUCCESS; 698 return H_SUCCESS;
694} 699}
695 700
701static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
702{
703 struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
704 struct kvmppc_icp *icp = vcpu->arch.icp;
705
706 XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n",
707 hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt);
708
709 if (icp->rm_action & XICS_RM_KICK_VCPU)
710 kvmppc_fast_vcpu_kick(icp->rm_kick_target);
711 if (icp->rm_action & XICS_RM_CHECK_RESEND)
712 icp_check_resend(xics, icp);
713 if (icp->rm_action & XICS_RM_REJECT)
714 icp_deliver_irq(xics, icp, icp->rm_reject);
715
716 icp->rm_action = 0;
717
718 return H_SUCCESS;
719}
720
696int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req) 721int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req)
697{ 722{
723 struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
698 unsigned long res; 724 unsigned long res;
699 int rc = H_SUCCESS; 725 int rc = H_SUCCESS;
700 726
701 /* Check if we have an ICP */ 727 /* Check if we have an ICP */
702 if (!vcpu->arch.icp || !vcpu->kvm->arch.xics) 728 if (!xics || !vcpu->arch.icp)
703 return H_HARDWARE; 729 return H_HARDWARE;
704 730
731 /* Check for real mode returning too hard */
732 if (xics->real_mode)
733 return kvmppc_xics_rm_complete(vcpu, req);
734
705 switch (req) { 735 switch (req) {
706 case H_XIRR: 736 case H_XIRR:
707 res = h_xirr(vcpu); 737 res = kvmppc_h_xirr(vcpu);
708 kvmppc_set_gpr(vcpu, 4, res); 738 kvmppc_set_gpr(vcpu, 4, res);
709 break; 739 break;
710 case H_CPPR: 740 case H_CPPR:
711 h_cppr(vcpu, kvmppc_get_gpr(vcpu, 4)); 741 kvmppc_h_cppr(vcpu, kvmppc_get_gpr(vcpu, 4));
712 break; 742 break;
713 case H_EOI: 743 case H_EOI:
714 rc = h_eoi(vcpu, kvmppc_get_gpr(vcpu, 4)); 744 rc = kvmppc_h_eoi(vcpu, kvmppc_get_gpr(vcpu, 4));
715 break; 745 break;
716 case H_IPI: 746 case H_IPI:
717 rc = h_ipi(vcpu, kvmppc_get_gpr(vcpu, 4), 747 rc = kvmppc_h_ipi(vcpu, kvmppc_get_gpr(vcpu, 4),
718 kvmppc_get_gpr(vcpu, 5)); 748 kvmppc_get_gpr(vcpu, 5));
719 break; 749 break;
720 } 750 }
721 751
@@ -933,6 +963,14 @@ int kvm_xics_create(struct kvm *kvm, u32 type)
933 963
934 xics_debugfs_init(xics); 964 xics_debugfs_init(xics);
935 965
966#ifdef CONFIG_KVM_BOOK3S_64_HV
967 if (cpu_has_feature(CPU_FTR_ARCH_206)) {
968 /* Enable real mode support */
969 xics->real_mode = ENABLE_REALMODE;
970 xics->real_mode_dbg = DEBUG_REALMODE;
971 }
972#endif /* CONFIG_KVM_BOOK3S_64_HV */
973
936 return 0; 974 return 0;
937} 975}
938 976