42aeb20e68
Update to v5.0.0 OBS-URL: https://build.opensuse.org/request/show/798748 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=547
120 lines
4.3 KiB
Diff
120 lines
4.3 KiB
Diff
From: Janosch Frank <frankja@linux.ibm.com>
|
|
Date: Fri, 29 Nov 2019 04:22:41 -0500
|
|
Subject: s390x: protvirt: Disable address checks for PV guest IO emulation
|
|
|
|
References: bsc#1167075
|
|
|
|
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>
|
|
(cherry picked from commit f658bf14295ad49caf8d1b21033982ce69423fb7)
|
|
Signed-off-by: Bruce Rogers <brogers@suse.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 0e840cc5792afe02d543568ba880..8828482eec306a2bccd8bef269b7 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);
|