Re: [GIT PULL 1/6] KVM: s390: Handle MVPG partial execution interception

2014-04-30 Thread Heiko Carstens
On Tue, Apr 29, 2014 at 03:36:43PM +0200, Christian Borntraeger wrote:
 +static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
 +{
 + unsigned long hostaddr, srcaddr, dstaddr;
 + psw_t *psw = vcpu-arch.sie_block-gpsw;
 + struct mm_struct *mm = current-mm;
 + int reg1, reg2, rc;
 +
 + kvm_s390_get_regs_rre(vcpu, reg1, reg2);
 + srcaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg2]);
 + dstaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg1]);
 +
 + /* Make sure that the source is paged-in */
 + hostaddr = gmap_fault(srcaddr, vcpu-arch.gmap);
 + if (IS_ERR_VALUE(hostaddr))
 + return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);

FWIW (and nothing that should keep this code from going upstream),
this is not entirely correct, since gmap_fault() may return -ENOMEM.
So a host out-of-memory situation will incorrectly result in a guest
addressing exception, which is most likely not what we want.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT PULL 1/6] KVM: s390: Handle MVPG partial execution interception

2014-04-30 Thread Thomas Huth
On Wed, 30 Apr 2014 10:07:09 +0200
Heiko Carstens heiko.carst...@de.ibm.com wrote:

 On Tue, Apr 29, 2014 at 03:36:43PM +0200, Christian Borntraeger wrote:
  +static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
  +{
  +   unsigned long hostaddr, srcaddr, dstaddr;
  +   psw_t *psw = vcpu-arch.sie_block-gpsw;
  +   struct mm_struct *mm = current-mm;
  +   int reg1, reg2, rc;
  +
  +   kvm_s390_get_regs_rre(vcpu, reg1, reg2);
  +   srcaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg2]);
  +   dstaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg1]);
  +
  +   /* Make sure that the source is paged-in */
  +   hostaddr = gmap_fault(srcaddr, vcpu-arch.gmap);
  +   if (IS_ERR_VALUE(hostaddr))
  +   return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
 
 FWIW (and nothing that should keep this code from going upstream),
 this is not entirely correct, since gmap_fault() may return -ENOMEM.
 So a host out-of-memory situation will incorrectly result in a guest
 addressing exception, which is most likely not what we want.

Ah, ... good point, thanks for the hint! (BTW: That's why I personally
prefer some more comments in the source code - by just looking at
gmap_fault() and __gmap_fault(), this is quite hard to see unless you
step through these functions and called functions line by line).

Anyway, I'll assemble a follow-up patch that addresses this
problem with handle_mvpg_pei().

 Thomas

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT PULL 1/6] KVM: s390: Handle MVPG partial execution interception

2014-04-30 Thread Christian Borntraeger
On 30/04/14 10:07, Heiko Carstens wrote:
 On Tue, Apr 29, 2014 at 03:36:43PM +0200, Christian Borntraeger wrote:
 +static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
 +{
 +unsigned long hostaddr, srcaddr, dstaddr;
 +psw_t *psw = vcpu-arch.sie_block-gpsw;
 +struct mm_struct *mm = current-mm;
 +int reg1, reg2, rc;
 +
 +kvm_s390_get_regs_rre(vcpu, reg1, reg2);
 +srcaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg2]);
 +dstaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg1]);
 +
 +/* Make sure that the source is paged-in */
 +hostaddr = gmap_fault(srcaddr, vcpu-arch.gmap);
 +if (IS_ERR_VALUE(hostaddr))
 +return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
 
 FWIW (and nothing that should keep this code from going upstream),
 this is not entirely correct, since gmap_fault() may return -ENOMEM.
 So a host out-of-memory situation will incorrectly result in a guest
 addressing exception, which is most likely not what we want.
 
Indeed, host out-of-memory situation will cause architectural non-compliance in 
some areas of KVM/s390.
The proper Linux way (returning -ENOMEM  (or EFAULT?) in the KVM_RUN ioctl) 
will cause qemu to print an error and abort(), which is also not ideal.
The s390 way, should probably be to inject an uncorrectable storage error 
machine check.

So the question is what is the right thing to  do for these cases?

Paolo, what is the x86 way of dealing with situations like this (here we fail 
to allocate a pud,pmd,pte or helper structure). Looks like you return
-ENOMEM to qemu. Is that true for all cases?

Christian



--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL 1/6] KVM: s390: Handle MVPG partial execution interception

2014-04-29 Thread Christian Borntraeger
From: Thomas Huth th...@linux.vnet.ibm.com

When the guest executes the MVPG instruction with DAT disabled,
and the source or destination page is not mapped in the host,
the so-called partial execution interception occurs. We need to
handle this event by setting up a mapping for the corresponding
user pages.

Signed-off-by: Thomas Huth th...@linux.vnet.ibm.com
Reviewed-by: Cornelia Huck cornelia.h...@de.ibm.com
Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
---
 arch/s390/kvm/intercept.c | 55 ++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 30e1c5e..54313fe 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -1,7 +1,7 @@
 /*
  * in-kernel handling for sie intercepts
  *
- * Copyright IBM Corp. 2008, 2009
+ * Copyright IBM Corp. 2008, 2014
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -234,6 +234,58 @@ static int handle_instruction_and_prog(struct kvm_vcpu 
*vcpu)
return rc2;
 }
 
+/**
+ * Handle MOVE PAGE partial execution interception.
+ *
+ * This interception can only happen for guests with DAT disabled and
+ * addresses that are currently not mapped in the host. Thus we try to
+ * set up the mappings for the corresponding user pages here (or throw
+ * addressing exceptions in case of illegal guest addresses).
+ */
+static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
+{
+   unsigned long hostaddr, srcaddr, dstaddr;
+   psw_t *psw = vcpu-arch.sie_block-gpsw;
+   struct mm_struct *mm = current-mm;
+   int reg1, reg2, rc;
+
+   kvm_s390_get_regs_rre(vcpu, reg1, reg2);
+   srcaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg2]);
+   dstaddr = kvm_s390_real_to_abs(vcpu, vcpu-run-s.regs.gprs[reg1]);
+
+   /* Make sure that the source is paged-in */
+   hostaddr = gmap_fault(srcaddr, vcpu-arch.gmap);
+   if (IS_ERR_VALUE(hostaddr))
+   return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+   down_read(mm-mmap_sem);
+   rc = get_user_pages(current, mm, hostaddr, 1, 0, 0, NULL, NULL);
+   up_read(mm-mmap_sem);
+   if (rc  0)
+   return rc;
+
+   /* Make sure that the destination is paged-in */
+   hostaddr = gmap_fault(dstaddr, vcpu-arch.gmap);
+   if (IS_ERR_VALUE(hostaddr))
+   return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+   down_read(mm-mmap_sem);
+   rc = get_user_pages(current, mm, hostaddr, 1, 1, 0, NULL, NULL);
+   up_read(mm-mmap_sem);
+   if (rc  0)
+   return rc;
+
+   psw-addr = __rewind_psw(*psw, 4);
+
+   return 0;
+}
+
+static int handle_partial_execution(struct kvm_vcpu *vcpu)
+{
+   if (vcpu-arch.sie_block-ipa == 0xb254)/* MVPG */
+   return handle_mvpg_pei(vcpu);
+
+   return -EOPNOTSUPP;
+}
+
 static const intercept_handler_t intercept_funcs[] = {
[0x00  2] = handle_noop,
[0x04  2] = handle_instruction,
@@ -245,6 +297,7 @@ static const intercept_handler_t intercept_funcs[] = {
[0x1C  2] = kvm_s390_handle_wait,
[0x20  2] = handle_validity,
[0x28  2] = handle_stop,
+   [0x38  2] = handle_partial_execution,
 };
 
 int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
-- 
1.8.4.2

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html