qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Pierre Morel <pmorel@linux.ibm.com>
To: qemu-s390x@nongnu.org
Cc: thuth@redhat.com, frankja@linux.ibm.com, david@redhat.com,
	cohuck@redhat.com, qemu-devel@nongnu.org, borntraeger@de.ibm.com,
	mihajlov@linux.ibm.com
Subject: [PATCH v1 1/1] s390x: protvirt: SCLP interpretation
Date: Thu, 28 Nov 2019 11:13:04 +0100	[thread overview]
Message-ID: <1574935984-16910-2-git-send-email-pmorel@linux.ibm.com> (raw)
In-Reply-To: <1574935984-16910-1-git-send-email-pmorel@linux.ibm.com>

The SCLP protection handle some of the exceptions due to
mis-constructions of the SCLP Control Block (SCCB) by the guest and
provides notifications to the host when something gets wrong.
We currently do not handle these exceptions, letting all the work to the
firmware therefor, we only need to inject an external interrupt to the
guest.

When the SCCB is correct, the S390x virtualisation protection copies
the SCLP Control Block (SCCB) from the guest inside the kernel to avoid
opening a direct access to the guest memory.
When accessing the kernel memory with standard s390_cpu_virt_mem_*
functions the host opens access to the SCCB shadow at address 0.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
 hw/s390x/sclp.c         | 18 +++++++++++++
 include/hw/s390x/sclp.h |  2 ++
 target/s390x/kvm.c      | 56 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index f57ce7b739..02e4e0146f 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -193,6 +193,24 @@ static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
     }
 }
 
+int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
+                                uint32_t code)
+{
+    SCLPDevice *sclp = get_sclp_device();
+    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
+    SCCB work_sccb;
+    hwaddr sccb_len = sizeof(SCCB);
+
+    /* Protected guest SCCB is always seen at address 0 */
+    s390_cpu_virt_mem_read(env_archcpu(env), 0, 0, &work_sccb, sccb_len);
+    sclp_c->execute(sclp, &work_sccb, code);
+    s390_cpu_virt_mem_write(env_archcpu(env), 0, 0, &work_sccb,
+                            be16_to_cpu(work_sccb.h.length));
+
+    sclp_c->service_interrupt(sclp, (uint64_t)&work_sccb);
+    return 0;
+}
+
 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
 {
     SCLPDevice *sclp = get_sclp_device();
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index c54413b78c..c0a3faa37d 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -217,5 +217,7 @@ void s390_sclp_init(void);
 void sclp_service_interrupt(uint32_t sccb);
 void raise_irq_cpu_hotplug(void);
 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
+int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
+                                uint32_t code);
 
 #endif
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 0c9d14b4b1..559f470f51 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1170,7 +1170,14 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
     sccb = env->regs[ipbh0 & 0xf];
     code = env->regs[(ipbh0 & 0xf0) >> 4];
 
-    r = sclp_service_call(env, sccb, code);
+    switch (run->s390_sieic.icptcode) {
+    case ICPT_PV_INSTR:
+        r = sclp_service_call_protected(env, sccb, code);
+        break;
+    default:
+        r = sclp_service_call(env, sccb, code);
+        break;
+    }
     if (r < 0) {
         kvm_s390_program_interrupt(cpu, -r);
     } else {
@@ -1575,6 +1582,47 @@ static int kvm_s390_handle_sigp(S390CPU *cpu, uint8_t ipa1, uint32_t ipb)
     return 0;
 }
 
+static int handle_secure_notification(S390CPU *cpu, struct kvm_run *run)
+{
+    unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
+    uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
+
+    switch (ipa0) {
+    case IPA0_SIGP: /* We get the notification that the guest stop */
+        kvm_s390_handle_sigp(cpu, ipa1, run->s390_sieic.ipb);
+        break;
+    case IPA0_B2: /* We accept but do nothing for B2 notifications */
+        break;
+    default: /* We do not expect other instruction's notification */
+        kvm_s390_program_interrupt(cpu, PGM_OPERATION);
+        break;
+    }
+    return 0;
+}
+
+static int handle_secure_instruction(S390CPU *cpu, struct kvm_run *run)
+{
+    unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
+    uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
+    int r = -1;
+
+    switch (ipa0) {
+    case IPA0_B2:
+        r = handle_b2(cpu, run, ipa1);
+        break;
+    case IPA0_DIAG:
+        r = handle_diag(cpu, run, run->s390_sieic.ipb);
+        break;
+    }
+
+    if (r < 0) {
+        r = 0;
+        kvm_s390_program_interrupt(cpu, PGM_OPERATION);
+    }
+
+    return r;
+}
+
 static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
 {
     unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
@@ -1665,6 +1713,12 @@ static int handle_intercept(S390CPU *cpu)
     DPRINTF("intercept: 0x%x (at 0x%lx)\n", icpt_code,
             (long)cs->kvm_run->psw_addr);
     switch (icpt_code) {
+         case ICPT_PV_INSTR_NOT:
+            r = handle_secure_notification(cpu, run);
+            break;
+        case ICPT_PV_INSTR:
+            r = handle_secure_instruction(cpu, run);
+            break;
         case ICPT_INSTRUCTION:
             r = handle_instruction(cpu, run);
             break;
-- 
2.17.0



  reply	other threads:[~2019-11-28 10:17 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-28 10:13 [PATCH v1 0/1] s390x: protvirt: SCLP interpretation Pierre Morel
2019-11-28 10:13 ` Pierre Morel [this message]
2019-11-28 12:10   ` [PATCH v1 1/1] " Thomas Huth
2019-11-28 13:05     ` Pierre Morel
2019-11-28 12:28 ` [PATCH v1 0/1] " Janosch Frank
2019-11-28 13:15   ` Pierre Morel
2019-11-28 23:09 ` no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1574935984-16910-2-git-send-email-pmorel@linux.ibm.com \
    --to=pmorel@linux.ibm.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=frankja@linux.ibm.com \
    --cc=mihajlov@linux.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).