Accepting request 787000 from home:bfrogers:branches:Virtualization

- Include upstream patches targeted for the next stable release
  (bug fixes only)
  block-io-fix-bdrv_co_do_copy_on_readv.patch
  compat-disable-edid-on-correct-virtio-gp.patch
  target-ppc-Fix-rlwinm-on-ppc64.patch
  vhost-correctly-turn-on-VIRTIO_F_IOMMU_P.patch
- s390x Protected Virtualization support - start and control guest
  in secure mode. (note: binary patch from patch series dropped since
  for s390x we rebuild the patched binary anyways) (bsc#1167075
  jsc#SLE-7407)
  s390-sclp-improve-special-wait-psw-logic.patch
  s390x-Add-missing-vcpu-reset-functions.patch
  s390x-Add-SIDA-memory-ops.patch
  s390x-Add-unpack-facility-feature-to-GA1.patch
  s390x-Beautify-diag308-handling.patch
  s390x-Don-t-do-a-normal-reset-on-the-ini.patch
  s390x-ipl-Consolidate-iplb-validity-chec.patch
  s390x-kvm-Make-kvm_sclp_service_call-voi.patch
  s390x-Move-clear-reset.patch
  s390x-Move-diagnose-308-subcodes-and-rcs.patch
  s390x-Move-initial-reset.patch
  s390x-Move-reset-normal-to-shared-reset-.patch
  s390x-protvirt-Add-migration-blocker.patch
  s390x-protvirt-Disable-address-checks-fo.patch
  s390x-protvirt-Handle-SIGP-store-status-.patch
  s390x-protvirt-Inhibit-balloon-when-swit.patch
  s390x-protvirt-KVM-intercept-changes.patch
  s390x-protvirt-Move-diag-308-data-over-S.patch
  s390x-protvirt-Move-IO-control-structure.patch
  s390x-protvirt-Move-STSI-data-over-SIDAD.patch
  s390x-protvirt-SCLP-interpretation.patch
  s390x-protvirt-Set-guest-IPL-PSW.patch
  s390x-protvirt-Support-unpack-facility.patch
  Sync-pv.patch

OBS-URL: https://build.opensuse.org/request/show/787000
OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=538
This commit is contained in:
Bruce Rogers 2020-03-20 22:41:29 +00:00 committed by Git OBS Bridge
parent 3be3db8e88
commit a447edb5e5
32 changed files with 3285 additions and 46 deletions

92
Sync-pv.patch Normal file
View File

@ -0,0 +1,92 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Tue, 25 Feb 2020 06:09:23 -0500
Subject: Sync pv
References: bsc#1167075
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
(cherry picked from commit 6807f464961cfee1dd81c95e22ddd91fa352fcc4)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
linux-headers/linux/kvm.h | 50 +++++++++++++++++++++++++++++++++++++--
1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 3d9b18f7f871acd0d13a0c42f184..18c636070edaf09dd8cf33ddb400 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -468,12 +468,17 @@ struct kvm_s390_mem_op {
__u32 size; /* amount of bytes */
__u32 op; /* type of operation */
__u64 buf; /* buffer in userspace */
- __u8 ar; /* the access register number */
- __u8 reserved[31]; /* should be set to 0 */
+ union {
+ __u8 ar; /* the access register number */
+ __u32 sida_offset; /* offset into the sida */
+ __u8 reserved[32]; /* should be set to 0 */
+ };
};
/* types for kvm_s390_mem_op->op */
#define KVM_S390_MEMOP_LOGICAL_READ 0
#define KVM_S390_MEMOP_LOGICAL_WRITE 1
+#define KVM_S390_MEMOP_SIDA_READ 2
+#define KVM_S390_MEMOP_SIDA_WRITE 3
/* flags for kvm_s390_mem_op->flags */
#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
@@ -1000,6 +1005,8 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_PMU_EVENT_FILTER 173
#define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
#define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
+#define KVM_CAP_S390_VCPU_RESETS 179
+#define KVM_CAP_S390_PROTECTED 180
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1461,6 +1468,45 @@ struct kvm_enc_region {
/* Available with KVM_CAP_ARM_SVE */
#define KVM_ARM_VCPU_FINALIZE _IOW(KVMIO, 0xc2, int)
+/* Available with KVM_CAP_S390_VCPU_RESETS */
+#define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3)
+#define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4)
+
+struct kvm_s390_pv_sec_parm {
+ __u64 origin;
+ __u64 length;
+};
+
+struct kvm_s390_pv_unp {
+ __u64 addr;
+ __u64 size;
+ __u64 tweak;
+};
+
+enum pv_cmd_id {
+ KVM_PV_ENABLE,
+ KVM_PV_DISABLE,
+ KVM_PV_VM_SET_SEC_PARMS,
+ KVM_PV_VM_UNPACK,
+ KVM_PV_VM_VERIFY,
+ KVM_PV_VM_PREP_RESET,
+ KVM_PV_VM_UNSHARE_ALL,
+ KVM_PV_VCPU_CREATE,
+ KVM_PV_VCPU_DESTROY,
+};
+
+struct kvm_pv_cmd {
+ __u32 cmd; /* Command to be executed */
+ __u16 rc; /* Ultravisor return code */
+ __u16 rrc; /* Ultravisor return reason code */
+ __u64 data; /* Data or address */
+ __u32 flags; /* flags for future extensions. Must be 0 for now */
+ __u32 reserved[3];
+};
+
+/* Available with KVM_CAP_S390_PROTECTED */
+#define KVM_S390_PV_COMMAND _IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
+
/* Secure Encrypted Virtualization command */
enum sev_cmd_id {
/* Guest initialization commands */

View File

@ -0,0 +1,38 @@
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Date: Thu, 12 Mar 2020 11:19:49 +0300
Subject: block/io: fix bdrv_co_do_copy_on_readv
Git-commit: 4ab78b19189a81038e744728ed949d09aa477550
Prior to 1143ec5ebf4 it was OK to qemu_iovec_from_buf() from aligned-up
buffer to original qiov, as qemu_iovec_from_buf() will stop at qiov end
anyway.
But after 1143ec5ebf4 we assume that bdrv_co_do_copy_on_readv works on
part of original qiov, defined by qiov_offset and bytes. So we must not
touch qiov behind qiov_offset+bytes bound. Fix it.
Cc: qemu-stable@nongnu.org # v4.2
Fixes: 1143ec5ebf4
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 20200312081949.5350-1-vsementsov@virtuozzo.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
block/io.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/io.c b/block/io.c
index d1f1ee9138c7af82352e9277f22b..c2c3aab9ee3d1d4d494ce98a6d8b 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1395,7 +1395,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
if (!(flags & BDRV_REQ_PREFETCH)) {
qemu_iovec_from_buf(qiov, qiov_offset + progress,
bounce_buffer + skip_bytes,
- pnum - skip_bytes);
+ MIN(pnum - skip_bytes, bytes - progress));
}
} else if (!(flags & BDRV_REQ_PREFETCH)) {
/* Read directly into the destination */

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d6076daf7ce76bafd1fc236b472bb3fbb516e8a2e68440f670a031c2d254250
size 105540
oid sha256:8f2312cc7d4811cb10363273c211a6fcf58361e401b7b0c9824c9ed22c4ce898
size 121876

View File

@ -0,0 +1,41 @@
From: Cornelia Huck <cohuck@redhat.com>
Date: Wed, 18 Mar 2020 10:39:19 +0100
Subject: compat: disable edid on correct virtio-gpu device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 02501fc39381c4dabaf6becdd12c2a4754c3847c
Commit bb15791166c1 ("compat: disable edid on virtio-gpu base
device") tried to disable 'edid' on the virtio-gpu base device.
However, that device is not 'virtio-gpu', but 'virtio-gpu-device'.
Fix it.
Fixes: bb15791166c1 ("compat: disable edid on virtio-gpu base device")
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
Tested-by: Lukáš Doktor <ldoktor@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Message-id: 20200318093919.24942-1-cohuck@redhat.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/core/machine.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index a15c5a8673ade765965b4e2c8237..cfab784b02ce6076c827c10c9e9c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -37,7 +37,7 @@ GlobalProperty hw_compat_4_0[] = {
{ "secondary-vga", "edid", "false" },
{ "bochs-display", "edid", "false" },
{ "virtio-vga", "edid", "false" },
- { "virtio-gpu", "edid", "false" },
+ { "virtio-gpu-device", "edid", "false" },
{ "virtio-device", "use-started", "false" },
{ "virtio-balloon-device", "qemu-4-0-config-size", "true" },
{ "pl031", "migrate-tick-offset", "false" },

View File

@ -2,7 +2,7 @@ From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 4 Mar 2020 06:42:31 -0500
Subject: pc-bios: s390x: Save iplb location in lowcore
References: bsc#1163140
References: bsc#1163140, bsc#1167075
The POP states that for a list directed IPL the IPLB is stored into
memory by the machine loader and its address is stored at offset 0x14
@ -23,7 +23,9 @@ Message-Id: <20200304114231.23493-19-frankja@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
(cherry picked from commit 9bfc04f9ef6802fff0fc77130ff345a541783363)
Signed-off-by: Liang Yan <lyan@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
pc-bios/s390-ccw/jump2ipl.c | 1 +
pc-bios/s390-ccw/main.c | 8 +++++++-

View File

@ -1,3 +1,41 @@
-------------------------------------------------------------------
Fri Mar 20 17:27:29 UTC 2020 - Bruce Rogers <brogers@suse.com>
- Include upstream patches targeted for the next stable release
(bug fixes only)
block-io-fix-bdrv_co_do_copy_on_readv.patch
compat-disable-edid-on-correct-virtio-gp.patch
target-ppc-Fix-rlwinm-on-ppc64.patch
vhost-correctly-turn-on-VIRTIO_F_IOMMU_P.patch
- s390x Protected Virtualization support - start and control guest
in secure mode. (note: binary patch from patch series dropped since
for s390x we rebuild the patched binary anyways) (bsc#1167075
jsc#SLE-7407)
s390-sclp-improve-special-wait-psw-logic.patch
s390x-Add-missing-vcpu-reset-functions.patch
s390x-Add-SIDA-memory-ops.patch
s390x-Add-unpack-facility-feature-to-GA1.patch
s390x-Beautify-diag308-handling.patch
s390x-Don-t-do-a-normal-reset-on-the-ini.patch
s390x-ipl-Consolidate-iplb-validity-chec.patch
s390x-kvm-Make-kvm_sclp_service_call-voi.patch
s390x-Move-clear-reset.patch
s390x-Move-diagnose-308-subcodes-and-rcs.patch
s390x-Move-initial-reset.patch
s390x-Move-reset-normal-to-shared-reset-.patch
s390x-protvirt-Add-migration-blocker.patch
s390x-protvirt-Disable-address-checks-fo.patch
s390x-protvirt-Handle-SIGP-store-status-.patch
s390x-protvirt-Inhibit-balloon-when-swit.patch
s390x-protvirt-KVM-intercept-changes.patch
s390x-protvirt-Move-diag-308-data-over-S.patch
s390x-protvirt-Move-IO-control-structure.patch
s390x-protvirt-Move-STSI-data-over-SIDAD.patch
s390x-protvirt-SCLP-interpretation.patch
s390x-protvirt-Set-guest-IPL-PSW.patch
s390x-protvirt-Support-unpack-facility.patch
Sync-pv.patch
-------------------------------------------------------------------
Fri Mar 20 15:28:35 UTC 2020 - Liang Yan <lyan@suse.com>

142
qemu.spec
View File

@ -202,49 +202,77 @@ Patch00071: iotests-Fix-nonportable-use-of-od-endian.patch
Patch00072: block-qcow2-threads-fix-qcow2_decompress.patch
Patch00073: job-refactor-progress-to-separate-object.patch
Patch00074: block-block-copy-fix-progress-calculatio.patch
Patch00075: XXX-dont-dump-core-on-sigabort.patch
Patch00076: qemu-binfmt-conf-Modify-default-path.patch
Patch00077: qemu-cvs-gettimeofday.patch
Patch00078: qemu-cvs-ioctl_debug.patch
Patch00079: qemu-cvs-ioctl_nodirection.patch
Patch00080: linux-user-add-binfmt-wrapper-for-argv-0.patch
Patch00081: PPC-KVM-Disable-mmu-notifier-check.patch
Patch00082: linux-user-binfmt-support-host-binaries.patch
Patch00083: linux-user-Fake-proc-cpuinfo.patch
Patch00084: linux-user-use-target_ulong.patch
Patch00085: Make-char-muxer-more-robust-wrt-small-FI.patch
Patch00086: linux-user-lseek-explicitly-cast-non-set.patch
Patch00087: AIO-Reduce-number-of-threads-for-32bit-h.patch
Patch00088: xen_disk-Add-suse-specific-flush-disable.patch
Patch00089: qemu-bridge-helper-reduce-security-profi.patch
Patch00090: qemu-binfmt-conf-use-qemu-ARCH-binfmt.patch
Patch00091: linux-user-properly-test-for-infinite-ti.patch
Patch00092: roms-Makefile-pass-a-packaging-timestamp.patch
Patch00093: Raise-soft-address-space-limit-to-hard-l.patch
Patch00094: increase-x86_64-physical-bits-to-42.patch
Patch00095: vga-Raise-VRAM-to-16-MiB-for-pc-0.15-and.patch
Patch00096: i8254-Fix-migration-from-SLE11-SP2.patch
Patch00097: acpi_piix4-Fix-migration-from-SLE11-SP2.patch
Patch00098: Switch-order-of-libraries-for-mpath-supp.patch
Patch00099: Make-installed-scripts-explicitly-python.patch
Patch00100: hw-smbios-handle-both-file-formats-regar.patch
Patch00101: xen-add-block-resize-support-for-xen-dis.patch
Patch00102: tests-qemu-iotests-Triple-timeout-of-i-o.patch
Patch00103: tests-Fix-block-tests-to-be-compatible-w.patch
Patch00104: xen-ignore-live-parameter-from-xen-save-.patch
Patch00105: Conditionalize-ui-bitmap-installation-be.patch
Patch00106: tests-change-error-message-in-test-162.patch
Patch00107: hw-usb-hcd-xhci-Fix-GCC-9-build-warning.patch
Patch00108: hw-usb-dev-mtp-Fix-GCC-9-build-warning.patch
Patch00109: hw-intc-exynos4210_gic-provide-more-room.patch
Patch00110: configure-only-populate-roms-if-softmmu.patch
Patch00111: pc-bios-s390-ccw-net-avoid-warning-about.patch
Patch00112: roms-change-cross-compiler-naming-to-be-.patch
Patch00113: tests-Disable-some-block-tests-for-now.patch
Patch00114: test-add-mapping-from-arch-of-i686-to-qe.patch
Patch00115: roms-Makefile-enable-cross-compile-for-b.patch
Patch00116: hw-i386-disable-smbus-migration-for-xenf.patch
Patch00117: pc-bios-s390x-Save-iplb-location-in-lowc.patch
Patch00075: block-io-fix-bdrv_co_do_copy_on_readv.patch
Patch00076: target-ppc-Fix-rlwinm-on-ppc64.patch
Patch00077: compat-disable-edid-on-correct-virtio-gp.patch
Patch00078: XXX-dont-dump-core-on-sigabort.patch
Patch00079: qemu-binfmt-conf-Modify-default-path.patch
Patch00080: qemu-cvs-gettimeofday.patch
Patch00081: qemu-cvs-ioctl_debug.patch
Patch00082: qemu-cvs-ioctl_nodirection.patch
Patch00083: linux-user-add-binfmt-wrapper-for-argv-0.patch
Patch00084: PPC-KVM-Disable-mmu-notifier-check.patch
Patch00085: linux-user-binfmt-support-host-binaries.patch
Patch00086: linux-user-Fake-proc-cpuinfo.patch
Patch00087: linux-user-use-target_ulong.patch
Patch00088: Make-char-muxer-more-robust-wrt-small-FI.patch
Patch00089: linux-user-lseek-explicitly-cast-non-set.patch
Patch00090: AIO-Reduce-number-of-threads-for-32bit-h.patch
Patch00091: xen_disk-Add-suse-specific-flush-disable.patch
Patch00092: qemu-bridge-helper-reduce-security-profi.patch
Patch00093: qemu-binfmt-conf-use-qemu-ARCH-binfmt.patch
Patch00094: linux-user-properly-test-for-infinite-ti.patch
Patch00095: roms-Makefile-pass-a-packaging-timestamp.patch
Patch00096: Raise-soft-address-space-limit-to-hard-l.patch
Patch00097: increase-x86_64-physical-bits-to-42.patch
Patch00098: vga-Raise-VRAM-to-16-MiB-for-pc-0.15-and.patch
Patch00099: i8254-Fix-migration-from-SLE11-SP2.patch
Patch00100: acpi_piix4-Fix-migration-from-SLE11-SP2.patch
Patch00101: Switch-order-of-libraries-for-mpath-supp.patch
Patch00102: Make-installed-scripts-explicitly-python.patch
Patch00103: hw-smbios-handle-both-file-formats-regar.patch
Patch00104: xen-add-block-resize-support-for-xen-dis.patch
Patch00105: tests-qemu-iotests-Triple-timeout-of-i-o.patch
Patch00106: tests-Fix-block-tests-to-be-compatible-w.patch
Patch00107: xen-ignore-live-parameter-from-xen-save-.patch
Patch00108: Conditionalize-ui-bitmap-installation-be.patch
Patch00109: tests-change-error-message-in-test-162.patch
Patch00110: hw-usb-hcd-xhci-Fix-GCC-9-build-warning.patch
Patch00111: hw-usb-dev-mtp-Fix-GCC-9-build-warning.patch
Patch00112: hw-intc-exynos4210_gic-provide-more-room.patch
Patch00113: configure-only-populate-roms-if-softmmu.patch
Patch00114: pc-bios-s390-ccw-net-avoid-warning-about.patch
Patch00115: roms-change-cross-compiler-naming-to-be-.patch
Patch00116: tests-Disable-some-block-tests-for-now.patch
Patch00117: test-add-mapping-from-arch-of-i686-to-qe.patch
Patch00118: roms-Makefile-enable-cross-compile-for-b.patch
Patch00119: hw-i386-disable-smbus-migration-for-xenf.patch
Patch00120: s390x-Don-t-do-a-normal-reset-on-the-ini.patch
Patch00121: s390x-Move-reset-normal-to-shared-reset-.patch
Patch00122: s390x-Move-initial-reset.patch
Patch00123: s390x-Move-clear-reset.patch
Patch00124: s390x-kvm-Make-kvm_sclp_service_call-voi.patch
Patch00125: s390x-ipl-Consolidate-iplb-validity-chec.patch
Patch00126: s390x-Beautify-diag308-handling.patch
Patch00127: s390x-Add-missing-vcpu-reset-functions.patch
Patch00128: pc-bios-s390x-Save-iplb-location-in-lowc.patch
Patch00129: s390-sclp-improve-special-wait-psw-logic.patch
Patch00130: s390x-Move-diagnose-308-subcodes-and-rcs.patch
Patch00131: vhost-correctly-turn-on-VIRTIO_F_IOMMU_P.patch
Patch00132: Sync-pv.patch
Patch00133: s390x-protvirt-Support-unpack-facility.patch
Patch00134: s390x-protvirt-Add-migration-blocker.patch
Patch00135: s390x-protvirt-Inhibit-balloon-when-swit.patch
Patch00136: s390x-protvirt-KVM-intercept-changes.patch
Patch00137: s390x-Add-SIDA-memory-ops.patch
Patch00138: s390x-protvirt-Move-STSI-data-over-SIDAD.patch
Patch00139: s390x-protvirt-SCLP-interpretation.patch
Patch00140: s390x-protvirt-Set-guest-IPL-PSW.patch
Patch00141: s390x-protvirt-Move-diag-308-data-over-S.patch
Patch00142: s390x-protvirt-Disable-address-checks-fo.patch
Patch00143: s390x-protvirt-Move-IO-control-structure.patch
Patch00144: s390x-protvirt-Handle-SIGP-store-status-.patch
Patch00145: s390x-Add-unpack-facility-feature-to-GA1.patch
# Patches applied in roms/seabios/:
Patch01000: seabios-use-python2-explicitly-as-needed.patch
Patch01001: seabios-switch-to-python3-as-needed.patch
@ -1078,6 +1106,34 @@ This package provides a service file for starting and stopping KSM.
%patch00115 -p1
%patch00116 -p1
%patch00117 -p1
%patch00118 -p1
%patch00119 -p1
%patch00120 -p1
%patch00121 -p1
%patch00122 -p1
%patch00123 -p1
%patch00124 -p1
%patch00125 -p1
%patch00126 -p1
%patch00127 -p1
%patch00128 -p1
%patch00129 -p1
%patch00130 -p1
%patch00131 -p1
%patch00132 -p1
%patch00133 -p1
%patch00134 -p1
%patch00135 -p1
%patch00136 -p1
%patch00137 -p1
%patch00138 -p1
%patch00139 -p1
%patch00140 -p1
%patch00141 -p1
%patch00142 -p1
%patch00143 -p1
%patch00144 -p1
%patch00145 -p1
%patch01000 -p1
%patch01001 -p1
%patch01002 -p1

View File

@ -0,0 +1,35 @@
From: Christian Borntraeger <borntraeger@de.ibm.com>
Date: Thu, 20 Feb 2020 14:16:22 +0100
Subject: s390/sclp: improve special wait psw logic
References: bsc#1167075
There is a special quiesce PSW that we check for "shutdown". Otherwise disabled
wait is detected as "crashed". Architecturally we must only check PSW bits
116-127. Fix this.
Cc: qemu-stable@nongnu.org
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <1582204582-22995-1-git-send-email-borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Acked-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 8b51c0961cc13e55b26bb6665ec3a341abdc7658)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index a3a49164e471b3f00a40020f987d..6808dfda01f42acbaa1d36ef787b 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -89,7 +89,7 @@ hwaddr s390_cpu_get_phys_addr_debug(CPUState *cs, vaddr vaddr)
static inline bool is_special_wait_psw(uint64_t psw_addr)
{
/* signal quiesce */
- return psw_addr == 0xfffUL;
+ return (psw_addr & 0xfffUL) == 0xfffUL;
}
void s390_handle_wait(S390CPU *cpu)

View File

@ -0,0 +1,135 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 5 Feb 2020 06:57:35 -0500
Subject: s390x: Add SIDA memory ops
References: bsc#1167075
Protected guests save the instruction control blocks in the SIDA
instead of QEMU/KVM directly accessing the guest's memory.
Let's introduce new functions to access the SIDA.
The memops for doing so are available with KVM_CAP_S390_PROTECTED, so
let's check for that.
Signed-off-by: Janosch Frank <frankja@linux.ibm.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 a9f21cec3bc9c86062c7c24bb2143d22cb3c2950)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/cpu.h | 7 ++++++-
target/s390x/kvm.c | 26 ++++++++++++++++++++++++++
target/s390x/kvm_s390x.h | 2 ++
target/s390x/mmu_helper.c | 14 ++++++++++++++
4 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index d2af13b345ccd9094f82385cd528..2ec0f78b48ee15978b62f5fdc1b2 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -821,7 +821,12 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
#define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \
s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
-
+int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
+ int len, bool is_write);
+#define s390_cpu_pv_mem_read(cpu, offset, dest, len) \
+ s390_cpu_pv_mem_rw(cpu, offset, dest, len, false)
+#define s390_cpu_pv_mem_write(cpu, offset, dest, len) \
+ s390_cpu_pv_mem_rw(cpu, offset, dest, len, true)
/* sigp.c */
int s390_cpu_restart(S390CPU *cpu);
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index abeeaaa67452b0b938557b0d0dea..941e4df630ad9b3dc780d3c92e6b 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -154,6 +154,7 @@ static int cap_ri;
static int cap_gs;
static int cap_hpage_1m;
static int cap_vcpu_resets;
+static int cap_protected;
static int active_cmma;
@@ -351,6 +352,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
+ cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED);
if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
@@ -848,6 +850,30 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
return ret;
}
+int kvm_s390_mem_op_pv(S390CPU *cpu, uint64_t offset, void *hostbuf,
+ int len, bool is_write)
+{
+ struct kvm_s390_mem_op mem_op = {
+ .sida_offset = offset,
+ .size = len,
+ .op = is_write ? KVM_S390_MEMOP_SIDA_WRITE
+ : KVM_S390_MEMOP_SIDA_READ,
+ .buf = (uint64_t)hostbuf,
+ };
+ int ret;
+
+ if (!cap_mem_op || !cap_protected) {
+ return -ENOSYS;
+ }
+
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
+ if (ret < 0) {
+ error_report("KVM_S390_MEM_OP failed: %s", strerror(-ret));
+ abort();
+ }
+ return ret;
+}
+
/*
* Legacy layout for s390:
* Older S390 KVM requires the topmost vma of the RAM to be
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
index dea813f450153c34e1269424772d..6ab17c81b73a0011e32213552698 100644
--- a/target/s390x/kvm_s390x.h
+++ b/target/s390x/kvm_s390x.h
@@ -19,6 +19,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
int len, bool is_write);
+int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
+ bool is_write);
void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index c9f3f347501097b894333a36cac3..ec8befbdc87d4c88d83baeeab20e 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -474,6 +474,20 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
return 0;
}
+int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
+ int len, bool is_write)
+{
+ int ret;
+
+ if (kvm_enabled()) {
+ ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write);
+ } else {
+ /* Protected Virtualization is a KVM/Hardware only feature */
+ g_assert_not_reached();
+ }
+ return ret;
+}
+
/**
* s390_cpu_virt_mem_rw:
* @laddr: the logical start address

View File

@ -0,0 +1,159 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Fri, 14 Feb 2020 10:16:21 -0500
Subject: s390x: Add missing vcpu reset functions
References: bsc#1167075
Up to now we only had an ioctl to reset vcpu data QEMU couldn't reach
for the initial reset, which was also called for the clear reset. To
be architecture compliant, we also need to clear local interrupts on a
normal reset.
Because of this and the upcoming protvirt support we need to add
ioctls for the missing clear and normal resets.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
Message-Id: <20200214151636.8764-3-frankja@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit b91a03946e0f65ddd22927dd80ca1276bf89c5af)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/cpu.c | 14 ++++++++++++--
target/s390x/kvm-stub.c | 10 +++++++++-
target/s390x/kvm.c | 42 ++++++++++++++++++++++++++++++++--------
target/s390x/kvm_s390x.h | 4 +++-
4 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index bd39cb54b7aa3fa8edba5d9975a4..52fefa1586caa3cbd366fe230630 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -131,8 +131,18 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
}
/* Reset state inside the kernel that we cannot access yet from QEMU. */
- if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
- kvm_s390_reset_vcpu(cpu);
+ if (kvm_enabled()) {
+ switch (type) {
+ case S390_CPU_RESET_CLEAR:
+ kvm_s390_reset_vcpu_clear(cpu);
+ break;
+ case S390_CPU_RESET_INITIAL:
+ kvm_s390_reset_vcpu_initial(cpu);
+ break;
+ case S390_CPU_RESET_NORMAL:
+ kvm_s390_reset_vcpu_normal(cpu);
+ break;
+ }
}
}
diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
index 5152e2bdf19b2661330a1da80c5d..c4cd497f850eb9c7a859932b0f1f 100644
--- a/target/s390x/kvm-stub.c
+++ b/target/s390x/kvm-stub.c
@@ -83,7 +83,15 @@ void kvm_s390_cmma_reset(void)
{
}
-void kvm_s390_reset_vcpu(S390CPU *cpu)
+void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
+{
+}
+
+void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
+{
+}
+
+void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
{
}
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index ad6e38c8761be7e0cad57771f49b..f633472980b48757989db245fb1f 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -151,6 +151,7 @@ static int cap_s390_irq;
static int cap_ri;
static int cap_gs;
static int cap_hpage_1m;
+static int cap_vcpu_resets;
static int active_cmma;
@@ -342,6 +343,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
+ cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
@@ -403,17 +405,41 @@ int kvm_arch_destroy_vcpu(CPUState *cs)
return 0;
}
-void kvm_s390_reset_vcpu(S390CPU *cpu)
+static void kvm_s390_reset_vcpu(S390CPU *cpu, unsigned long type)
{
CPUState *cs = CPU(cpu);
- /* The initial reset call is needed here to reset in-kernel
- * vcpu data that we can't access directly from QEMU
- * (i.e. with older kernels which don't support sync_regs/ONE_REG).
- * Before this ioctl cpu_synchronize_state() is called in common kvm
- * code (kvm-all) */
- if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
- error_report("Initial CPU reset failed on CPU %i", cs->cpu_index);
+ /*
+ * The reset call is needed here to reset in-kernel vcpu data that
+ * we can't access directly from QEMU (i.e. with older kernels
+ * which don't support sync_regs/ONE_REG). Before this ioctl
+ * cpu_synchronize_state() is called in common kvm code
+ * (kvm-all).
+ */
+ if (kvm_vcpu_ioctl(cs, type)) {
+ error_report("CPU reset failed on CPU %i type %lx",
+ cs->cpu_index, type);
+ }
+}
+
+void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
+{
+ kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
+}
+
+void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
+{
+ if (cap_vcpu_resets) {
+ kvm_s390_reset_vcpu(cpu, KVM_S390_CLEAR_RESET);
+ } else {
+ kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
+ }
+}
+
+void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
+{
+ if (cap_vcpu_resets) {
+ kvm_s390_reset_vcpu(cpu, KVM_S390_NORMAL_RESET);
}
}
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
index caf985955ba5da4e2cda021ed1b5..0b21789796d7c462bdc72160166f 100644
--- a/target/s390x/kvm_s390x.h
+++ b/target/s390x/kvm_s390x.h
@@ -34,7 +34,9 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
int vq, bool assign);
int kvm_s390_cmma_active(void);
void kvm_s390_cmma_reset(void);
-void kvm_s390_reset_vcpu(S390CPU *cpu);
+void kvm_s390_reset_vcpu_clear(S390CPU *cpu);
+void kvm_s390_reset_vcpu_normal(S390CPU *cpu);
+void kvm_s390_reset_vcpu_initial(S390CPU *cpu);
int kvm_s390_set_mem_limit(uint64_t new_limit, uint64_t *hw_limit);
void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
void kvm_s390_crypto_reset(void);

