aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/intercept.c
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2013-05-17 08:41:36 -0400
committerGleb Natapov <gleb@redhat.com>2013-05-21 04:55:24 -0400
commit2c70fe4416d5f6d092b20ebf7d7654835e09c109 (patch)
tree077a740810c4ed97629efa5e6fc598823f2af503 /arch/s390/kvm/intercept.c
parent49b99e1e0dedbd6cc93b2d2776b60fb7151ff3d7 (diff)
s390/kvm: Kick guests out of sie if prefix page host pte is touched
The guest prefix pages must be mapped writeable all the time while SIE is running, otherwise the guest might see random behaviour. (pinned at the pte level) Turns out that mlocking is not enough, the page table entry (not the page) might change or become r/o. This patch uses the gmap notifiers to kick guest cpus out of SIE. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/s390/kvm/intercept.c')
-rw-r--r--arch/s390/kvm/intercept.c39
1 files changed, 2 insertions, 37 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index b7d1b2edeeb3..f0b8be0cc08d 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -174,47 +174,12 @@ static int handle_stop(struct kvm_vcpu *vcpu)
174 174
175static int handle_validity(struct kvm_vcpu *vcpu) 175static int handle_validity(struct kvm_vcpu *vcpu)
176{ 176{
177 unsigned long vmaddr;
178 int viwhy = vcpu->arch.sie_block->ipb >> 16; 177 int viwhy = vcpu->arch.sie_block->ipb >> 16;
179 int rc;
180 178
181 vcpu->stat.exit_validity++; 179 vcpu->stat.exit_validity++;
182 trace_kvm_s390_intercept_validity(vcpu, viwhy); 180 trace_kvm_s390_intercept_validity(vcpu, viwhy);
183 if (viwhy == 0x37) { 181 WARN_ONCE(true, "kvm: unhandled validity intercept 0x%x\n", viwhy);
184 vmaddr = gmap_fault(vcpu->arch.sie_block->prefix, 182 return -EOPNOTSUPP;
185 vcpu->arch.gmap);
186 if (IS_ERR_VALUE(vmaddr)) {
187 rc = -EOPNOTSUPP;
188 goto out;
189 }
190 rc = fault_in_pages_writeable((char __user *) vmaddr,
191 PAGE_SIZE);
192 if (rc) {
193 /* user will receive sigsegv, exit to user */
194 rc = -EOPNOTSUPP;
195 goto out;
196 }
197 vmaddr = gmap_fault(vcpu->arch.sie_block->prefix + PAGE_SIZE,
198 vcpu->arch.gmap);
199 if (IS_ERR_VALUE(vmaddr)) {
200 rc = -EOPNOTSUPP;
201 goto out;
202 }
203 rc = fault_in_pages_writeable((char __user *) vmaddr,
204 PAGE_SIZE);
205 if (rc) {
206 /* user will receive sigsegv, exit to user */
207 rc = -EOPNOTSUPP;
208 goto out;
209 }
210 } else
211 rc = -EOPNOTSUPP;
212
213out:
214 if (rc)
215 VCPU_EVENT(vcpu, 2, "unhandled validity intercept code %d",
216 viwhy);
217 return rc;
218} 183}
219 184
220static int handle_instruction(struct kvm_vcpu *vcpu) 185static int handle_instruction(struct kvm_vcpu *vcpu)