aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/e500.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 11:42:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 11:42:08 -0400
commitf4b10bc60a310916bab5413f821b99ef845cac17 (patch)
tree904532e8cd93b88261f21427c4ec4917d4b3e79d /arch/powerpc/kvm/e500.c
parent53ee7569ce8beb3fd3fc0817116c29298d72353f (diff)
parentc8cfbb555eb3632bf3dcbe1a591c1f4d0c28681c (diff)
Merge branch 'kvm-updates/2.6.40' of git://git.kernel.org/pub/scm/virt/kvm/kvm
* 'kvm-updates/2.6.40' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (131 commits) KVM: MMU: Use ptep_user for cmpxchg_gpte() KVM: Fix kvm mmu_notifier initialization order KVM: Add documentation for KVM_CAP_NR_VCPUS KVM: make guest mode entry to be rcu quiescent state KVM: x86 emulator: Make jmp far emulation into a separate function KVM: x86 emulator: Rename emulate_grpX() to em_grpX() KVM: x86 emulator: Remove unused arg from emulate_pop() KVM: x86 emulator: Remove unused arg from writeback() KVM: x86 emulator: Remove unused arg from read_descriptor() KVM: x86 emulator: Remove unused arg from seg_override() KVM: Validate userspace_addr of memslot when registered KVM: MMU: Clean up gpte reading with copy_from_user() KVM: PPC: booke: add sregs support KVM: PPC: booke: save/restore VRSAVE (a.k.a. USPRG0) KVM: PPC: use ticks, not usecs, for exit timing KVM: PPC: fix exit accounting for SPRs, tlbwe, tlbsx KVM: PPC: e500: emulate SVR KVM: VMX: Cache vmcs segment fields KVM: x86 emulator: consolidate segment accessors KVM: VMX: Avoid reading %rip unnecessarily when handling exceptions ...
Diffstat (limited to 'arch/powerpc/kvm/e500.c')
-rw-r--r--arch/powerpc/kvm/e500.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index e3768ee9b595..318dbc61ba44 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -63,6 +63,7 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
63 63
64 /* Registers init */ 64 /* Registers init */
65 vcpu->arch.pvr = mfspr(SPRN_PVR); 65 vcpu->arch.pvr = mfspr(SPRN_PVR);
66 vcpu_e500->svr = mfspr(SPRN_SVR);
66 67
67 /* Since booke kvm only support one core, update all vcpus' PIR to 0 */ 68 /* Since booke kvm only support one core, update all vcpus' PIR to 0 */
68 vcpu->vcpu_id = 0; 69 vcpu->vcpu_id = 0;
@@ -96,6 +97,81 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
96 return 0; 97 return 0;
97} 98}
98 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
99struct 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)
100{ 176{
101 struct kvmppc_vcpu_e500 *vcpu_e500; 177 struct kvmppc_vcpu_e500 *vcpu_e500;