View File

@ -0,0 +1,61 @@
From: Christian Borntraeger <borntraeger@de.ibm.com>
Date: Tue, 25 Feb 2020 06:28:51 -0500
Subject: s390x: Add unpack facility feature to GA1
References: bsc#1167075
The unpack facility is an indication that diagnose 308 subcodes 8-10
are available to the guest. That means, that the guest can put itself
into protected mode.
Once it is in protected mode, the hardware stops any attempt of VM
introspection by the hypervisor.
Some features are currently not supported in protected mode:
* vfio devices
* Migration
* Huge page backings
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
(cherry picked from commit 3034eaac3b2970ba85a1d77814ceef1352d05357)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/gen-features.c | 1 +
target/s390x/kvm.c | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 6278845b12b8dee84c086413c60a..8ddeebc54419a3e2481e21916389 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -562,6 +562,7 @@ static uint16_t full_GEN15_GA1[] = {
S390_FEAT_GROUP_MSA_EXT_9,
S390_FEAT_GROUP_MSA_EXT_9_PCKMO,
S390_FEAT_ETOKEN,
+ S390_FEAT_UNPACK,
};
/* Default features (in order of release)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index d94b915da419c3ad0a1f9622ca13..8b82e4c93dfa7e89127bce74cde7 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -2407,6 +2407,14 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
clear_bit(S390_FEAT_BPB, model->features);
}
+ /*
+ * If we have support for protected virtualization, indicate
+ * the protected virtualization IPL unpack facility.
+ */
+ if (cap_protected) {
+ set_bit(S390_FEAT_UNPACK, model->features);
+ }
+
/* We emulate a zPCI bus and AEN, therefore we don't need HW support */
set_bit(S390_FEAT_ZPCI, model->features);
set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features);

