aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/44x.c10
-rw-r--r--arch/powerpc/kvm/booke.c154
-rw-r--r--arch/powerpc/kvm/e500.c75
-rw-r--r--arch/powerpc/kvm/e500_emulate.c5
-rw-r--r--arch/powerpc/kvm/e500_tlb.c8
-rw-r--r--arch/powerpc/kvm/emulate.c13
-rw-r--r--arch/powerpc/kvm/powerpc.c4
7 files changed, 259 insertions, 10 deletions
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 74d0e7421143..da3a1225c0ac 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -107,6 +107,16 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
107 return 0; 107 return 0;
108} 108}
109 109
110void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
111{
112 kvmppc_get_sregs_ivor(vcpu, sregs);
113}
114
115int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
116{
117 return kvmppc_set_sregs_ivor(vcpu, sregs);
118}
119
110struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 120struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
111{ 121{
112 struct kvmppc_vcpu_44x *vcpu_44x; 122 struct kvmppc_vcpu_44x *vcpu_44x;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index ef76acb455c3..8462b3a1c1c7 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -569,6 +569,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
569 kvmppc_set_msr(vcpu, regs->msr); 569 kvmppc_set_msr(vcpu, regs->msr);
570 vcpu->arch.shared->srr0 = regs->srr0; 570 vcpu->arch.shared->srr0 = regs->srr0;
571 vcpu->arch.shared->srr1 = regs->srr1; 571 vcpu->arch.shared->srr1 = regs->srr1;
572 kvmppc_set_pid(vcpu, regs->pid);
572 vcpu->arch.shared->sprg0 = regs->sprg0; 573 vcpu->arch.shared->sprg0 = regs->sprg0;
573 vcpu->arch.shared->sprg1 = regs->sprg1; 574 vcpu->arch.shared->sprg1 = regs->sprg1;
574 vcpu->arch.shared->sprg2 = regs->sprg2; 575 vcpu->arch.shared->sprg2 = regs->sprg2;
@@ -584,16 +585,165 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
584 return 0; 585 return 0;
585} 586}
586 587
588static void get_sregs_base(struct kvm_vcpu *vcpu,
589 struct kvm_sregs *sregs)
590{
591 u64 tb = get_tb();
592
593 sregs->u.e.features |= KVM_SREGS_E_BASE;
594
595 sregs->u.e.csrr0 = vcpu->arch.csrr0;
596 sregs->u.e.csrr1 = vcpu->arch.csrr1;
597 sregs->u.e.mcsr = vcpu->arch.mcsr;
598 sregs->u.e.esr = vcpu->arch.esr;
599 sregs->u.e.dear = vcpu->arch.shared->dar;
600 sregs->u.e.tsr = vcpu->arch.tsr;
601 sregs->u.e.tcr = vcpu->arch.tcr;
602 sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
603 sregs->u.e.tb = tb;
604 sregs->u.e.vrsave = vcpu->arch.vrsave;
605}
606
607static int set_sregs_base(struct kvm_vcpu *vcpu,
608 struct kvm_sregs *sregs)
609{
610 if (!(sregs->u.e.features & KVM_SREGS_E_BASE))
611 return 0;
612
613 vcpu->arch.csrr0 = sregs->u.e.csrr0;
614 vcpu->arch.csrr1 = sregs->u.e.csrr1;
615 vcpu->arch.mcsr = sregs->u.e.mcsr;
616 vcpu->arch.esr = sregs->u.e.esr;
617 vcpu->arch.shared->dar = sregs->u.e.dear;
618 vcpu->arch.vrsave = sregs->u.e.vrsave;
619 vcpu->arch.tcr = sregs->u.e.tcr;
620
621 if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DEC)
622 vcpu->arch.dec = sregs->u.e.dec;
623
624 kvmppc_emulate_dec(vcpu);
625
626 if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_TSR) {
627 /*
628 * FIXME: existing KVM timer handling is incomplete.
629 * TSR cannot be read by the guest, and its value in
630 * vcpu->arch is always zero. For now, just handle
631 * the case where the caller is trying to inject a
632 * decrementer interrupt.
633 */
634
635 if ((sregs->u.e.tsr & TSR_DIS) &&
636 (vcpu->arch.tcr & TCR_DIE))
637 kvmppc_core_queue_dec(vcpu);
638 }
639
640 return 0;
641}
642
643static void get_sregs_arch206(struct kvm_vcpu *vcpu,
644 struct kvm_sregs *sregs)
645{
646 sregs->u.e.features |= KVM_SREGS_E_ARCH206;
647
648 sregs->u.e.pir = 0;
649 sregs->u.e.mcsrr0 = vcpu->arch.mcsrr0;
650 sregs->u.e.mcsrr1 = vcpu->arch.mcsrr1;
651 sregs->u.e.decar = vcpu->arch.decar;
652 sregs->u.e.ivpr = vcpu->arch.ivpr;
653}
654
655static int set_sregs_arch206(struct kvm_vcpu *vcpu,
656 struct kvm_sregs *sregs)
657{
658 if (!(sregs->u.e.features & KVM_SREGS_E_ARCH206))
659 return 0;
660
661 if (sregs->u.e.pir != 0)
662 return -EINVAL;
663
664 vcpu->arch.mcsrr0 = sregs->u.e.mcsrr0;
665 vcpu->arch.mcsrr1 = sregs->u.e.mcsrr1;
666 vcpu->arch.decar = sregs->u.e.decar;
667 vcpu->arch.ivpr = sregs->u.e.ivpr;
668
669 return 0;
670}
671
672void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
673{
674 sregs->u.e.features |= KVM_SREGS_E_IVOR;
675
676 sregs->u.e.ivor_low[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
677 sregs->u.e.ivor_low[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
678 sregs->u.e.ivor_low[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
679 sregs->u.e.ivor_low[3] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
680 sregs->u.e.ivor_low[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
681 sregs->u.e.ivor_low[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
682 sregs->u.e.ivor_low[6] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
683 sregs->u.e.ivor_low[7] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
684 sregs->u.e.ivor_low[8] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
685 sregs->u.e.ivor_low[9] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
686 sregs->u.e.ivor_low[10] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
687 sregs->u.e.ivor_low[11] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
688 sregs->u.e.ivor_low[12] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
689 sregs->u.e.ivor_low[13] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
690 sregs->u.e.ivor_low[14] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
691 sregs->u.e.ivor_low[15] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
692}
693
694int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
695{
696 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
697 return 0;
698
699 vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = sregs->u.e.ivor_low[0];
700 vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = sregs->u.e.ivor_low[1];
701 vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = sregs->u.e.ivor_low[2];
702 vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = sregs->u.e.ivor_low[3];
703 vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = sregs->u.e.ivor_low[4];
704 vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = sregs->u.e.ivor_low[5];
705 vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = sregs->u.e.ivor_low[6];
706 vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = sregs->u.e.ivor_low[7];
707 vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = sregs->u.e.ivor_low[8];
708 vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = sregs->u.e.ivor_low[9];
709 vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = sregs->u.e.ivor_low[10];
710 vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = sregs->u.e.ivor_low[11];
711 vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = sregs->u.e.ivor_low[12];
712 vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = sregs->u.e.ivor_low[13];
713 vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = sregs->u.e.ivor_low[14];
714 vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = sregs->u.e.ivor_low[15];
715
716 return 0;
717}
718
587int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, 719int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
588 struct kvm_sregs *sregs) 720 struct kvm_sregs *sregs)
589{ 721{
590 return -ENOTSUPP; 722 sregs->pvr = vcpu->arch.pvr;
723
724 get_sregs_base(vcpu, sregs);
725 get_sregs_arch206(vcpu, sregs);
726 kvmppc_core_get_sregs(vcpu, sregs);
727 return 0;
591} 728}
592 729
593int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, 730int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
594 struct kvm_sregs *sregs) 731 struct kvm_sregs *sregs)
595{ 732{
596 return -ENOTSUPP; 733 int ret;
734
735 if (vcpu->arch.pvr != sregs->pvr)
736 return -EINVAL;
737
738 ret = set_sregs_base(vcpu, sregs);
739 if (ret < 0)
740 return ret;
741
742 ret = set_sregs_arch206(vcpu, sregs);
743 if (ret < 0)
744 return ret;
745
746 return kvmppc_core_set_sregs(vcpu, sregs);
597} 747}
598 748
599int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 749int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 0c1af1267843..318dbc61ba44 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -97,6 +97,81 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
97 return 0; 97 return 0;
98} 98}
99 99
100void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
101{
102 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
103
104 sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_SPE |
105 KVM_SREGS_E_PM;
106 sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
107
108 sregs->u.e.impl.fsl.features = 0;
109 sregs->u.e.impl.fsl.svr = vcpu_e500->svr;
110 sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
111 sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
112
113 sregs->u.e.mas0 = vcpu_e500->mas0;
114 sregs->u.e.mas1 = vcpu_e500->mas1;
115 sregs->u.e.mas2 = vcpu_e500->mas2;
116 sregs->u.e.mas7_3 = ((u64)vcpu_e500->mas7 << 32) | vcpu_e500->mas3;
117 sregs->u.e.mas4 = vcpu_e500->mas4;
118 sregs->u.e.mas6 = vcpu_e500->mas6;
119
120 sregs->u.e.mmucfg = mfspr(SPRN_MMUCFG);
121 sregs->u.e.tlbcfg[0] = vcpu_e500->tlb0cfg;
122 sregs->u.e.tlbcfg[1] = vcpu_e500->tlb1cfg;
123 sregs->u.e.tlbcfg[2] = 0;
124 sregs->u.e.tlbcfg[3] = 0;
125
126 sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
127 sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
128 sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
129 sregs->u.e.ivor_high[3] =
130 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
131
132 kvmppc_get_sregs_ivor(vcpu, sregs);
133}
134
135int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
136{
137 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
138
139 if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
140 vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
141 vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0;
142 vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
143 }
144
145 if (sregs->u.e.features & KVM_SREGS_E_ARCH206_MMU) {
146 vcpu_e500->mas0 = sregs->u.e.mas0;
147 vcpu_e500->mas1 = sregs->u.e.mas1;
148 vcpu_e500->mas2 = sregs->u.e.mas2;
149 vcpu_e500->mas7 = sregs->u.e.mas7_3 >> 32;
150 vcpu_e500->mas3 = (u32)sregs->u.e.mas7_3;
151 vcpu_e500->mas4 = sregs->u.e.mas4;
152 vcpu_e500->mas6 = sregs->u.e.mas6;
153 }
154
155 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
156 return 0;
157
158 if (sregs->u.e.features & KVM_SREGS_E_SPE) {
159 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] =
160 sregs->u.e.ivor_high[0];
161 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] =
162 sregs->u.e.ivor_high[1];
163 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] =
164 sregs->u.e.ivor_high[2];
165 }
166
167 if (sregs->u.e.features & KVM_SREGS_E_PM) {
168 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
169 sregs->u.e.ivor_high[3];
170 }
171
172 return kvmppc_set_sregs_ivor(vcpu, sregs);
173}
174
100struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 175struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
101{ 176{
102 struct kvmppc_vcpu_e500 *vcpu_e500; 177 struct kvmppc_vcpu_e500 *vcpu_e500;
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e2fb47f035a5..69cd665a0caf 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: Yu Liu, <yu.liu@freescale.com> 4 * Author: Yu Liu, <yu.liu@freescale.com>
5 * 5 *
@@ -78,8 +78,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
78 78
79 switch (sprn) { 79 switch (sprn) {
80 case SPRN_PID: 80 case SPRN_PID:
81 vcpu_e500->pid[0] = vcpu->arch.shadow_pid = 81 kvmppc_set_pid(vcpu, spr_val);
82 vcpu->arch.pid = spr_val;
83 break; 82 break;
84 case SPRN_PID1: 83 case SPRN_PID1:
85 vcpu_e500->pid[1] = spr_val; break; 84 vcpu_e500->pid[1] = spr_val; break;
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 56ac4523857d..b18fe353397d 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -675,6 +675,14 @@ int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
675 return -1; 675 return -1;
676} 676}
677 677
678void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
679{
680 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
681
682 vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
683 vcpu->arch.pid = pid;
684}
685
678void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500) 686void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
679{ 687{
680 struct tlbe *tlbe; 688 struct tlbe *tlbe;
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 8f7a3aa03c26..141dce3c6810 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -114,6 +114,12 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
114 } 114 }
115} 115}
116 116
117u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
118{
119 u64 jd = tb - vcpu->arch.dec_jiffies;
120 return vcpu->arch.dec - jd;
121}
122
117/* XXX to do: 123/* XXX to do:
118 * lhax 124 * lhax
119 * lhaux 125 * lhaux
@@ -279,11 +285,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
279 285
280 case SPRN_DEC: 286 case SPRN_DEC:
281 { 287 {
282 u64 jd = get_tb() - vcpu->arch.dec_jiffies; 288 kvmppc_set_gpr(vcpu, rt,
283 kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd); 289 kvmppc_get_dec(vcpu, get_tb()));
284 pr_debug("mfDEC: %x - %llx = %lx\n",
285 vcpu->arch.dec, jd,
286 kvmppc_get_gpr(vcpu, rt));
287 break; 290 break;
288 } 291 }
289 default: 292 default:
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 9e6aa8bfd160..616dd516ca1f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -175,7 +175,11 @@ int kvm_dev_ioctl_check_extension(long ext)
175 int r; 175 int r;
176 176
177 switch (ext) { 177 switch (ext) {
178#ifdef CONFIG_BOOKE
179 case KVM_CAP_PPC_BOOKE_SREGS:
180#else
178 case KVM_CAP_PPC_SEGSTATE: 181 case KVM_CAP_PPC_SEGSTATE:
182#endif
179 case KVM_CAP_PPC_PAIRED_SINGLES: 183 case KVM_CAP_PPC_PAIRED_SINGLES:
180 case KVM_CAP_PPC_UNSET_IRQ: 184 case KVM_CAP_PPC_UNSET_IRQ:
181 case KVM_CAP_PPC_IRQ_LEVEL: 185 case KVM_CAP_PPC_IRQ_LEVEL: