diff options
| author | Scott Wood <scottwood@freescale.com> | 2011-12-20 15:34:43 +0000 | 
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2012-04-08 12:51:19 +0300 | 
| commit | d30f6e480055e5be12e7a03fd11ea912a451daa5 (patch) | |
| tree | e6c367e6f1da4da67b3a395a1a735a09e52067c0 /arch/powerpc/kvm/booke_emulate.c | |
| parent | cfac57847a67c4903f34a77e971521531bbc7c77 (diff) | |
KVM: PPC: booke: category E.HV (GS-mode) support
Chips such as e500mc that implement category E.HV in Power ISA 2.06
provide hardware virtualization features, including a new MSR mode for
guest state.  The guest OS can perform many operations without trapping
into the hypervisor, including transitions to and from guest userspace.
Since we can use SRR1[GS] to reliably tell whether an exception came from
guest state, instead of messing around with IVPR, we use DO_KVM similarly
to book3s.
Current issues include:
 - Machine checks from guest state are not routed to the host handler.
 - The guest can cause a host oops by executing an emulated instruction
   in a page that lacks read permission.  Existing e500/4xx support has
   the same problem.
Includes work by Ashish Kalra <Ashish.Kalra@freescale.com>,
Varun Sethi <Varun.Sethi@freescale.com>, and
Liu Yu <yu.liu@freescale.com>.
Signed-off-by: Scott Wood <scottwood@freescale.com>
[agraf: remove pt_regs usage]
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/booke_emulate.c')
| -rw-r--r-- | arch/powerpc/kvm/booke_emulate.c | 23 | 
1 files changed, 20 insertions, 3 deletions
| diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index 3e652da36534..904412bbea40 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c @@ -99,6 +99,12 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,  	return emulated;  } +/* + * NOTE: some of these registers are not emulated on BOOKE_HV (GS-mode). + * Their backing store is in real registers, and these functions + * will return the wrong result if called for them in another context + * (such as debugging). + */  int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)  {  	int emulated = EMULATE_DONE; @@ -122,9 +128,11 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)  		kvmppc_set_tcr(vcpu, spr_val);  		break; -	/* Note: SPRG4-7 are user-readable. These values are -	 * loaded into the real SPRGs when resuming the -	 * guest. */ +	/* +	 * Note: SPRG4-7 are user-readable. +	 * These values are loaded into the real SPRGs when resuming the +	 * guest (PR-mode only). +	 */  	case SPRN_SPRG4:  		vcpu->arch.shared->sprg4 = spr_val; break;  	case SPRN_SPRG5: @@ -136,6 +144,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)  	case SPRN_IVPR:  		vcpu->arch.ivpr = spr_val; +#ifdef CONFIG_KVM_BOOKE_HV +		mtspr(SPRN_GIVPR, spr_val); +#endif  		break;  	case SPRN_IVOR0:  		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val; @@ -145,6 +156,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)  		break;  	case SPRN_IVOR2:  		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val; +#ifdef CONFIG_KVM_BOOKE_HV +		mtspr(SPRN_GIVOR2, spr_val); +#endif  		break;  	case SPRN_IVOR3:  		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val; @@ -163,6 +177,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)  		break;  	case SPRN_IVOR8:  		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val; +#ifdef CONFIG_KVM_BOOKE_HV +		mtspr(SPRN_GIVOR8, spr_val); +#endif  		break;  	case SPRN_IVOR9:  		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val; | 
