diff options
author | Liu Yu <yu.liu@freescale.com> | 2011-06-14 19:35:14 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 06:16:39 -0400 |
commit | dd9ebf1f94354b010f2ac7a98bf69168636cb08e (patch) | |
tree | d7a6cbe2b31cd7349913d289b715fa1086ba0a1a /arch/powerpc/kvm/booke_interrupts.S | |
parent | 08b7fa92b9250eab0f493f7721977e781a887b3d (diff) |
KVM: PPC: e500: Add shadow PID support
Dynamically assign host PIDs to guest PIDs, splitting each guest PID into
multiple host (shadow) PIDs based on kernel/user and MSR[IS/DS]. Use
both PID0 and PID1 so that the shadow PIDs for the right mode can be
selected, that correspond both to guest TID = zero and guest TID = guest
PID.
This allows us to significantly reduce the frequency of needing to
invalidate the entire TLB. When the guest mode or PID changes, we just
update the host PID0/PID1. And since the allocation of shadow PIDs is
global, multiple guests can share the TLB without conflict.
Note that KVM does not yet support the guest setting PID1 or PID2 to
a value other than zero. This will need to be fixed for nested KVM
to work. Until then, we enforce the requirement for guest PID1/PID2
to stay zero by failing the emulation if the guest tries to set them
to something else.
Signed-off-by: Liu Yu <yu.liu@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/booke_interrupts.S')
-rw-r--r-- | arch/powerpc/kvm/booke_interrupts.S | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 8cb3dfe29f75..42f2fb1f66e9 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -191,6 +191,12 @@ _GLOBAL(kvmppc_resume_host) | |||
191 | lwz r3, VCPU_HOST_PID(r4) | 191 | lwz r3, VCPU_HOST_PID(r4) |
192 | mtspr SPRN_PID, r3 | 192 | mtspr SPRN_PID, r3 |
193 | 193 | ||
194 | #ifdef CONFIG_FSL_BOOKE | ||
195 | /* we cheat and know that Linux doesn't use PID1 which is always 0 */ | ||
196 | lis r3, 0 | ||
197 | mtspr SPRN_PID1, r3 | ||
198 | #endif | ||
199 | |||
194 | /* Restore host IVPR before re-enabling interrupts. We cheat and know | 200 | /* Restore host IVPR before re-enabling interrupts. We cheat and know |
195 | * that Linux IVPR is always 0xc0000000. */ | 201 | * that Linux IVPR is always 0xc0000000. */ |
196 | lis r3, 0xc000 | 202 | lis r3, 0xc000 |
@@ -365,6 +371,11 @@ lightweight_exit: | |||
365 | lwz r3, VCPU_SHADOW_PID(r4) | 371 | lwz r3, VCPU_SHADOW_PID(r4) |
366 | mtspr SPRN_PID, r3 | 372 | mtspr SPRN_PID, r3 |
367 | 373 | ||
374 | #ifdef CONFIG_FSL_BOOKE | ||
375 | lwz r3, VCPU_SHADOW_PID1(r4) | ||
376 | mtspr SPRN_PID1, r3 | ||
377 | #endif | ||
378 | |||
368 | #ifdef CONFIG_44x | 379 | #ifdef CONFIG_44x |
369 | iccci 0, 0 /* XXX hack */ | 380 | iccci 0, 0 /* XXX hack */ |
370 | #endif | 381 | #endif |