diff options
author | Scott Wood <scottwood@freescale.com> | 2011-12-20 10:34:43 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-04-08 05:51:19 -0400 |
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, | |||
99 | return emulated; | 99 | return emulated; |
100 | } | 100 | } |
101 | 101 | ||
102 | /* | ||
103 | * NOTE: some of these registers are not emulated on BOOKE_HV (GS-mode). | ||
104 | * Their backing store is in real registers, and these functions | ||
105 | * will return the wrong result if called for them in another context | ||
106 | * (such as debugging). | ||
107 | */ | ||
102 | int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | 108 | int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) |
103 | { | 109 | { |
104 | int emulated = EMULATE_DONE; | 110 | int emulated = EMULATE_DONE; |
@@ -122,9 +128,11 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
122 | kvmppc_set_tcr(vcpu, spr_val); | 128 | kvmppc_set_tcr(vcpu, spr_val); |
123 | break; | 129 | break; |
124 | 130 | ||
125 | /* Note: SPRG4-7 are user-readable. These values are | 131 | /* |
126 | * loaded into the real SPRGs when resuming the | 132 | * Note: SPRG4-7 are user-readable. |
127 | * guest. */ | 133 | * These values are loaded into the real SPRGs when resuming the |
134 | * guest (PR-mode only). | ||
135 | */ | ||
128 | case SPRN_SPRG4: | 136 | case SPRN_SPRG4: |
129 | vcpu->arch.shared->sprg4 = spr_val; break; | 137 | vcpu->arch.shared->sprg4 = spr_val; break; |
130 | case SPRN_SPRG5: | 138 | case SPRN_SPRG5: |
@@ -136,6 +144,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
136 | 144 | ||
137 | case SPRN_IVPR: | 145 | case SPRN_IVPR: |
138 | vcpu->arch.ivpr = spr_val; | 146 | vcpu->arch.ivpr = spr_val; |
147 | #ifdef CONFIG_KVM_BOOKE_HV | ||
148 | mtspr(SPRN_GIVPR, spr_val); | ||
149 | #endif | ||
139 | break; | 150 | break; |
140 | case SPRN_IVOR0: | 151 | case SPRN_IVOR0: |
141 | vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val; | 152 | 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) | |||
145 | break; | 156 | break; |
146 | case SPRN_IVOR2: | 157 | case SPRN_IVOR2: |
147 | vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val; | 158 | vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val; |
159 | #ifdef CONFIG_KVM_BOOKE_HV | ||
160 | mtspr(SPRN_GIVOR2, spr_val); | ||
161 | #endif | ||
148 | break; | 162 | break; |
149 | case SPRN_IVOR3: | 163 | case SPRN_IVOR3: |
150 | vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val; | 164 | 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) | |||
163 | break; | 177 | break; |
164 | case SPRN_IVOR8: | 178 | case SPRN_IVOR8: |
165 | vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val; | 179 | vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val; |
180 | #ifdef CONFIG_KVM_BOOKE_HV | ||
181 | mtspr(SPRN_GIVOR8, spr_val); | ||
182 | #endif | ||
166 | break; | 183 | break; |
167 | case SPRN_IVOR9: | 184 | case SPRN_IVOR9: |
168 | vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val; | 185 | vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val; |