diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 11:42:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 11:42:08 -0400 |
commit | f4b10bc60a310916bab5413f821b99ef845cac17 (patch) | |
tree | 904532e8cd93b88261f21427c4ec4917d4b3e79d /arch/powerpc/kvm/e500.c | |
parent | 53ee7569ce8beb3fd3fc0817116c29298d72353f (diff) | |
parent | c8cfbb555eb3632bf3dcbe1a591c1f4d0c28681c (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.c | 76 |
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 | ||
100 | void 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 | |||
135 | int 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 | |||
99 | struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | 175 | struct 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; |