77c23f
From ebcd74c2267d69fe09ca03cb8bfed7bef5ea3a85 Mon Sep 17 00:00:00 2001
77c23f
From: Thomas Huth <thuth@redhat.com>
77c23f
Date: Fri, 29 May 2020 05:54:08 -0400
77c23f
Subject: [PATCH 26/42] s390x: Add SIDA memory ops
77c23f
77c23f
RH-Author: Thomas Huth <thuth@redhat.com>
77c23f
Message-id: <20200529055420.16855-27-thuth@redhat.com>
77c23f
Patchwork-id: 97033
77c23f
O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 26/38] s390x: Add SIDA memory ops
77c23f
Bugzilla: 1828317
77c23f
RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
77c23f
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
77c23f
RH-Acked-by: David Hildenbrand <david@redhat.com>
77c23f
77c23f
From: Janosch Frank <frankja@linux.ibm.com>
77c23f
77c23f
Protected guests save the instruction control blocks in the SIDA
77c23f
instead of QEMU/KVM directly accessing the guest's memory.
77c23f
77c23f
Let's introduce new functions to access the SIDA.
77c23f
77c23f
The memops for doing so are available with KVM_CAP_S390_PROTECTED, so
77c23f
let's check for that.
77c23f
77c23f
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
77c23f
Reviewed-by: David Hildenbrand <david@redhat.com>
77c23f
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
77c23f
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
77c23f
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
77c23f
Message-Id: <20200319131921.2367-8-frankja@linux.ibm.com>
77c23f
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
77c23f
(cherry picked from commit 1cca8265499d394d9ed4bfb75bd6e7265b529f89)
77c23f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
77c23f
---
77c23f
 target/s390x/cpu.h        |  7 ++++++-
77c23f
 target/s390x/kvm.c        | 26 ++++++++++++++++++++++++++
77c23f
 target/s390x/kvm_s390x.h  |  2 ++
77c23f
 target/s390x/mmu_helper.c | 14 ++++++++++++++
77c23f
 4 files changed, 48 insertions(+), 1 deletion(-)
77c23f
77c23f
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
77c23f
index 1ff84e6b3a..edf8391504 100644
77c23f
--- a/target/s390x/cpu.h
77c23f
+++ b/target/s390x/cpu.h
77c23f
@@ -828,7 +828,12 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
77c23f
 #define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len)   \
77c23f
         s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
77c23f
 void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
77c23f
-
77c23f
+int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
77c23f
+                       int len, bool is_write);
77c23f
+#define s390_cpu_pv_mem_read(cpu, offset, dest, len)    \
77c23f
+        s390_cpu_pv_mem_rw(cpu, offset, dest, len, false)
77c23f
+#define s390_cpu_pv_mem_write(cpu, offset, dest, len)       \
77c23f
+        s390_cpu_pv_mem_rw(cpu, offset, dest, len, true)
77c23f
 
77c23f
 /* sigp.c */
77c23f
 int s390_cpu_restart(S390CPU *cpu);
77c23f
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
77c23f
index af50b2c253..f67bb5ce2c 100644
77c23f
--- a/target/s390x/kvm.c
77c23f
+++ b/target/s390x/kvm.c
77c23f
@@ -154,6 +154,7 @@ static int cap_ri;
77c23f
 static int cap_gs;
77c23f
 static int cap_hpage_1m;
77c23f
 static int cap_vcpu_resets;
77c23f
+static int cap_protected;
77c23f
 
77c23f
 static int active_cmma;
77c23f
 
77c23f
@@ -351,6 +352,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
77c23f
     cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
77c23f
     cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
77c23f
     cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
77c23f
+    cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED);
77c23f
 
77c23f
     if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
77c23f
         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
77c23f
@@ -848,6 +850,30 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
77c23f
     return ret;
77c23f
 }
77c23f
 
77c23f
+int kvm_s390_mem_op_pv(S390CPU *cpu, uint64_t offset, void *hostbuf,
77c23f
+                       int len, bool is_write)
77c23f
+{
77c23f
+    struct kvm_s390_mem_op mem_op = {
77c23f
+        .sida_offset = offset,
77c23f
+        .size = len,
77c23f
+        .op = is_write ? KVM_S390_MEMOP_SIDA_WRITE
77c23f
+                       : KVM_S390_MEMOP_SIDA_READ,
77c23f
+        .buf = (uint64_t)hostbuf,
77c23f
+    };
77c23f
+    int ret;
77c23f
+
77c23f
+    if (!cap_mem_op || !cap_protected) {
77c23f
+        return -ENOSYS;
77c23f
+    }
77c23f
+
77c23f
+    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
77c23f
+    if (ret < 0) {
77c23f
+        error_report("KVM_S390_MEM_OP failed: %s", strerror(-ret));
77c23f
+        abort();
77c23f
+    }
77c23f
+    return ret;
77c23f
+}
77c23f
+
77c23f
 /*
77c23f
  * Legacy layout for s390:
77c23f
  * Older S390 KVM requires the topmost vma of the RAM to be
77c23f
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
77c23f
index dea813f450..6ab17c81b7 100644
77c23f
--- a/target/s390x/kvm_s390x.h
77c23f
+++ b/target/s390x/kvm_s390x.h
77c23f
@@ -19,6 +19,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
77c23f
 void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
77c23f
 int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
77c23f
                     int len, bool is_write);
77c23f
+int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
77c23f
+                       bool is_write);
77c23f
 void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
77c23f
 int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
77c23f
 void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
77c23f
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
77c23f
index c9f3f34750..ec8befbdc8 100644
77c23f
--- a/target/s390x/mmu_helper.c
77c23f
+++ b/target/s390x/mmu_helper.c
77c23f
@@ -474,6 +474,20 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
77c23f
     return 0;
77c23f
 }
77c23f
 
77c23f
+int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
77c23f
+                       int len, bool is_write)
77c23f
+{
77c23f
+    int ret;
77c23f
+
77c23f
+    if (kvm_enabled()) {
77c23f
+        ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write);
77c23f
+    } else {
77c23f
+        /* Protected Virtualization is a KVM/Hardware only feature */
77c23f
+        g_assert_not_reached();
77c23f
+    }
77c23f
+    return ret;
77c23f
+}
77c23f
+
77c23f
 /**
77c23f
  * s390_cpu_virt_mem_rw:
77c23f
  * @laddr:     the logical start address
77c23f
-- 
77c23f
2.27.0
77c23f