View File

@ -0,0 +1,113 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 27 Nov 2019 12:50:45 -0500
Subject: s390x: Beautify diag308 handling
References: bsc#1167075
Let's improve readability by:
* Using constants for the subcodes
* Moving parameter checking into a function
* Removing subcode > 6 check as the default case catches that
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20191127175046.4911-6-frankja@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 0b7fd817e0f383760e37ca9286150d5816cf0594)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/diag.c | 54 +++++++++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 0c81d8e1efbfe37a384199488a72..54e5670b3fd6d960bd3fb4baca8b 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -53,6 +53,29 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
#define DIAG_308_RC_NO_CONF 0x0102
#define DIAG_308_RC_INVALID 0x0402
+#define DIAG308_RESET_MOD_CLR 0
+#define DIAG308_RESET_LOAD_NORM 1
+#define DIAG308_LOAD_CLEAR 3
+#define DIAG308_LOAD_NORMAL_DUMP 4
+#define DIAG308_SET 5
+#define DIAG308_STORE 6
+
+static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
+ uintptr_t ra, bool write)
+{
+ if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+ return -1;
+ }
+ if (!address_space_access_valid(&address_space_memory, addr,
+ sizeof(IplParameterBlock), write,
+ MEMTXATTRS_UNSPECIFIED)) {
+ s390_program_interrupt(env, PGM_ADDRESSING, ra);
+ return -1;
+ }
+ return 0;
+}
+
void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
{
CPUState *cs = env_cpu(env);
@@ -65,30 +88,24 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
return;
}
- if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
+ if (subcode & ~0x0ffffULL) {
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
return;
}
switch (subcode) {
- case 0:
+ case DIAG308_RESET_MOD_CLR:
s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
break;
- case 1:
+ case DIAG308_RESET_LOAD_NORM:
s390_ipl_reset_request(cs, S390_RESET_LOAD_NORMAL);
break;
- case 3:
+ case DIAG308_LOAD_CLEAR:
+ /* Well we still lack the clearing bit... */
s390_ipl_reset_request(cs, S390_RESET_REIPL);
break;
- case 5:
- if ((r1 & 1) || (addr & 0x0fffULL)) {
- s390_program_interrupt(env, PGM_SPECIFICATION, ra);
- return;
- }
- if (!address_space_access_valid(&address_space_memory, addr,
- sizeof(IplParameterBlock), false,
- MEMTXATTRS_UNSPECIFIED)) {
- s390_program_interrupt(env, PGM_ADDRESSING, ra);
+ case DIAG308_SET:
+ if (diag308_parm_check(env, r1, addr, ra, false)) {
return;
}
iplb = g_new0(IplParameterBlock, 1);
@@ -110,15 +127,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
out:
g_free(iplb);
return;
- case 6:
- if ((r1 & 1) || (addr & 0x0fffULL)) {
- s390_program_interrupt(env, PGM_SPECIFICATION, ra);
- return;
- }
- if (!address_space_access_valid(&address_space_memory, addr,
- sizeof(IplParameterBlock), true,
- MEMTXATTRS_UNSPECIFIED)) {
- s390_program_interrupt(env, PGM_ADDRESSING, ra);
+ case DIAG308_STORE:
+ if (diag308_parm_check(env, r1, addr, ra, true)) {
return;
}
iplb = s390_ipl_get_iplb();

View File

@ -0,0 +1,35 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 27 Nov 2019 12:50:41 -0500
Subject: s390x: Don't do a normal reset on the initial cpu
References: bsc#1167075
The initiating cpu needs to be reset with an initial reset. While
doing a normal reset followed by a initial reset is not wrong per se,
the Ultravisor will only allow the correct reset to be performed.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20191127175046.4911-2-frankja@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit ec9227339fce99412830d44a37eb0bd2fadd5f75)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/s390x/s390-virtio-ccw.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index d3edeef0ad924af160eb83ea6724..c1d1440272a42eef86eb14724f52 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -348,6 +348,9 @@ static void s390_machine_reset(MachineState *machine)
break;
case S390_RESET_LOAD_NORMAL:
CPU_FOREACH(t) {
+ if (t == cs) {
+ continue;
+ }
run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
}
subsystem_reset();

View File

@ -0,0 +1,129 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 27 Nov 2019 12:50:44 -0500
Subject: s390x: Move clear reset
References: bsc#1167075
Let's also move the clear reset function into the reset handler.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Message-Id: <20191127175046.4911-5-frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit eb8adcc3e9e3b8405c104ede72cf9f3bb2a5e226)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/cpu-qom.h | 1 +
target/s390x/cpu.c | 58 +++++++++++++-----------------------------
2 files changed, 18 insertions(+), 41 deletions(-)
diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
index 6f0a12042ed4802de7da08d63612..dbe5346ec9019f4f5939598b7a83 100644
--- a/target/s390x/cpu-qom.h
+++ b/target/s390x/cpu-qom.h
@@ -37,6 +37,7 @@ typedef struct S390CPUDef S390CPUDef;
typedef enum cpu_reset_type {
S390_CPU_RESET_NORMAL,
S390_CPU_RESET_INITIAL,
+ S390_CPU_RESET_CLEAR,
} cpu_reset_type;
/**
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index ca62fe768569b992bbf41b064734..bd39cb54b7aa3fa8edba5d9975a4 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -94,6 +94,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
switch (type) {
+ case S390_CPU_RESET_CLEAR:
+ memset(env, 0, offsetof(CPUS390XState, start_initial_reset_fields));
+ /* fall through */
case S390_CPU_RESET_INITIAL:
/* initial reset does not clear everything! */
memset(&env->start_initial_reset_fields, 0,
@@ -107,6 +110,14 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
env->cregs[0] = CR0_RESET;
env->cregs[14] = CR14_RESET;
+#if defined(CONFIG_USER_ONLY)
+ /* user mode should always be allowed to use the full FPU */
+ env->cregs[0] |= CR0_AFP;
+ if (s390_has_feat(S390_FEAT_VECTOR)) {
+ env->cregs[0] |= CR0_VECTOR;
+ }
+#endif
+
/* tininess for underflow is detected before rounding */
set_float_detect_tininess(float_tininess_before_rounding,
&env->fpu_status);
@@ -125,46 +136,6 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
}
}
-/* CPUClass:reset() */
-static void s390_cpu_full_reset(CPUState *s)
-{
- S390CPU *cpu = S390_CPU(s);
- S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
- CPUS390XState *env = &cpu->env;
-
- scc->parent_reset(s);
- cpu->env.sigp_order = 0;
- s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
-
- memset(env, 0, offsetof(CPUS390XState, end_reset_fields));
-
- /* architectured initial values for CR 0 and 14 */
- env->cregs[0] = CR0_RESET;
- env->cregs[14] = CR14_RESET;
-
-#if defined(CONFIG_USER_ONLY)
- /* user mode should always be allowed to use the full FPU */
- env->cregs[0] |= CR0_AFP;
- if (s390_has_feat(S390_FEAT_VECTOR)) {
- env->cregs[0] |= CR0_VECTOR;
- }
-#endif
-
- /* architectured initial value for Breaking-Event-Address register */
- env->gbea = 1;
-
- env->pfault_token = -1UL;
-
- /* tininess for underflow is detected before rounding */
- set_float_detect_tininess(float_tininess_before_rounding,
- &env->fpu_status);
-
- /* Reset state inside the kernel that we cannot access yet from QEMU. */
- if (kvm_enabled()) {
- kvm_s390_reset_vcpu(cpu);
- }
-}
-
#if !defined(CONFIG_USER_ONLY)
static void s390_cpu_machine_reset_cb(void *opaque)
{
@@ -456,6 +427,11 @@ static Property s390x_cpu_properties[] = {
DEFINE_PROP_END_OF_LIST()
};
+static void s390_cpu_reset_full(CPUState *s)
+{
+ return s390_cpu_reset(s, S390_CPU_RESET_CLEAR);
+}
+
static void s390_cpu_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *scc = S390_CPU_CLASS(oc);
@@ -472,7 +448,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
scc->load_normal = s390_cpu_load_normal;
#endif
scc->reset = s390_cpu_reset;
- cc->reset = s390_cpu_full_reset;
+ cc->reset = s390_cpu_reset_full;
cc->class_by_name = s390_cpu_class_by_name,
cc->has_work = s390_cpu_has_work;
#ifdef CONFIG_TCG

View File

@ -0,0 +1,61 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Fri, 13 Mar 2020 10:35:02 -0400
Subject: s390x: Move diagnose 308 subcodes and rcs into ipl.h
References: bsc#1167075
They are part of the IPL process, so let's put them into the ipl
header.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
(cherry picked from commit 284bc3dd6e9a978e6e34b00777ce72007a88d6d9)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/s390x/ipl.h | 11 +++++++++++
target/s390x/diag.c | 11 -----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 3e44abe1c651d8a01f4708c2801c..a5665e6bfde2e8cfbb1b2e6c7234 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -159,6 +159,17 @@ struct S390IPLState {
typedef struct S390IPLState S390IPLState;
QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
+#define DIAG_308_RC_OK 0x0001
+#define DIAG_308_RC_NO_CONF 0x0102
+#define DIAG_308_RC_INVALID 0x0402
+
+#define DIAG308_RESET_MOD_CLR 0
+#define DIAG308_RESET_LOAD_NORM 1
+#define DIAG308_LOAD_CLEAR 3
+#define DIAG308_LOAD_NORMAL_DUMP 4
+#define DIAG308_SET 5
+#define DIAG308_STORE 6
+
#define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02
#define S390_IPL_TYPE_QEMU_SCSI 0xff
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 54e5670b3fd6d960bd3fb4baca8b..8aba6341f94848e1ce8fff420ed8 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -49,17 +49,6 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
return diag288_class->handle_timer(diag288, func, timeout);
}
-#define DIAG_308_RC_OK 0x0001
-#define DIAG_308_RC_NO_CONF 0x0102
-#define DIAG_308_RC_INVALID 0x0402
-
-#define DIAG308_RESET_MOD_CLR 0
-#define DIAG308_RESET_LOAD_NORM 1
-#define DIAG308_LOAD_CLEAR 3
-#define DIAG308_LOAD_NORMAL_DUMP 4
-#define DIAG308_SET 5
-#define DIAG308_STORE 6
-
static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
uintptr_t ra, bool write)
{

View File

@ -0,0 +1,142 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Thu, 28 Nov 2019 03:37:23 -0500
Subject: s390x: Move initial reset
References: bsc#1167075
Let's move the intial reset into the reset handler and cleanup
afterwards.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20191128083723.11937-1-frankja@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 81b9222358e5c8f666f0d86057c75e40531d804c)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/cpu-qom.h | 2 +-
target/s390x/cpu.c | 46 +++++++++++++++++-------------------------
target/s390x/cpu.h | 2 +-
target/s390x/sigp.c | 2 +-
4 files changed, 21 insertions(+), 31 deletions(-)
diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
index f3b71bac67c91c9e307fa250b47a..6f0a12042ed4802de7da08d63612 100644
--- a/target/s390x/cpu-qom.h
+++ b/target/s390x/cpu-qom.h
@@ -36,6 +36,7 @@ typedef struct S390CPUDef S390CPUDef;
typedef enum cpu_reset_type {
S390_CPU_RESET_NORMAL,
+ S390_CPU_RESET_INITIAL,
} cpu_reset_type;
/**
@@ -62,7 +63,6 @@ typedef struct S390CPUClass {
void (*parent_reset)(CPUState *cpu);
void (*load_normal)(CPUState *cpu);
void (*reset)(CPUState *cpu, cpu_reset_type type);
- void (*initial_cpu_reset)(CPUState *cpu);
} S390CPUClass;
typedef struct S390CPU S390CPU;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 67d6fbfa4401720aa24f2ace8e3c..ca62fe768569b992bbf41b064734 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -94,6 +94,23 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
switch (type) {
+ case S390_CPU_RESET_INITIAL:
+ /* initial reset does not clear everything! */
+ memset(&env->start_initial_reset_fields, 0,
+ offsetof(CPUS390XState, end_reset_fields) -
+ offsetof(CPUS390XState, start_initial_reset_fields));
+
+ /* architectured initial value for Breaking-Event-Address register */
+ env->gbea = 1;
+
+ /* architectured initial values for CR 0 and 14 */
+ env->cregs[0] = CR0_RESET;
+ env->cregs[14] = CR14_RESET;
+
+ /* tininess for underflow is detected before rounding */
+ set_float_detect_tininess(float_tininess_before_rounding,
+ &env->fpu_status);
+ /* fall through */
case S390_CPU_RESET_NORMAL:
env->pfault_token = -1UL;
env->bpbc = false;
@@ -101,35 +118,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
default:
g_assert_not_reached();
}
-}
-
-/* S390CPUClass::initial_reset() */
-static void s390_cpu_initial_reset(CPUState *s)
-{
- S390CPU *cpu = S390_CPU(s);
- CPUS390XState *env = &cpu->env;
-
- s390_cpu_reset(s, S390_CPU_RESET_NORMAL);
- /* initial reset does not clear everything! */
- memset(&env->start_initial_reset_fields, 0,
- offsetof(CPUS390XState, end_reset_fields) -
- offsetof(CPUS390XState, start_initial_reset_fields));
-
- /* architectured initial values for CR 0 and 14 */
- env->cregs[0] = CR0_RESET;
- env->cregs[14] = CR14_RESET;
-
- /* architectured initial value for Breaking-Event-Address register */
- env->gbea = 1;
-
- env->pfault_token = -1UL;
-
- /* tininess for underflow is detected before rounding */
- set_float_detect_tininess(float_tininess_before_rounding,
- &env->fpu_status);
/* Reset state inside the kernel that we cannot access yet from QEMU. */
- if (kvm_enabled()) {
+ if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
kvm_s390_reset_vcpu(cpu);
}
}
@@ -481,7 +472,6 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
scc->load_normal = s390_cpu_load_normal;
#endif
scc->reset = s390_cpu_reset;
- scc->initial_cpu_reset = s390_cpu_initial_reset;
cc->reset = s390_cpu_full_reset;
cc->class_by_name = s390_cpu_class_by_name,
cc->has_work = s390_cpu_has_work;
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 18123dfd5bd13f530fcc3f8c54c4..d2af13b345ccd9094f82385cd528 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -748,7 +748,7 @@ static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
{
S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
- scc->initial_cpu_reset(cs);
+ scc->reset(cs, S390_CPU_RESET_INITIAL);
}
static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index 850139b9cd544c4bb34497fec554..727875bb4ab9b6c6f606e4ba8afb 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -254,7 +254,7 @@ static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
SigpInfo *si = arg.host_ptr;
cpu_synchronize_state(cs);
- scc->initial_cpu_reset(cs);
+ scc->reset(cs, S390_CPU_RESET_INITIAL);
cpu_synchronize_post_reset(cs);
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

View File

@ -0,0 +1,128 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 27 Nov 2019 12:50:42 -0500
Subject: s390x: Move reset normal to shared reset handler
References: bsc#1167075
Let's start moving the cpu reset functions into a single function with
a switch/case, so we can later use fallthroughs and share more code
between resets.
This patch introduces the reset function by renaming cpu_reset().
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20191127175046.4911-3-frankja@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit eac4f82791f1807c423e85670837db103b9d59b3)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/cpu-qom.h | 6 +++++-
target/s390x/cpu.c | 19 +++++++++++++------
target/s390x/cpu.h | 2 +-
target/s390x/sigp.c | 2 +-
4 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
index b809ec8418e016cf8b227489f905..f3b71bac67c91c9e307fa250b47a 100644
--- a/target/s390x/cpu-qom.h
+++ b/target/s390x/cpu-qom.h
@@ -34,6 +34,10 @@
typedef struct S390CPUModel S390CPUModel;
typedef struct S390CPUDef S390CPUDef;
+typedef enum cpu_reset_type {
+ S390_CPU_RESET_NORMAL,
+} cpu_reset_type;
+
/**
* S390CPUClass:
* @parent_realize: The parent class' realize handler.
@@ -57,7 +61,7 @@ typedef struct S390CPUClass {
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
void (*load_normal)(CPUState *cpu);
- void (*cpu_reset)(CPUState *cpu);
+ void (*reset)(CPUState *cpu, cpu_reset_type type);
void (*initial_cpu_reset)(CPUState *cpu);
} S390CPUClass;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 3abe7e80fd0a067a95545c7c3b9b..67d6fbfa4401720aa24f2ace8e3c 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -82,18 +82,25 @@ static void s390_cpu_load_normal(CPUState *s)
}
#endif
-/* S390CPUClass::cpu_reset() */
-static void s390_cpu_reset(CPUState *s)
+/* S390CPUClass::reset() */
+static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
{
S390CPU *cpu = S390_CPU(s);
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
CPUS390XState *env = &cpu->env;
- env->pfault_token = -1UL;
- env->bpbc = false;
scc->parent_reset(s);
cpu->env.sigp_order = 0;
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
+
+ switch (type) {
+ case S390_CPU_RESET_NORMAL:
+ env->pfault_token = -1UL;
+ env->bpbc = false;
+ break;
+ default:
+ g_assert_not_reached();
+ }
}
/* S390CPUClass::initial_reset() */
@@ -102,7 +109,7 @@ static void s390_cpu_initial_reset(CPUState *s)
S390CPU *cpu = S390_CPU(s);
CPUS390XState *env = &cpu->env;
- s390_cpu_reset(s);
+ s390_cpu_reset(s, S390_CPU_RESET_NORMAL);
/* initial reset does not clear everything! */
memset(&env->start_initial_reset_fields, 0,
offsetof(CPUS390XState, end_reset_fields) -
@@ -473,7 +480,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
#if !defined(CONFIG_USER_ONLY)
scc->load_normal = s390_cpu_load_normal;
#endif
- scc->cpu_reset = s390_cpu_reset;
+ scc->reset = s390_cpu_reset;
scc->initial_cpu_reset = s390_cpu_initial_reset;
cc->reset = s390_cpu_full_reset;
cc->class_by_name = s390_cpu_class_by_name,
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 17460ed7b381070b4d8206e2c4cb..18123dfd5bd13f530fcc3f8c54c4 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -741,7 +741,7 @@ static inline void s390_do_cpu_reset(CPUState *cs, run_on_cpu_data arg)
{
S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
- scc->cpu_reset(cs);
+ scc->reset(cs, S390_CPU_RESET_NORMAL);
}
static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index 2ce22d4dc18bb764948f0abe1084..850139b9cd544c4bb34497fec554 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -266,7 +266,7 @@ static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
SigpInfo *si = arg.host_ptr;
cpu_synchronize_state(cs);
- scc->cpu_reset(cs);
+ scc->reset(cs, S390_CPU_RESET_NORMAL);
cpu_synchronize_post_reset(cs);
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
}

View File

@ -0,0 +1,64 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Tue, 10 Mar 2020 05:09:50 -0400
Subject: s390x: ipl: Consolidate iplb validity check into one function
References: bsc#1167075
It's nicer to just call one function than calling a function for each
possible iplb type.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20200310090950.61172-1-frankja@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
(cherry picked from commit 94c21436e5a89143f8b9cb4d089d1a2f3f4fd377)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/s390x/ipl.h | 18 +++++++++---------
target/s390x/diag.c | 2 +-
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index d4813105db33253fd1eba53cd7e3..3e44abe1c651d8a01f4708c2801c 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -173,16 +173,16 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb)
return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
}
-static inline bool iplb_valid_ccw(IplParameterBlock *iplb)
+static inline bool iplb_valid(IplParameterBlock *iplb)
{
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN &&
- iplb->pbt == S390_IPL_TYPE_CCW;
-}
-
-static inline bool iplb_valid_fcp(IplParameterBlock *iplb)
-{
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN &&
- iplb->pbt == S390_IPL_TYPE_FCP;
+ switch (iplb->pbt) {
+ case S390_IPL_TYPE_FCP:
+ return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN;
+ case S390_IPL_TYPE_CCW:
+ return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN;
+ default:
+ return false;
+ }
}
#endif
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 53c2f81f2a1aad58d417bc3dc79c..0c81d8e1efbfe37a384199488a72 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -100,7 +100,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
- if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
+ if (!iplb_valid(iplb)) {
env->regs[r1 + 1] = DIAG_308_RC_INVALID;
goto out;
}

View File

@ -0,0 +1,66 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Fri, 29 Nov 2019 04:17:13 -0500
Subject: s390x: kvm: Make kvm_sclp_service_call void
References: bsc#1167075
It defaults to returning 0 anyway and that return value is not
necessary, as 0 is also the default rc that the caller would return.
While doing that we can simplify the logic a bit and return early if
we inject a PGM exception.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20191129091713.4582-1-frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 15b6c0370c3e2774fd9ffda5c10c6e36952e8eb6)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/kvm.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 0c9d14b4b115de974e21af3f0f47..ad6e38c8761be7e0cad57771f49b 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1159,13 +1159,13 @@ void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code)
kvm_s390_vcpu_interrupt(cpu, &irq);
}
-static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
+static void kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
uint16_t ipbh0)
{
CPUS390XState *env = &cpu->env;
uint64_t sccb;
uint32_t code;
- int r = 0;
+ int r;
sccb = env->regs[ipbh0 & 0xf];
code = env->regs[(ipbh0 & 0xf0) >> 4];
@@ -1173,11 +1173,9 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
r = sclp_service_call(env, sccb, code);
if (r < 0) {
kvm_s390_program_interrupt(cpu, -r);
- } else {
- setcc(cpu, r);
+ return;
}
-
- return 0;
+ setcc(cpu, r);
}
static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
@@ -1240,7 +1238,7 @@ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
setcc(cpu, 3);
break;
case PRIV_B2_SCLP_CALL:
- rc = kvm_sclp_service_call(cpu, run, ipbh0);
+ kvm_sclp_service_call(cpu, run, ipbh0);
break;
default:
rc = -1;

View File

@ -0,0 +1,64 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Fri, 6 Mar 2020 06:40:13 -0500
Subject: s390x: protvirt: Add migration blocker
References: bsc#1167075
Migration is not yet supported.
Signed-off-by: Janosch Frank <frankja@linux.ibm.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 e721e55a3dabb2897081614b17dd4565e85249ac)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/s390x/s390-virtio-ccw.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 5149030d2216040c396a02d977c8..ed910a099627dae96ab5da747fb3 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -44,6 +44,9 @@
#include "sysemu/sysemu.h"
#include "hw/s390x/pv.h"
#include <linux/kvm.h>
+#include "migration/blocker.h"
+
+static Error *pv_mig_blocker;
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
{
@@ -325,15 +328,30 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
{
s390_pv_vm_disable();
ms->pv = false;
+ migrate_del_blocker(pv_mig_blocker);
+ error_free_or_abort(&pv_mig_blocker);
}
static int s390_machine_protect(S390CcwMachineState *ms)
{
+ Error *local_err = NULL;
int rc;
+ error_setg(&pv_mig_blocker,
+ "protected VMs are currently not migrateable.");
+ rc = migrate_add_blocker(pv_mig_blocker, &local_err);
+ if (rc) {
+ error_report_err(local_err);
+ error_free_or_abort(&pv_mig_blocker);
+ return rc;
+ }
+
/* Create SE VM */
rc = s390_pv_vm_enable();
if (rc) {
+ error_report_err(local_err);
+ migrate_del_blocker(pv_mig_blocker);
+ error_free_or_abort(&pv_mig_blocker);
return rc;
}

View File

@ -0,0 +1,119 @@
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 c437a1d8c6afed80199034ab6f6a..bbcccf6be23456393282287bf116 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);

View File

@ -0,0 +1,44 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Tue, 6 Aug 2019 15:40:05 +0200
Subject: s390x: protvirt: Handle SIGP store status correctly
References: bsc#1167075
For protected VMs status storing is not done by QEMU anymore.
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 398fc6874438c320407449d1c9560925aba2280b)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/helper.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index 6808dfda01f42acbaa1d36ef787b..36b6d3d9d1bca9db90aac1c7bec6 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -25,6 +25,7 @@
#include "qemu/timer.h"
#include "qemu/qemu-print.h"
#include "hw/s390x/ioinst.h"
+#include "hw/s390x/pv.h"
#include "sysemu/hw_accel.h"
#include "sysemu/runstate.h"
#ifndef CONFIG_USER_ONLY
@@ -246,6 +247,11 @@ int s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch)
hwaddr len = sizeof(*sa);
int i;
+ /* For PVMs storing will occur when this cpu enters SIE again */
+ if (s390_is_pv()) {
+ return 0;
+ }
+
sa = cpu_physical_memory_map(addr, &len, 1);
if (!sa) {
return -EFAULT;

View File

@ -0,0 +1,84 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Mon, 24 Feb 2020 07:49:06 -0500
Subject: s390x: protvirt: Inhibit balloon when switching to protected mode
References: bsc#1167075
Ballooning in protected VMs can only be done when the guest shares the
pages it gives to the host. If pages are not shared, the integrity
checks will fail once those pages have been altered and are given back
to the guest.
As we currently do not yet have a solution for this we will continue
like this:
1. We block ballooning now in QEMU (with this patch).
2. Later we will provide a change to virtio that removes the blocker
and adds VIRTIO_F_IOMMU_PLATFORM automatically by QEMU when doing the
protvirt switch. This is OK, as the balloon driver in Linux (the only
supported guest) will refuse to work with the IOMMU_PLATFORM feature
bit set.
3. Later, we can fix the guest balloon driver to accept the IOMMU
feature bit and correctly exercise sharing and unsharing of balloon
pages.
Signed-off-by: Janosch Frank <frankja@linux.ibm.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 59dc32a3494d6afdd420f3e401f1f324a1179256)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/s390x/s390-virtio-ccw.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index ed910a099627dae96ab5da747fb3..85250bf046ed72313b03c6ff6c54 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -42,6 +42,7 @@
#include "hw/qdev-properties.h"
#include "hw/s390x/tod.h"
#include "sysemu/sysemu.h"
+#include "sysemu/balloon.h"
#include "hw/s390x/pv.h"
#include <linux/kvm.h>
#include "migration/blocker.h"
@@ -330,6 +331,7 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
ms->pv = false;
migrate_del_blocker(pv_mig_blocker);
error_free_or_abort(&pv_mig_blocker);
+ qemu_balloon_inhibit(false);
}
static int s390_machine_protect(S390CcwMachineState *ms)
@@ -337,10 +339,18 @@ static int s390_machine_protect(S390CcwMachineState *ms)
Error *local_err = NULL;
int rc;
+ /*
+ * Ballooning on protected VMs needs support in the guest for
+ * sharing and unsharing balloon pages. Block ballooning for
+ * now, until we have a solution to make at least Linux guests
+ * either support it or fail gracefully.
+ */
+ qemu_balloon_inhibit(true);
error_setg(&pv_mig_blocker,
"protected VMs are currently not migrateable.");
rc = migrate_add_blocker(pv_mig_blocker, &local_err);
if (rc) {
+ qemu_balloon_inhibit(false);
error_report_err(local_err);
error_free_or_abort(&pv_mig_blocker);
return rc;
@@ -349,6 +359,7 @@ static int s390_machine_protect(S390CcwMachineState *ms)
/* Create SE VM */
rc = s390_pv_vm_enable();
if (rc) {
+ qemu_balloon_inhibit(false);
error_report_err(local_err);
migrate_del_blocker(pv_mig_blocker);
error_free_or_abort(&pv_mig_blocker);

View File

@ -0,0 +1,60 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Mon, 13 May 2019 10:35:27 +0200
Subject: s390x: protvirt: KVM intercept changes
References: bsc#1167075
Protected VMs no longer intercept with code 4 for an instruction
interception. Instead they have codes 104 and 108 for protected
instruction interception and protected instruction notification
respectively.
The 104 mirrors the 4 interception.
The 108 is a notification interception to let KVM and QEMU know that
something changed and we need to update tracking information or
perform specific tasks. It's currently taken for the following
instructions:
* spx (To inform about the changed prefix location)
* sclp (On incorrect SCCB values, so we can inject a IRQ)
* sigp (All but "stop and store status")
* diag308 (Subcodes 0/1)
Of these exits only sclp errors, state changing sigps and diag308 will
reach QEMU. QEMU will do its parts of the job, while the ultravisor
has done the instruction part of the job.
Signed-off-by: Janosch Frank <frankja@linux.ibm.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 fd70eb764f176c200d6723c2ad88362f23536bfa)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/kvm.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index d8d02ff34f4fc942cb7935deec58..abeeaaa67452b0b938557b0d0dea 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -115,6 +115,8 @@
#define ICPT_CPU_STOP 0x28
#define ICPT_OPEREXC 0x2c
#define ICPT_IO 0x40
+#define ICPT_PV_INSTR 0x68
+#define ICPT_PV_INSTR_NOTIFICATION 0x6c
#define NR_LOCAL_IRQS 32
/*
@@ -1695,6 +1697,8 @@ static int handle_intercept(S390CPU *cpu)
(long)cs->kvm_run->psw_addr);
switch (icpt_code) {
case ICPT_INSTRUCTION:
+ case ICPT_PV_INSTR:
+ case ICPT_PV_INSTR_NOTIFICATION:
r = handle_instruction(cpu, run);
break;
case ICPT_PROGRAM:

View File

@ -0,0 +1,156 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 5 Feb 2020 07:02:33 -0500
Subject: s390x: protvirt: Move IO control structures over SIDA
References: bsc#1167075
For protected guests, we need to put the IO emulation results into the
SIDA, so SIE will write them into the guest at the next entry.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 4989e18cbe5621df39020ef812316f479d8f5246)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/ioinst.c | 61 +++++++++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 16 deletions(-)
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index bbcccf6be23456393282287bf116..f40c35c6ff58315622510ae72103 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -138,7 +138,9 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
return;
}
- if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib));
+ } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return;
}
@@ -195,7 +197,9 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
return;
}
- if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb));
+ } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return;
}
@@ -231,14 +235,19 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
cc = css_do_stcrw(&crw);
/* 0 - crw stored, 1 - zeroes stored */
- if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw));
setcc(cpu, cc);
} else {
- if (cc == 0) {
- /* Write failed: requeue CRW since STCRW is suppressing */
- css_undo_stcrw(&crw);
+ if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
+ setcc(cpu, cc);
+ } else {
+ if (cc == 0) {
+ /* Write failed: requeue CRW since STCRW is suppressing */
+ css_undo_stcrw(&crw);
+ }
+ s390_cpu_virt_mem_handle_exc(cpu, ra);
}
- s390_cpu_virt_mem_handle_exc(cpu, ra);
}
}
@@ -260,6 +269,13 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
}
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
+ /*
+ * The Ultravisor checks schid bit 16 to be one and bits 0-12
+ * to be 0 and injects a operand exception itself.
+ *
+ * Hence we should never end up here.
+ */
+ g_assert(!s390_is_pv());
/*
* As operand exceptions have a lower priority than access exceptions,
* we check whether the memory area is writeable (injecting the
@@ -292,14 +308,17 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
}
}
if (cc != 3) {
- if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
- sizeof(schib)) != 0) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib));
+ } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
+ sizeof(schib)) != 0) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return;
}
} else {
/* Access exceptions have a higher priority than cc3 */
- if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
+ if (!s390_is_pv() &&
+ s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return;
}
@@ -336,7 +355,9 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
}
/* 0 - status pending, 1 - not status pending, 3 - not operational */
if (cc != 3) {
- if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len);
+ } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return -EFAULT;
}
@@ -344,7 +365,8 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
} else {
irb_len = sizeof(irb) - sizeof(irb.emw);
/* Access exceptions have a higher priority than cc3 */
- if (s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
+ if (!s390_is_pv() &&
+ s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return -EFAULT;
}
@@ -642,7 +664,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
* present CHSC sub-handlers ... if we ever need more, we should take
* care of req->len here first.
*/
- if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_read(cpu, addr, buf, sizeof(ChscReq));
+ } else if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
s390_cpu_virt_mem_handle_exc(cpu, ra);
return;
}
@@ -675,11 +699,16 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
break;
}
- if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
- be16_to_cpu(res->len))) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_write(cpu, addr + len, res, be16_to_cpu(res->len));
setcc(cpu, 0); /* Command execution complete */
} else {
- s390_cpu_virt_mem_handle_exc(cpu, ra);
+ if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
+ be16_to_cpu(res->len))) {
+ setcc(cpu, 0); /* Command execution complete */
+ } else {
+ s390_cpu_virt_mem_handle_exc(cpu, ra);
+ }
}
}

View File

@ -0,0 +1,55 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 5 Feb 2020 07:02:51 -0500
Subject: s390x: protvirt: Move STSI data over SIDAD
References: bsc#1167075
For protected guests, we need to put the STSI emulation results into
the SIDA, so SIE will write them into the guest at the next entry.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit ccce7a654911ae507c962aff5f41004a7a88fad6)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/kvm.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 941e4df630ad9b3dc780d3c92e6b..d00e05cc10d274790a215d0f4359 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -50,6 +50,7 @@
#include "exec/memattrs.h"
#include "hw/s390x/s390-virtio-ccw.h"
#include "hw/s390x/s390-virtio-hcall.h"
+#include "hw/s390x/pv.h"
#ifndef DEBUG_KVM
#define DEBUG_KVM 0
@@ -1803,7 +1804,9 @@ static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, uint8_t ar)
SysIB_322 sysib;
int del;
- if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_read(cpu, 0, &sysib, sizeof(sysib));
+ } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
return;
}
/* Shift the stack of Extended Names to prepare for our own data */
@@ -1843,7 +1846,11 @@ static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, uint8_t ar)
/* Insert UUID */
memcpy(sysib.vm[0].uuid, &qemu_uuid, sizeof(sysib.vm[0].uuid));
- s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
+ if (s390_is_pv()) {
+ s390_cpu_pv_mem_write(cpu, 0, &sysib, sizeof(sysib));
+ } else {
+ s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
+ }
}
static int handle_stsi(S390CPU *cpu)

View File

@ -0,0 +1,78 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Wed, 31 Jul 2019 17:49:08 +0200
Subject: s390x: protvirt: Move diag 308 data over SIDA
References: bsc#1167075
For protected guests the IPIB is written/read to/from the SIDA, so we
need those accesses to go through s390_cpu_pv_mem_read/write().
Signed-off-by: Janosch Frank <frankja@linux.ibm.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 258da1c7736d3aa4604ceea6cce00995c6f30058)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/diag.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index b2cbefb8cfe4e5a244219e761fb4..1a4842956402e308426c0ed5ce5c 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -75,6 +75,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
{
bool valid;
CPUState *cs = env_cpu(env);
+ S390CPU *cpu = S390_CPU(cs);
uint64_t addr = env->regs[r1];
uint64_t subcode = env->regs[r3];
IplParameterBlock *iplb;
@@ -111,13 +112,22 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
return;
}
iplb = g_new0(IplParameterBlock, 1);
- cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
+ if (!s390_is_pv()) {
+ cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
+ } else {
+ s390_cpu_pv_mem_read(cpu, 0, iplb, sizeof(iplb->len));
+ }
+
if (!iplb_valid_len(iplb)) {
env->regs[r1 + 1] = DIAG_308_RC_INVALID;
goto out;
}
- cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
+ if (!s390_is_pv()) {
+ cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
+ } else {
+ s390_cpu_pv_mem_read(cpu, 0, iplb, be32_to_cpu(iplb->len));
+ }
valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb);
if (!valid) {
@@ -140,12 +150,17 @@ out:
} else {
iplb = s390_ipl_get_iplb();
}
- if (iplb) {
+ if (!iplb) {
+ env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
+ return;
+ }
+
+ if (!s390_is_pv()) {
cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
- env->regs[r1 + 1] = DIAG_308_RC_OK;
} else {
- env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
+ s390_cpu_pv_mem_write(cpu, 0, iplb, be32_to_cpu(iplb->len));
}
+ env->regs[r1 + 1] = DIAG_308_RC_OK;
return;
case DIAG308_PV_START:
iplb = s390_ipl_get_iplb_pv();

View File

@ -0,0 +1,156 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Mon, 3 Jun 2019 16:40:29 +0200
Subject: s390x: protvirt: SCLP interpretation
References: bsc#1167075
SCLP for a protected guest is done over the SIDAD, so we need to use
the s390_cpu_pv_mem_* functions to access the SIDAD instead of guest
memory when reading/writing SCBs.
To not confuse the sclp emulation, we set 0x4000 as the SCCB address,
since the function that injects the sclp external interrupt would
reject a zero sccb address.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 32633cf4539341180dbc7a92c2655c711b4a6996)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/s390x/sclp.c | 56 +++++++++++++++++++++++++++++++++--------
include/hw/s390x/sclp.h | 2 ++
target/s390x/kvm.c | 25 ++++++++++++++----
3 files changed, 67 insertions(+), 16 deletions(-)
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index f57ce7b73943564f4d44dcbe0cf0..1c380a49cc7140687329e43e9745 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -33,6 +33,22 @@ static inline SCLPDevice *get_sclp_device(void)
return sclp;
}
+static inline bool sclp_command_code_valid(uint32_t code)
+{
+ switch (code & SCLP_CMD_CODE_MASK) {
+ case SCLP_CMDW_READ_SCP_INFO:
+ case SCLP_CMDW_READ_SCP_INFO_FORCED:
+ case SCLP_CMDW_READ_CPU_INFO:
+ case SCLP_CMDW_CONFIGURE_IOA:
+ case SCLP_CMDW_DECONFIGURE_IOA:
+ case SCLP_CMD_READ_EVENT_DATA:
+ case SCLP_CMD_WRITE_EVENT_DATA:
+ case SCLP_CMD_WRITE_EVENT_MASK:
+ return true;
+ }
+ return false;
+}
+
static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
{
MachineState *ms = MACHINE(qdev_get_machine());
@@ -193,6 +209,34 @@ static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
}
}
+/*
+ * We only need the address to have something valid for the
+ * service_interrupt call.
+ */
+#define SCLP_PV_DUMMY_ADDR 0x4000
+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);
+
+ s390_cpu_pv_mem_read(env_archcpu(env), 0, &work_sccb, sccb_len);
+
+ if (!sclp_command_code_valid(code)) {
+ work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+ goto out_write;
+ }
+
+ sclp_c->execute(sclp, &work_sccb, code);
+out_write:
+ s390_cpu_pv_mem_write(env_archcpu(env), 0, &work_sccb,
+ be16_to_cpu(work_sccb.h.length));
+ sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
+ return 0;
+}
+
int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
{
SCLPDevice *sclp = get_sclp_device();
@@ -230,17 +274,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
goto out;
}
- switch (code & SCLP_CMD_CODE_MASK) {
- case SCLP_CMDW_READ_SCP_INFO:
- case SCLP_CMDW_READ_SCP_INFO_FORCED:
- case SCLP_CMDW_READ_CPU_INFO:
- case SCLP_CMDW_CONFIGURE_IOA:
- case SCLP_CMDW_DECONFIGURE_IOA:
- case SCLP_CMD_READ_EVENT_DATA:
- case SCLP_CMD_WRITE_EVENT_DATA:
- case SCLP_CMD_WRITE_EVENT_MASK:
- break;
- default:
+ if (!sclp_command_code_valid(code)) {
work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
goto out_write;
}
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index c54413b78cf01b274cc249b1409b..c0a3faa37d7304536e75d32f2050 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 d00e05cc10d274790a215d0f4359..d94b915da419c3ad0a1f9622ca13 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1230,12 +1230,27 @@ static void 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);
- if (r < 0) {
- kvm_s390_program_interrupt(cpu, -r);
- return;
+ switch (run->s390_sieic.icptcode) {
+ case ICPT_PV_INSTR_NOTIFICATION:
+ g_assert(s390_is_pv());
+ /* The notification intercepts are currently handled by KVM */
+ error_report("unexpected SCLP PV notification");
+ exit(1);
+ break;
+ case ICPT_PV_INSTR:
+ g_assert(s390_is_pv());
+ sclp_service_call_protected(env, sccb, code);
+ /* Setting the CC is done by the Ultravisor. */
+ break;
+ case ICPT_INSTRUCTION:
+ g_assert(!s390_is_pv());
+ r = sclp_service_call(env, sccb, code);
+ if (r < 0) {
+ kvm_s390_program_interrupt(cpu, -r);
+ return;
+ }
+ setcc(cpu, r);
}
- setcc(cpu, r);
}
static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)

View File

@ -0,0 +1,45 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Tue, 23 Jul 2019 13:17:32 +0200
Subject: s390x: protvirt: Set guest IPL PSW
References: bsc#1167075
Handling of CPU reset and setting of the IPL psw from guest storage at
offset 0 is done by a Ultravisor call. Let's only fetch it if
necessary.
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 e8686d9849f1625f4f4b28403f0555181b72d1b6)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/s390x/cpu.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 479f1978c974722ceeb72ac5fb32..6da0c3f15530310fba5f609b8c7f 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -77,8 +77,16 @@ static bool s390_cpu_has_work(CPUState *cs)
static void s390_cpu_load_normal(CPUState *s)
{
S390CPU *cpu = S390_CPU(s);
- cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR;
- cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
+ if (!s390_is_pv()) {
+ cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR;
+ cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
+ } else {
+ /*
+ * Firmware requires us to set the load state before we set
+ * the cpu to operating on protected guests.
+ */
+ s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
+ }
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
}
#endif

View File

@ -0,0 +1,868 @@
From: Janosch Frank <frankja@linux.ibm.com>
Date: Mon, 11 Feb 2019 16:07:19 +0100
Subject: s390x: protvirt: Support unpack facility
References: bsc#1167075
The unpack facility provides the means to setup a protected guest. A
protected guest cannot be introspected by the hypervisor or any
user/administrator of the machine it is running on.
Protected guests are encrypted at rest and need a special boot
mechanism via diag308 subcode 8 and 10.
Code 8 sets the PV specific IPLB which is retained separately from
those set via code 5.
Code 10 is used to unpack the VM into protected memory, verify its
integrity and start it.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Co-developed-by: Christian Borntraeger <borntraeger@de.ibm.com> [Changes
to machine]
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 2150c92b9b7d12b5fbdd2c59e5b17197d28f53db)
[BR: Needed to fix a compiler warning on i586 in hw/s390x/ipl.c]
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
MAINTAINERS | 2 +
hw/s390x/Makefile.objs | 1 +
hw/s390x/ipl.c | 59 +++++++++++++-
hw/s390x/ipl.h | 91 ++++++++++++++++++++-
hw/s390x/pv.c | 98 +++++++++++++++++++++++
hw/s390x/s390-virtio-ccw.c | 119 +++++++++++++++++++++++++++-
include/hw/s390x/pv.h | 55 +++++++++++++
include/hw/s390x/s390-virtio-ccw.h | 1 +
target/s390x/cpu.c | 1 +
target/s390x/cpu_features_def.inc.h | 1 +
target/s390x/diag.c | 39 ++++++++-
target/s390x/kvm-stub.c | 5 ++
target/s390x/kvm.c | 5 ++
target/s390x/kvm_s390x.h | 1 +
14 files changed, 468 insertions(+), 10 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 5e5e3e52d614d05e7d6e8225e3b7..1dbe9345a022a25b7b40a5b5e9c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -385,6 +385,8 @@ F: target/s390x/machine.c
F: target/s390x/sigp.c
F: target/s390x/cpu_features*.[ch]
F: target/s390x/cpu_models.[ch]
+F: hw/s390x/pv.c
+F: include/hw/s390x/pv.h
F: hw/intc/s390_flic.c
F: hw/intc/s390_flic_kvm.c
F: include/hw/s390x/s390_flic.h
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index e02ed80b6829a511362abc3525ec..a46a1c7894e0f612a2d74cec74f6 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -31,6 +31,7 @@ obj-y += tod-qemu.o
obj-$(CONFIG_KVM) += tod-kvm.o
obj-$(CONFIG_KVM) += s390-skeys-kvm.o
obj-$(CONFIG_KVM) += s390-stattrib-kvm.o
+obj-$(CONFIG_KVM) += pv.o
obj-y += s390-ccw.o
obj-y += ap-device.o
obj-y += ap-bridge.o
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index ca544d64c5e04782fb49d12521d5..73e5210b4d4e7ad912cfe5475ac4 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -1,10 +1,11 @@
/*
* bootloader support
*
- * Copyright IBM, Corp. 2012
+ * Copyright IBM, Corp. 2012, 2020
*
* Authors:
* Christian Borntraeger <borntraeger@de.ibm.com>
+ * Janosch Frank <frankja@linux.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at your
* option) any later version. See the COPYING file in the top-level directory.
@@ -27,6 +28,7 @@
#include "hw/s390x/vfio-ccw.h"
#include "hw/s390x/css.h"
#include "hw/s390x/ebcdic.h"
+#include "hw/s390x/pv.h"
#include "ipl.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
@@ -533,11 +535,30 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
{
S390IPLState *ipl = get_ipl_device();
- ipl->iplb = *iplb;
- ipl->iplb_valid = true;
+ /*
+ * The IPLB set and retrieved by subcodes 8/9 is completely
+ * separate from the one managed via subcodes 5/6.
+ */
+ if (iplb->pbt == S390_IPL_TYPE_PV) {
+ ipl->iplb_pv = *iplb;
+ ipl->iplb_valid_pv = true;
+ } else {
+ ipl->iplb = *iplb;
+ ipl->iplb_valid = true;
+ }
ipl->netboot = is_virtio_net_device(iplb);
}
+IplParameterBlock *s390_ipl_get_iplb_pv(void)
+{
+ S390IPLState *ipl = get_ipl_device();
+
+ if (!ipl->iplb_valid_pv) {
+ return NULL;
+ }
+ return &ipl->iplb_pv;
+}
+
IplParameterBlock *s390_ipl_get_iplb(void)
{
S390IPLState *ipl = get_ipl_device();
@@ -626,6 +647,38 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu)
cpu_physical_memory_unmap(addr, len, 1, len);
}
+int s390_ipl_prepare_pv_header(void)
+{
+ IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
+ IPLBlockPV *ipib_pv = &ipib->pv;
+ void *hdr = g_malloc(ipib_pv->pv_header_len);
+ int rc;
+
+ cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr,
+ ipib_pv->pv_header_len);
+ rc = s390_pv_set_sec_parms((uint64_t)(uintptr_t)hdr,
+ ipib_pv->pv_header_len);
+ g_free(hdr);
+ return rc;
+}
+
+int s390_ipl_pv_unpack(void)
+{
+ IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
+ IPLBlockPV *ipib_pv = &ipib->pv;
+ int i, rc = 0;
+
+ for (i = 0; i < ipib_pv->num_comp; i++) {
+ rc = s390_pv_unpack(ipib_pv->components[i].addr,
+ TARGET_PAGE_ALIGN(ipib_pv->components[i].size),
+ ipib_pv->components[i].tweak_pref);
+ if (rc) {
+ break;
+ }
+ }
+ return rc;
+}
+
void s390_ipl_prepare_cpu(S390CPU *cpu)
{
S390IPLState *ipl = get_ipl_device();
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index a5665e6bfde2e8cfbb1b2e6c7234..89b3044d7a2ee54014daa8eeafc9 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -1,8 +1,9 @@
/*
* s390 IPL device
*
- * Copyright 2015 IBM Corp.
+ * Copyright 2015, 2020 IBM Corp.
* Author(s): Zhang Fan <bjfanzh@cn.ibm.com>
+ * Janosch Frank <frankja@linux.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
@@ -15,6 +16,24 @@
#include "cpu.h"
#include "hw/qdev-core.h"
+struct IPLBlockPVComp {
+ uint64_t tweak_pref;
+ uint64_t addr;
+ uint64_t size;
+} QEMU_PACKED;
+typedef struct IPLBlockPVComp IPLBlockPVComp;
+
+struct IPLBlockPV {
+ uint8_t reserved18[87]; /* 0x18 */
+ uint8_t version; /* 0x6f */
+ uint32_t reserved70; /* 0x70 */
+ uint32_t num_comp; /* 0x74 */
+ uint64_t pv_header_addr; /* 0x78 */
+ uint64_t pv_header_len; /* 0x80 */
+ struct IPLBlockPVComp components[];
+} QEMU_PACKED;
+typedef struct IPLBlockPV IPLBlockPV;
+
struct IplBlockCcw {
uint8_t reserved0[85];
uint8_t ssid;
@@ -71,6 +90,7 @@ union IplParameterBlock {
union {
IplBlockCcw ccw;
IplBlockFcp fcp;
+ IPLBlockPV pv;
IplBlockQemuScsi scsi;
};
} QEMU_PACKED;
@@ -85,8 +105,11 @@ typedef union IplParameterBlock IplParameterBlock;
int s390_ipl_set_loadparm(uint8_t *loadparm);
void s390_ipl_update_diag308(IplParameterBlock *iplb);
+int s390_ipl_prepare_pv_header(void);
+int s390_ipl_pv_unpack(void);
void s390_ipl_prepare_cpu(S390CPU *cpu);
IplParameterBlock *s390_ipl_get_iplb(void);
+IplParameterBlock *s390_ipl_get_iplb_pv(void);
enum s390_reset {
/* default is a reset not triggered by a CPU e.g. issued by QMP */
@@ -94,6 +117,7 @@ enum s390_reset {
S390_RESET_REIPL,
S390_RESET_MODIFIED_CLEAR,
S390_RESET_LOAD_NORMAL,
+ S390_RESET_PV,
};
void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type);
void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type);
@@ -133,6 +157,7 @@ struct S390IPLState {
/*< private >*/
DeviceState parent_obj;
IplParameterBlock iplb;
+ IplParameterBlock iplb_pv;
QemuIplParameters qipl;
uint64_t start_addr;
uint64_t compat_start_addr;
@@ -140,6 +165,7 @@ struct S390IPLState {
uint64_t compat_bios_start_addr;
bool enforce_bios;
bool iplb_valid;
+ bool iplb_valid_pv;
bool netboot;
/* reset related properties don't have to be migrated or reset */
enum s390_reset reset_type;
@@ -162,6 +188,8 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
#define DIAG_308_RC_OK 0x0001
#define DIAG_308_RC_NO_CONF 0x0102
#define DIAG_308_RC_INVALID 0x0402
+#define DIAG_308_RC_NO_PV_CONF 0x0902
+#define DIAG_308_RC_INVAL_FOR_PV 0x0a02
#define DIAG308_RESET_MOD_CLR 0
#define DIAG308_RESET_LOAD_NORM 1
@@ -169,12 +197,17 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
#define DIAG308_LOAD_NORMAL_DUMP 4
#define DIAG308_SET 5
#define DIAG308_STORE 6
+#define DIAG308_PV_SET 8
+#define DIAG308_PV_STORE 9
+#define DIAG308_PV_START 10
#define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02
+#define S390_IPL_TYPE_PV 0x05
#define S390_IPL_TYPE_QEMU_SCSI 0xff
#define S390_IPLB_HEADER_LEN 8
+#define S390_IPLB_MIN_PV_LEN 148
#define S390_IPLB_MIN_CCW_LEN 200
#define S390_IPLB_MIN_FCP_LEN 384
#define S390_IPLB_MIN_QEMU_SCSI_LEN 200
@@ -184,6 +217,62 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb)
return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
}
+static inline bool ipl_valid_pv_components(IplParameterBlock *iplb)
+{
+ IPLBlockPV *ipib_pv = &iplb->pv;
+ int i;
+
+ if (ipib_pv->num_comp == 0) {
+ return false;
+ }
+
+ for (i = 0; i < ipib_pv->num_comp; i++) {
+ /* Addr must be 4k aligned */
+ if (ipib_pv->components[i].addr & ~TARGET_PAGE_MASK) {
+ return false;
+ }
+
+ /* Tweak prefix is monotonically increasing with each component */
+ if (i < ipib_pv->num_comp - 1 &&
+ ipib_pv->components[i].tweak_pref >=
+ ipib_pv->components[i + 1].tweak_pref) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static inline bool ipl_valid_pv_header(IplParameterBlock *iplb)
+{
+ IPLBlockPV *ipib_pv = &iplb->pv;
+
+ if (ipib_pv->pv_header_len > 2 * TARGET_PAGE_SIZE) {
+ return false;
+ }
+
+ if (!address_space_access_valid(&address_space_memory,
+ ipib_pv->pv_header_addr,
+ ipib_pv->pv_header_len,
+ false,
+ MEMTXATTRS_UNSPECIFIED)) {
+ return false;
+ }
+
+ return true;
+}
+
+static inline bool iplb_valid_pv(IplParameterBlock *iplb)
+{
+ if (iplb->pbt != S390_IPL_TYPE_PV ||
+ be32_to_cpu(iplb->len) < S390_IPLB_MIN_PV_LEN) {
+ return false;
+ }
+ if (!ipl_valid_pv_header(iplb)) {
+ return false;
+ }
+ return ipl_valid_pv_components(iplb);
+}
+
static inline bool iplb_valid(IplParameterBlock *iplb)
{
switch (iplb->pbt) {
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
new file mode 100644
index 0000000000000000000000000000000000000000..8cf5cd2c9bcd48b03af1e546fb3a85cdc7ac28bb
--- /dev/null
+++ b/hw/s390x/pv.c
@@ -0,0 +1,98 @@
+/*
+ * Protected Virtualization functions
+ *
+ * Copyright IBM Corp. 2020
+ * Author(s):
+ * Janosch Frank <frankja@linux.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#include "qemu/osdep.h"
+
+#include <linux/kvm.h>
+
+#include "qemu/error-report.h"
+#include "sysemu/kvm.h"
+#include "hw/s390x/pv.h"
+
+static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
+{
+ struct kvm_pv_cmd pv_cmd = {
+ .cmd = cmd,
+ .data = (uint64_t)data,
+ };
+ int rc = kvm_vm_ioctl(kvm_state, KVM_S390_PV_COMMAND, &pv_cmd);
+
+ if (rc) {
+ error_report("KVM PV command %d (%s) failed: header rc %x rrc %x "
+ "IOCTL rc: %d", cmd, cmdname, pv_cmd.rc, pv_cmd.rrc,
+ rc);
+ }
+ return rc;
+}
+
+/*
+ * This macro lets us pass the command as a string to the function so
+ * we can print it on an error.
+ */
+#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data);
+#define s390_pv_cmd_exit(cmd, data) \
+{ \
+ int rc; \
+ \
+ rc = __s390_pv_cmd(cmd, #cmd, data);\
+ if (rc) { \
+ exit(1); \
+ } \
+}
+
+int s390_pv_vm_enable(void)
+{
+ return s390_pv_cmd(KVM_PV_ENABLE, NULL);
+}
+
+void s390_pv_vm_disable(void)
+{
+ s390_pv_cmd_exit(KVM_PV_DISABLE, NULL);
+}
+
+int s390_pv_set_sec_parms(uint64_t origin, uint64_t length)
+{
+ struct kvm_s390_pv_sec_parm args = {
+ .origin = origin,
+ .length = length,
+ };
+
+ return s390_pv_cmd(KVM_PV_VM_SET_SEC_PARMS, &args);
+}
+
+/*
+ * Called for each component in the SE type IPL parameter block 0.
+ */
+int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak)
+{
+ struct kvm_s390_pv_unp args = {
+ .addr = addr,
+ .size = size,
+ .tweak = tweak,
+ };
+
+ return s390_pv_cmd(KVM_PV_VM_UNPACK, &args);
+}
+
+void s390_pv_perf_clear_reset(void)
+{
+ s390_pv_cmd_exit(KVM_PV_VM_PREP_RESET, NULL);
+}
+
+int s390_pv_verify(void)
+{
+ return s390_pv_cmd(KVM_PV_VM_VERIFY, NULL);
+}
+
+void s390_pv_unshare(void)
+{
+ s390_pv_cmd_exit(KVM_PV_VM_UNSHARE_ALL, NULL);
+}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index c1d1440272a42eef86eb14724f52..5149030d2216040c396a02d977c8 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1,9 +1,10 @@
/*
* virtio ccw machine
*
- * Copyright 2012 IBM Corp.
+ * Copyright 2012, 2020 IBM Corp.
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ * Janosch Frank <frankja@linux.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
@@ -41,6 +42,8 @@
#include "hw/qdev-properties.h"
#include "hw/s390x/tod.h"
#include "sysemu/sysemu.h"
+#include "hw/s390x/pv.h"
+#include <linux/kvm.h>
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
{
@@ -318,10 +321,78 @@ static inline void s390_do_cpu_ipl(CPUState *cs, run_on_cpu_data arg)
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
}
+static void s390_machine_unprotect(S390CcwMachineState *ms)
+{
+ s390_pv_vm_disable();
+ ms->pv = false;
+}
+
+static int s390_machine_protect(S390CcwMachineState *ms)
+{
+ int rc;
+
+ /* Create SE VM */
+ rc = s390_pv_vm_enable();
+ if (rc) {
+ return rc;
+ }
+
+ ms->pv = true;
+
+ /* Set SE header and unpack */
+ rc = s390_ipl_prepare_pv_header();
+ if (rc) {
+ goto out_err;
+ }
+
+ /* Decrypt image */
+ rc = s390_ipl_pv_unpack();
+ if (rc) {
+ goto out_err;
+ }
+
+ /* Verify integrity */
+ rc = s390_pv_verify();
+ if (rc) {
+ goto out_err;
+ }
+ return rc;
+
+out_err:
+ s390_machine_unprotect(ms);
+ return rc;
+}
+
+static void s390_machine_inject_pv_error(CPUState *cs)
+{
+ int r1 = (cs->kvm_run->s390_sieic.ipa & 0x00f0) >> 4;
+ CPUS390XState *env = &S390_CPU(cs)->env;
+
+ /* Report that we are unable to enter protected mode */
+ env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
+}
+
+static void s390_pv_prepare_reset(S390CcwMachineState *ms)
+{
+ CPUState *cs;
+
+ if (!s390_is_pv()) {
+ return;
+ }
+ /* Unsharing requires all cpus to be stopped */
+ CPU_FOREACH(cs) {
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs));
+ }
+ s390_pv_unshare();
+ s390_pv_perf_clear_reset();
+}
+
static void s390_machine_reset(MachineState *machine)
{
+ S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
enum s390_reset reset_type;
CPUState *cs, *t;
+ S390CPU *cpu;
/* get the reset parameters, reset them once done */
s390_ipl_get_reset_request(&cs, &reset_type);
@@ -329,9 +400,15 @@ static void s390_machine_reset(MachineState *machine)
/* all CPUs are paused and synchronized at this point */
s390_cmma_reset();
+ cpu = S390_CPU(cs);
+
switch (reset_type) {
case S390_RESET_EXTERNAL:
case S390_RESET_REIPL:
+ if (s390_is_pv()) {
+ s390_machine_unprotect(ms);
+ }
+
qemu_devices_reset();
s390_crypto_reset();
@@ -339,22 +416,56 @@ static void s390_machine_reset(MachineState *machine)
run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
break;
case S390_RESET_MODIFIED_CLEAR:
+ /*
+ * Susbsystem reset needs to be done before we unshare memory
+ * and lose access to VIRTIO structures in guest memory.
+ */
+ subsystem_reset();
+ s390_crypto_reset();
+ s390_pv_prepare_reset(ms);
CPU_FOREACH(t) {
run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
}
- subsystem_reset();
- s390_crypto_reset();
run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
break;
case S390_RESET_LOAD_NORMAL:
+ /*
+ * Susbsystem reset needs to be done before we unshare memory
+ * and lose access to VIRTIO structures in guest memory.
+ */
+ subsystem_reset();
+ s390_pv_prepare_reset(ms);
CPU_FOREACH(t) {
if (t == cs) {
continue;
}
run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
}
- subsystem_reset();
run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL);
+ run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
+ break;
+ case S390_RESET_PV: /* Subcode 10 */
+ subsystem_reset();
+ s390_crypto_reset();
+
+ CPU_FOREACH(t) {
+ if (t == cs) {
+ continue;
+ }
+ run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
+ }
+ run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL);
+
+ if (s390_machine_protect(ms)) {
+ s390_machine_inject_pv_error(cs);
+ /*
+ * Continue after the diag308 so the guest knows something
+ * went wrong.
+ */
+ s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
+ return;
+ }
+
run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
break;
default:
diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6cb360f2f6a0a32a37970769e1bf2eb0220b199
--- /dev/null
+++ b/include/hw/s390x/pv.h
@@ -0,0 +1,55 @@
+/*
+ * Protected Virtualization header
+ *
+ * Copyright IBM Corp. 2020
+ * Author(s):
+ * Janosch Frank <frankja@linux.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#ifndef HW_S390_PV_H
+#define HW_S390_PV_H
+
+#ifdef CONFIG_KVM
+#include "hw/s390x/s390-virtio-ccw.h"
+
+static inline bool s390_is_pv(void)
+{
+ static S390CcwMachineState *ccw;
+ Object *obj;
+
+ if (ccw) {
+ return ccw->pv;
+ }
+
+ /* we have to bail out for the "none" machine */
+ obj = object_dynamic_cast(qdev_get_machine(),
+ TYPE_S390_CCW_MACHINE);
+ if (!obj) {
+ return false;
+ }
+ ccw = S390_CCW_MACHINE(obj);
+ return ccw->pv;
+}
+
+int s390_pv_vm_enable(void);
+void s390_pv_vm_disable(void);
+int s390_pv_set_sec_parms(uint64_t origin, uint64_t length);
+int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak);
+void s390_pv_perf_clear_reset(void);
+int s390_pv_verify(void);
+void s390_pv_unshare(void);
+#else /* CONFIG_KVM */
+static inline bool s390_is_pv(void) { return false; }
+static inline int s390_pv_vm_enable(void) { return 0; }
+static inline void s390_pv_vm_disable(void) {}
+static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; }
+static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) { return 0; }
+static inline void s390_pv_perf_clear_reset(void) {}
+static inline int s390_pv_verify(void) { return 0; }
+static inline void s390_pv_unshare(void) {}
+#endif /* CONFIG_KVM */
+
+#endif /* HW_S390_PV_H */
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index 8aa27199c9123bab03d3450313a5..cd1dccc6e3ba86455a9de5eb41cb 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -28,6 +28,7 @@ typedef struct S390CcwMachineState {
/*< public >*/
bool aes_key_wrap;
bool dea_key_wrap;
+ bool pv;
uint8_t loadparm[8];
} S390CcwMachineState;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 52fefa1586caa3cbd366fe230630..479f1978c974722ceeb72ac5fb32 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -37,6 +37,7 @@
#include "sysemu/hw_accel.h"
#include "hw/qdev-properties.h"
#ifndef CONFIG_USER_ONLY
+#include "hw/s390x/pv.h"
#include "hw/boards.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
diff --git a/target/s390x/cpu_features_def.inc.h b/target/s390x/cpu_features_def.inc.h
index 31dff0d84e9724513b1945f8d447..60db28351d059091b6e05fd62c37 100644
--- a/target/s390x/cpu_features_def.inc.h
+++ b/target/s390x/cpu_features_def.inc.h
@@ -107,6 +107,7 @@ DEF_FEAT(DEFLATE_BASE, "deflate-base", STFL, 151, "Deflate-conversion facility (
DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH, "vxpdeh", STFL, 152, "Vector-Packed-Decimal-Enhancement Facility")
DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)")
DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility")
+DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack facility")
/* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */
DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility")
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 8aba6341f94848e1ce8fff420ed8..b2cbefb8cfe4e5a244219e761fb4 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -20,6 +20,8 @@
#include "sysemu/cpus.h"
#include "hw/s390x/ipl.h"
#include "hw/s390x/s390-virtio-ccw.h"
+#include "hw/s390x/pv.h"
+#include "kvm_s390x.h"
int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
{
@@ -52,6 +54,10 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
uintptr_t ra, bool write)
{
+ /* Handled by the Ultravisor */
+ if (s390_is_pv()) {
+ return 0;
+ }
if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) {
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
return -1;
@@ -67,6 +73,7 @@ static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
{
+ bool valid;
CPUState *cs = env_cpu(env);
uint64_t addr = env->regs[r1];
uint64_t subcode = env->regs[r3];
@@ -82,6 +89,11 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
return;
}
+ if (subcode >= DIAG308_PV_SET && !s390_has_feat(S390_FEAT_UNPACK)) {
+ s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+ return;
+ }
+
switch (subcode) {
case DIAG308_RESET_MOD_CLR:
s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
@@ -94,6 +106,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
s390_ipl_reset_request(cs, S390_RESET_REIPL);
break;
case DIAG308_SET:
+ case DIAG308_PV_SET:
if (diag308_parm_check(env, r1, addr, ra, false)) {
return;
}
@@ -106,7 +119,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
- if (!iplb_valid(iplb)) {
+ valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb);
+ if (!valid) {
env->regs[r1 + 1] = DIAG_308_RC_INVALID;
goto out;
}
@@ -117,10 +131,15 @@ out:
g_free(iplb);
return;
case DIAG308_STORE:
+ case DIAG308_PV_STORE:
if (diag308_parm_check(env, r1, addr, ra, true)) {
return;
}
- iplb = s390_ipl_get_iplb();
+ if (subcode == DIAG308_PV_STORE) {
+ iplb = s390_ipl_get_iplb_pv();
+ } else {
+ iplb = s390_ipl_get_iplb();
+ }
if (iplb) {
cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
env->regs[r1 + 1] = DIAG_308_RC_OK;
@@ -128,6 +147,22 @@ out:
env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
}
return;
+ case DIAG308_PV_START:
+ iplb = s390_ipl_get_iplb_pv();
+ if (!iplb) {
+ env->regs[r1 + 1] = DIAG_308_RC_NO_PV_CONF;
+ return;
+ }
+
+ if (kvm_s390_get_hpage_1m()) {
+ error_report("Protected VMs can currently not be backed with "
+ "huge pages");
+ env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
+ return;
+ }
+
+ s390_ipl_reset_request(cs, S390_RESET_PV);
+ break;
default:
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
break;
diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
index c4cd497f850eb9c7a859932b0f1f..aa185017a2a886ca300fa75747ed 100644
--- a/target/s390x/kvm-stub.c
+++ b/target/s390x/kvm-stub.c
@@ -39,6 +39,11 @@ int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
return 0;
}
+int kvm_s390_get_hpage_1m(void)
+{
+ return 0;
+}
+
int kvm_s390_get_ri(void)
{
return 0;
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index f633472980b48757989db245fb1f..d8d02ff34f4fc942cb7935deec58 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -321,6 +321,11 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp)
cap_hpage_1m = 1;
}
+int kvm_s390_get_hpage_1m(void)
+{
+ return cap_hpage_1m;
+}
+
static void ccw_machine_class_foreach(ObjectClass *oc, void *opaque)
{
MachineClass *mc = MACHINE_CLASS(oc);
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
index 0b21789796d7c462bdc72160166f..dea813f450153c34e1269424772d 100644
--- a/target/s390x/kvm_s390x.h
+++ b/target/s390x/kvm_s390x.h
@@ -23,6 +23,7 @@ void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
+int kvm_s390_get_hpage_1m(void);
int kvm_s390_get_ri(void);
int kvm_s390_get_gs(void);
int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock);

View File

@ -0,0 +1,59 @@
From: Vitaly Chikunov <vt@altlinux.org>
Date: Mon, 9 Mar 2020 23:45:57 +0300
Subject: target/ppc: Fix rlwinm on ppc64
Git-commit: 94f040aaecf4e41cc68991b80204b1b6886bbdd0
rlwinm cannot just AND with Mask if shift value is zero on ppc64 when
Mask Begin is greater than Mask End and high bits are set to 1.
Note that PowerISA 3.0B says that for `rlwinm' ROTL32 is used, and
ROTL32 is defined (in 3.3.14) so that rotated value should have two
copies of lower word of the source value.
This seems to be another incarnation of the fix from 820724d170
("target-ppc: Fix rlwimi, rlwinm, rlwnm again"), except I leave
optimization when Mask value is less than 32 bits.
Fixes: 7b4d326f47 ("target-ppc: Use the new deposit and extract ops")
Cc: qemu-stable@nongnu.org
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Message-Id: <20200309204557.14836-1-vt@altlinux.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
target/ppc/translate.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index f5fe5d06118a7c86d11f38767fab..f87f6eeaf7d988896c61b025320a 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1938,15 +1938,17 @@ static void gen_rlwinm(DisasContext *ctx)
me += 32;
#endif
mask = MASK(mb, me);
- if (sh == 0) {
- tcg_gen_andi_tl(t_ra, t_rs, mask);
- } else if (mask <= 0xffffffffu) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, t_rs);
- tcg_gen_rotli_i32(t0, t0, sh);
- tcg_gen_andi_i32(t0, t0, mask);
- tcg_gen_extu_i32_tl(t_ra, t0);
- tcg_temp_free_i32(t0);
+ if (mask <= 0xffffffffu) {
+ if (sh == 0) {
+ tcg_gen_andi_tl(t_ra, t_rs, mask);
+ } else {
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, t_rs);
+ tcg_gen_rotli_i32(t0, t0, sh);
+ tcg_gen_andi_i32(t0, t0, mask);
+ tcg_gen_extu_i32_tl(t_ra, t0);
+ tcg_temp_free_i32(t0);
+ }
} else {
#if defined(TARGET_PPC64)
tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);

View File

@ -0,0 +1,56 @@
From: Jason Wang <jasowang@redhat.com>
Date: Mon, 2 Mar 2020 12:24:54 +0800
Subject: vhost: correctly turn on VIRTIO_F_IOMMU_PLATFORM
References: bsc#1167075
We turn on device IOTLB via VIRTIO_F_IOMMU_PLATFORM unconditionally on
platform without IOMMU support. This can lead unnecessary IOTLB
transactions which will damage the performance.
Fixing this by check whether the device is backed by IOMMU and disable
device IOTLB.
Reported-by: Halil Pasic <pasic@linux.ibm.com>
Tested-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20200302042454.24814-1-jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit f7ef7e6e3ba6e994e070cc609eb154339d1c4a11)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
hw/virtio/vhost.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 4da0d5a6c5867325cb8cacab4894..554e76434ffaf2dc9ada0d4bdd7a 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -290,7 +290,14 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
{
VirtIODevice *vdev = dev->vdev;
- return virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+ /*
+ * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
+ * incremental memory mapping API via IOTLB API. For platform that
+ * does not have IOMMU, there's no need to enable this feature
+ * which may cause unnecessary IOTLB miss/update trnasactions.
+ */
+ return vdev->dma_as != &address_space_memory &&
+ virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
}
static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
@@ -762,6 +769,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
if (enable_log) {
features |= 0x1ULL << VHOST_F_LOG_ALL;
}
+ if (!vhost_dev_has_iommu(dev)) {
+ features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
+ }
r = dev->vhost_ops->vhost_set_features(dev, features);
if (r < 0) {
VHOST_OPS_DEBUG("vhost_set_features failed");