You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.6 KiB
110 lines
3.6 KiB
9 months ago
|
From 2fc8489b70445a3db0a2e72c1f1edb4d61d404d6 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||
|
Date: Mon, 16 Jan 2023 18:46:05 +0100
|
||
|
Subject: [PATCH] s390x/pv: Implement a CGS check helper
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
RH-Author: Cédric Le Goater <clg@redhat.com>
|
||
|
RH-MergeRequest: 271: Secure guest can't boot with maximal number of vcpus (248)
|
||
|
RH-Bugzilla: 2187159
|
||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||
|
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||
|
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
||
|
RH-Commit: [1/1] c870d525c48ab6d0df964b5abe48efe2528c9883
|
||
|
|
||
|
When a protected VM is started with the maximum number of CPUs (248),
|
||
|
the service call providing information on the CPUs requires more
|
||
|
buffer space than allocated and QEMU disgracefully aborts :
|
||
|
|
||
|
LOADPARM=[........]
|
||
|
Using virtio-blk.
|
||
|
Using SCSI scheme.
|
||
|
...................................................................................
|
||
|
qemu-system-s390x: KVM_S390_MEM_OP failed: Argument list too long
|
||
|
|
||
|
When protected virtualization is initialized, compute the maximum
|
||
|
number of vCPUs supported by the machine and return useful information
|
||
|
to the user before the machine starts in case of error.
|
||
|
|
||
|
Suggested-by: Thomas Huth <thuth@redhat.com>
|
||
|
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||
|
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||
|
Message-Id: <20230116174607.2459498-2-clg@kaod.org>
|
||
|
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||
|
(cherry picked from commit 75d7150c636569f6687f7e70a33be893be43eb5f)
|
||
|
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||
|
---
|
||
|
hw/s390x/pv.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 40 insertions(+)
|
||
|
|
||
|
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
|
||
|
index 728ba24547..749e5db1ce 100644
|
||
|
--- a/hw/s390x/pv.c
|
||
|
+++ b/hw/s390x/pv.c
|
||
|
@@ -20,6 +20,7 @@
|
||
|
#include "exec/confidential-guest-support.h"
|
||
|
#include "hw/s390x/ipl.h"
|
||
|
#include "hw/s390x/pv.h"
|
||
|
+#include "hw/s390x/sclp.h"
|
||
|
#include "target/s390x/kvm/kvm_s390x.h"
|
||
|
|
||
|
static bool info_valid;
|
||
|
@@ -249,6 +250,41 @@ struct S390PVGuestClass {
|
||
|
ConfidentialGuestSupportClass parent_class;
|
||
|
};
|
||
|
|
||
|
+/*
|
||
|
+ * If protected virtualization is enabled, the amount of data that the
|
||
|
+ * Read SCP Info Service Call can use is limited to one page. The
|
||
|
+ * available space also depends on the Extended-Length SCCB (ELS)
|
||
|
+ * feature which can take more buffer space to store feature
|
||
|
+ * information. This impacts the maximum number of CPUs supported in
|
||
|
+ * the machine.
|
||
|
+ */
|
||
|
+static uint32_t s390_pv_get_max_cpus(void)
|
||
|
+{
|
||
|
+ int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
|
||
|
+ offsetof(ReadInfo, entries) : SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
|
||
|
+
|
||
|
+ return (TARGET_PAGE_SIZE - offset_cpu) / sizeof(CPUEntry);
|
||
|
+}
|
||
|
+
|
||
|
+static bool s390_pv_check_cpus(Error **errp)
|
||
|
+{
|
||
|
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||
|
+ uint32_t pv_max_cpus = s390_pv_get_max_cpus();
|
||
|
+
|
||
|
+ if (ms->smp.max_cpus > pv_max_cpus) {
|
||
|
+ error_setg(errp, "Protected VMs support a maximum of %d CPUs",
|
||
|
+ pv_max_cpus);
|
||
|
+ return false;
|
||
|
+ }
|
||
|
+
|
||
|
+ return true;
|
||
|
+}
|
||
|
+
|
||
|
+static bool s390_pv_guest_check(ConfidentialGuestSupport *cgs, Error **errp)
|
||
|
+{
|
||
|
+ return s390_pv_check_cpus(errp);
|
||
|
+}
|
||
|
+
|
||
|
int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
||
|
{
|
||
|
if (!object_dynamic_cast(OBJECT(cgs), TYPE_S390_PV_GUEST)) {
|
||
|
@@ -261,6 +297,10 @@ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
+ if (!s390_pv_guest_check(cgs, errp)) {
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
cgs->ready = true;
|
||
|
|
||
|
return 0;
|
||
|
--
|
||
|
2.39.1
|
||
|
|