136 lines
4.9 KiB
Diff
136 lines
4.9 KiB
Diff
From 1cfcff169f392179258e4535e60d4ef9cabae3c6 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Huth <thuth@redhat.com>
|
|
Date: Fri, 29 May 2020 05:54:13 -0400
|
|
Subject: [PATCH 31/42] s390x: protvirt: Disable address checks for PV guest IO
|
|
emulation
|
|
|
|
RH-Author: Thomas Huth <thuth@redhat.com>
|
|
Message-id: <20200529055420.16855-32-thuth@redhat.com>
|
|
Patchwork-id: 97044
|
|
O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 31/38] s390x: protvirt: Disable address checks for PV guest IO emulation
|
|
Bugzilla: 1828317
|
|
RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
|
|
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
|
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
|
|
|
From: Janosch Frank <frankja@linux.ibm.com>
|
|
|
|
IO instruction data is routed through SIDAD for protected guests, so
|
|
adresses do not need to be checked, as this is kernel memory which is
|
|
always available.
|
|
|
|
Also the instruction data always starts at offset 0 of the SIDAD.
|
|
|
|
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
|
|
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
|
Reviewed-by: David Hildenbrand <david@redhat.com>
|
|
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
|
|
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
|
|
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
|
|
Message-Id: <20200319131921.2367-13-frankja@linux.ibm.com>
|
|
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
|
|
(cherry picked from commit c10b708752e5264a85b5c3afa0a0ccfcf6503ddf)
|
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
---
|
|
target/s390x/ioinst.c | 35 ++++++++++++++++++++++++++++-------
|
|
1 file changed, 28 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
|
|
index c437a1d8c6..bbcccf6be2 100644
|
|
--- a/target/s390x/ioinst.c
|
|
+++ b/target/s390x/ioinst.c
|
|
@@ -16,6 +16,25 @@
|
|
#include "hw/s390x/ioinst.h"
|
|
#include "trace.h"
|
|
#include "hw/s390x/s390-pci-bus.h"
|
|
+#include "hw/s390x/pv.h"
|
|
+
|
|
+/* All I/O instructions but chsc use the s format */
|
|
+static uint64_t get_address_from_regs(CPUS390XState *env, uint32_t ipb,
|
|
+ uint8_t *ar)
|
|
+{
|
|
+ /*
|
|
+ * Addresses for protected guests are all offsets into the
|
|
+ * satellite block which holds the IO control structures. Those
|
|
+ * control structures are always starting at offset 0 and are
|
|
+ * always aligned and accessible. So we can return 0 here which
|
|
+ * will pass the following address checks.
|
|
+ */
|
|
+ if (s390_is_pv()) {
|
|
+ *ar = 0;
|
|
+ return 0;
|
|
+ }
|
|
+ return decode_basedisp_s(env, ipb, ar);
|
|
+}
|
|
|
|
int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
|
|
int *schid)
|
|
@@ -114,7 +133,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
|
CPUS390XState *env = &cpu->env;
|
|
uint8_t ar;
|
|
|
|
- addr = decode_basedisp_s(env, ipb, &ar);
|
|
+ addr = get_address_from_regs(env, ipb, &ar);
|
|
if (addr & 3) {
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
|
return;
|
|
@@ -171,7 +190,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
|
CPUS390XState *env = &cpu->env;
|
|
uint8_t ar;
|
|
|
|
- addr = decode_basedisp_s(env, ipb, &ar);
|
|
+ addr = get_address_from_regs(env, ipb, &ar);
|
|
if (addr & 3) {
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
|
return;
|
|
@@ -203,7 +222,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
|
|
CPUS390XState *env = &cpu->env;
|
|
uint8_t ar;
|
|
|
|
- addr = decode_basedisp_s(env, ipb, &ar);
|
|
+ addr = get_address_from_regs(env, ipb, &ar);
|
|
if (addr & 3) {
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
|
return;
|
|
@@ -234,7 +253,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
|
|
CPUS390XState *env = &cpu->env;
|
|
uint8_t ar;
|
|
|
|
- addr = decode_basedisp_s(env, ipb, &ar);
|
|
+ addr = get_address_from_regs(env, ipb, &ar);
|
|
if (addr & 3) {
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
|
return;
|
|
@@ -303,7 +322,7 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
|
return -EIO;
|
|
}
|
|
trace_ioinst_sch_id("tsch", cssid, ssid, schid);
|
|
- addr = decode_basedisp_s(env, ipb, &ar);
|
|
+ addr = get_address_from_regs(env, ipb, &ar);
|
|
if (addr & 3) {
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
|
return -EIO;
|
|
@@ -601,7 +620,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
|
|
{
|
|
ChscReq *req;
|
|
ChscResp *res;
|
|
- uint64_t addr;
|
|
+ uint64_t addr = 0;
|
|
int reg;
|
|
uint16_t len;
|
|
uint16_t command;
|
|
@@ -610,7 +629,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
|
|
|
|
trace_ioinst("chsc");
|
|
reg = (ipb >> 20) & 0x00f;
|
|
- addr = env->regs[reg];
|
|
+ if (!s390_is_pv()) {
|
|
+ addr = env->regs[reg];
|
|
+ }
|
|
/* Page boundary? */
|
|
if (addr & 0xfff) {
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
|
--
|
|
2.27.0
|
|
|