* [PATCH 0/5] s390x/pv: Improve protected VM support
@ 2023-01-04 11:51 Cédric Le Goater
2023-01-04 11:51 ` [PATCH 1/5] confidential guest support: Introduce a 'check' class handler Cédric Le Goater
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-04 11:51 UTC (permalink / raw)
To: qemu-s390x
Cc: qemu-devel, Thomas Huth, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
Hello,
Here is a little series improving error reporting of protected VMs.
Thanks,
C.
Cédric Le Goater (5):
confidential guest support: Introduce a 'check' class handler
s390x/pv: Implement CGS check handler
s390x/pv: Check for support on the host
s390x/pv: Introduce a s390_pv_check() helper for runtime
s390x/pv: Move check on hugepage under s390_pv_guest_check()
include/exec/confidential-guest-support.h | 4 +-
include/hw/s390x/pv.h | 2 +
hw/core/machine.c | 11 ++--
hw/s390x/pv.c | 70 +++++++++++++++++++++++
target/s390x/diag.c | 6 +-
5 files changed, 84 insertions(+), 9 deletions(-)
--
2.38.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/5] confidential guest support: Introduce a 'check' class handler
2023-01-04 11:51 [PATCH 0/5] s390x/pv: Improve protected VM support Cédric Le Goater
@ 2023-01-04 11:51 ` Cédric Le Goater
2023-01-05 8:46 ` Thomas Huth
2023-01-04 11:51 ` [PATCH 2/5] s390x/pv: Implement CGS check handler Cédric Le Goater
` (3 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-04 11:51 UTC (permalink / raw)
To: qemu-s390x
Cc: qemu-devel, Thomas Huth, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Eduardo Habkost,
Marcel Apfelbaum, Philippe Mathieu-Daudé,
Yanan Wang
From: Cédric Le Goater <clg@redhat.com>
Some machines have specific requirements to activate confidential
guest support. Add a class handler to the confidential guest support
interface to let the arch implementation perform extra checks.
Cc: Eduardo Habkost <eduardo@habkost.net>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>
Cc: Yanan Wang <wangyanan55@huawei.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
include/exec/confidential-guest-support.h | 4 +++-
hw/core/machine.c | 11 ++++++-----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h
index ba2dd4b5df..9e6d362b26 100644
--- a/include/exec/confidential-guest-support.h
+++ b/include/exec/confidential-guest-support.h
@@ -23,7 +23,8 @@
#include "qom/object.h"
#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
-OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT)
+OBJECT_DECLARE_TYPE(ConfidentialGuestSupport, ConfidentialGuestSupportClass,
+ CONFIDENTIAL_GUEST_SUPPORT)
struct ConfidentialGuestSupport {
Object parent;
@@ -55,6 +56,7 @@ struct ConfidentialGuestSupport {
typedef struct ConfidentialGuestSupportClass {
ObjectClass parent;
+ bool (*check)(const Object *obj, Error **errp);
} ConfidentialGuestSupportClass;
#endif /* !CONFIG_USER_ONLY */
diff --git a/hw/core/machine.c b/hw/core/machine.c
index f589b92909..bab43cd675 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -502,11 +502,12 @@ static void machine_check_confidential_guest_support(const Object *obj,
Object *new_target,
Error **errp)
{
- /*
- * So far the only constraint is that the target has the
- * TYPE_CONFIDENTIAL_GUEST_SUPPORT interface, and that's checked
- * by the QOM core
- */
+ ConfidentialGuestSupportClass *cgsc =
+ CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(new_target);
+
+ if (cgsc->check) {
+ cgsc->check(obj, errp);
+ }
}
static bool machine_get_nvdimm(Object *obj, Error **errp)
--
2.38.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/5] s390x/pv: Implement CGS check handler
2023-01-04 11:51 [PATCH 0/5] s390x/pv: Improve protected VM support Cédric Le Goater
2023-01-04 11:51 ` [PATCH 1/5] confidential guest support: Introduce a 'check' class handler Cédric Le Goater
@ 2023-01-04 11:51 ` Cédric Le Goater
2023-01-05 11:42 ` Thomas Huth
2023-01-04 11:51 ` [PATCH 3/5] s390x/pv: Check for support on the host Cédric Le Goater
` (2 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-04 11:51 UTC (permalink / raw)
To: qemu-s390x
Cc: qemu-devel, Thomas Huth, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
From: Cédric Le Goater <clg@redhat.com>
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
Implement a test for this limitation in the ConfidentialGuestSupportClass
check handler and provide some valid information to the user before the
machine starts.
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/s390x/pv.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
index 8dfe92d8df..3a7ec70634 100644
--- a/hw/s390x/pv.c
+++ b/hw/s390x/pv.c
@@ -266,6 +266,26 @@ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
return 0;
}
+static bool s390_pv_check_cpus(Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ uint32_t pv_max_cpus = mc->max_cpus - 1;
+
+ 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(const Object *obj, Error **errp)
+{
+ return s390_pv_check_cpus(errp);
+}
+
OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
s390_pv_guest,
S390_PV_GUEST,
@@ -275,6 +295,9 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
static void s390_pv_guest_class_init(ObjectClass *oc, void *data)
{
+ ConfidentialGuestSupportClass *cgsc = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
+
+ cgsc->check = s390_pv_guest_check;
}
static void s390_pv_guest_init(Object *obj)
--
2.38.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/5] s390x/pv: Check for support on the host
2023-01-04 11:51 [PATCH 0/5] s390x/pv: Improve protected VM support Cédric Le Goater
2023-01-04 11:51 ` [PATCH 1/5] confidential guest support: Introduce a 'check' class handler Cédric Le Goater
2023-01-04 11:51 ` [PATCH 2/5] s390x/pv: Implement CGS check handler Cédric Le Goater
@ 2023-01-04 11:51 ` Cédric Le Goater
2023-01-05 11:46 ` Thomas Huth
2023-01-04 11:51 ` [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime Cédric Le Goater
2023-01-04 11:51 ` [PATCH 5/5] s390x/pv: Move check on hugepage under s390_pv_guest_check() Cédric Le Goater
4 siblings, 1 reply; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-04 11:51 UTC (permalink / raw)
To: qemu-s390x
Cc: qemu-devel, Thomas Huth, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
From: Cédric Le Goater <clg@redhat.com>
Support for protected VMs should have been enabled on the host with
the kernel parameter 'prot_virt=1'. If the hardware supports the
feature, it is reflected under sysfs.
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/s390x/pv.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
index 3a7ec70634..8d0d3f4adc 100644
--- a/hw/s390x/pv.c
+++ b/hw/s390x/pv.c
@@ -14,6 +14,7 @@
#include <linux/kvm.h>
#include "qapi/error.h"
+#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
#include "qom/object_interfaces.h"
@@ -281,9 +282,29 @@ static bool s390_pv_check_cpus(Error **errp)
return true;
}
+#define S390_PV_HOST "/sys/firmware/uv/prot_virt_host"
+
+static bool s390_pv_check_host(Error **errp)
+{
+ gchar *s = NULL;
+ uint64_t pv_host = 0;
+
+ if (g_file_get_contents(S390_PV_HOST, &s, NULL, NULL)) {
+ pv_host = g_ascii_strtoull(s, NULL, 10);
+ }
+ g_free(s);
+
+ if (pv_host != 1) {
+ error_setg(errp, "Host does not support protected VMs");
+ return false;
+ }
+
+ return true;
+}
+
static bool s390_pv_guest_check(const Object *obj, Error **errp)
{
- return s390_pv_check_cpus(errp);
+ return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
}
OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
--
2.38.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime
2023-01-04 11:51 [PATCH 0/5] s390x/pv: Improve protected VM support Cédric Le Goater
` (2 preceding siblings ...)
2023-01-04 11:51 ` [PATCH 3/5] s390x/pv: Check for support on the host Cédric Le Goater
@ 2023-01-04 11:51 ` Cédric Le Goater
2023-01-05 12:33 ` Thomas Huth
2023-01-05 14:24 ` Claudio Imbrenda
2023-01-04 11:51 ` [PATCH 5/5] s390x/pv: Move check on hugepage under s390_pv_guest_check() Cédric Le Goater
4 siblings, 2 replies; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-04 11:51 UTC (permalink / raw)
To: qemu-s390x
Cc: qemu-devel, Thomas Huth, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
From: Cédric Le Goater <clg@redhat.com>
If a secure kernel is started in a non-protected VM, the OS will hang
during boot without giving a proper error message to the user.
Perform the checks on Confidential Guest support at runtime with an
helper called from the service call switching the guest to protected
mode.
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
include/hw/s390x/pv.h | 2 ++
hw/s390x/pv.c | 14 ++++++++++++++
target/s390x/diag.c | 7 +++++++
3 files changed, 23 insertions(+)
diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
index 9360aa1091..ca7dac2e20 100644
--- a/include/hw/s390x/pv.h
+++ b/include/hw/s390x/pv.h
@@ -55,6 +55,7 @@ int kvm_s390_dump_init(void);
int kvm_s390_dump_cpu(S390CPU *cpu, void *buff);
int kvm_s390_dump_mem_state(uint64_t addr, size_t len, void *dest);
int kvm_s390_dump_completion_data(void *buff);
+bool s390_pv_check(Error **errp);
#else /* CONFIG_KVM */
static inline bool s390_is_pv(void) { return false; }
static inline int s390_pv_query_info(void) { return 0; }
@@ -75,6 +76,7 @@ static inline int kvm_s390_dump_cpu(S390CPU *cpu, void *buff) { return 0; }
static inline int kvm_s390_dump_mem_state(uint64_t addr, size_t len,
void *dest) { return 0; }
static inline int kvm_s390_dump_completion_data(void *buff) { return 0; }
+static inline bool s390_pv_check(Error **errp) { return false; }
#endif /* CONFIG_KVM */
int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp);
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
index 8d0d3f4adc..96c0728ec9 100644
--- a/hw/s390x/pv.c
+++ b/hw/s390x/pv.c
@@ -307,6 +307,20 @@ static bool s390_pv_guest_check(const Object *obj, Error **errp)
return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
}
+bool s390_pv_check(Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ Object *obj = OBJECT(ms->cgs);
+
+ if (!obj) {
+ error_setg(errp, "Protected VM started without a Confidential"
+ " Guest support interface");
+ return false;
+ }
+
+ return s390_pv_guest_check(obj, errp);
+}
+
OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
s390_pv_guest,
S390_PV_GUEST,
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 76b01dcd68..9b16e25930 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -79,6 +79,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
uint64_t addr = env->regs[r1];
uint64_t subcode = env->regs[r3];
IplParameterBlock *iplb;
+ Error *local_err = NULL;
if (env->psw.mask & PSW_MASK_PSTATE) {
s390_program_interrupt(env, PGM_PRIVILEGED, ra);
@@ -176,6 +177,12 @@ out:
return;
}
+ if (!s390_pv_check(&local_err)) {
+ error_report_err(local_err);
+ env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
+ return;
+ }
+
s390_ipl_reset_request(cs, S390_RESET_PV);
break;
default:
--
2.38.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 5/5] s390x/pv: Move check on hugepage under s390_pv_guest_check()
2023-01-04 11:51 [PATCH 0/5] s390x/pv: Improve protected VM support Cédric Le Goater
` (3 preceding siblings ...)
2023-01-04 11:51 ` [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime Cédric Le Goater
@ 2023-01-04 11:51 ` Cédric Le Goater
2023-01-05 12:37 ` Thomas Huth
4 siblings, 1 reply; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-04 11:51 UTC (permalink / raw)
To: qemu-s390x
Cc: qemu-devel, Thomas Huth, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
From: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/s390x/pv.c | 14 +++++++++++++-
target/s390x/diag.c | 7 -------
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
index 96c0728ec9..4e1f991d98 100644
--- a/hw/s390x/pv.c
+++ b/hw/s390x/pv.c
@@ -302,9 +302,21 @@ static bool s390_pv_check_host(Error **errp)
return true;
}
+static bool s390_pv_check_hpage(Error **errp)
+{
+ if (kvm_s390_get_hpage_1m()) {
+ error_setg(errp, "Protected VMs can currently not be backed with "
+ "huge pages");
+ return false;
+ }
+
+ return true;
+}
+
static bool s390_pv_guest_check(const Object *obj, Error **errp)
{
- return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
+ return s390_pv_check_cpus(errp) && s390_pv_check_host(errp) &&
+ s390_pv_check_hpage(errp);
}
bool s390_pv_check(Error **errp)
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 9b16e25930..28f4350aed 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -170,13 +170,6 @@ out:
return;
}
- if (kvm_enabled() && 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;
- }
-
if (!s390_pv_check(&local_err)) {
error_report_err(local_err);
env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
--
2.38.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] confidential guest support: Introduce a 'check' class handler
2023-01-04 11:51 ` [PATCH 1/5] confidential guest support: Introduce a 'check' class handler Cédric Le Goater
@ 2023-01-05 8:46 ` Thomas Huth
2023-01-05 10:34 ` Philippe Mathieu-Daudé
2023-01-05 13:56 ` Cédric Le Goater
0 siblings, 2 replies; 18+ messages in thread
From: Thomas Huth @ 2023-01-05 8:46 UTC (permalink / raw)
To: Cédric Le Goater, qemu-s390x
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Eduardo Habkost,
Marcel Apfelbaum, Philippe Mathieu-Daudé,
Yanan Wang
On 04/01/2023 12.51, Cédric Le Goater wrote:
> From: Cédric Le Goater <clg@redhat.com>
>
> Some machines have specific requirements to activate confidential
> guest support. Add a class handler to the confidential guest support
> interface to let the arch implementation perform extra checks.
>
> Cc: Eduardo Habkost <eduardo@habkost.net>
> Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
> Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>
> Cc: Yanan Wang <wangyanan55@huawei.com>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> include/exec/confidential-guest-support.h | 4 +++-
> hw/core/machine.c | 11 ++++++-----
> 2 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h
> index ba2dd4b5df..9e6d362b26 100644
> --- a/include/exec/confidential-guest-support.h
> +++ b/include/exec/confidential-guest-support.h
> @@ -23,7 +23,8 @@
> #include "qom/object.h"
>
> #define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
> -OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT)
> +OBJECT_DECLARE_TYPE(ConfidentialGuestSupport, ConfidentialGuestSupportClass,
> + CONFIDENTIAL_GUEST_SUPPORT)
>
> struct ConfidentialGuestSupport {
> Object parent;
> @@ -55,6 +56,7 @@ struct ConfidentialGuestSupport {
>
> typedef struct ConfidentialGuestSupportClass {
> ObjectClass parent;
> + bool (*check)(const Object *obj, Error **errp);
> } ConfidentialGuestSupportClass;
>
> #endif /* !CONFIG_USER_ONLY */
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index f589b92909..bab43cd675 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -502,11 +502,12 @@ static void machine_check_confidential_guest_support(const Object *obj,
> Object *new_target,
> Error **errp)
> {
> - /*
> - * So far the only constraint is that the target has the
> - * TYPE_CONFIDENTIAL_GUEST_SUPPORT interface, and that's checked
> - * by the QOM core
> - */
> + ConfidentialGuestSupportClass *cgsc =
> + CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(new_target);
> +
> + if (cgsc->check) {
> + cgsc->check(obj, errp);
I assume the caller is checking *errp, so it's ok to ignore the return value
of the check function here?
> + }
> }
>
> static bool machine_get_nvdimm(Object *obj, Error **errp)
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] confidential guest support: Introduce a 'check' class handler
2023-01-05 8:46 ` Thomas Huth
@ 2023-01-05 10:34 ` Philippe Mathieu-Daudé
2023-01-05 13:56 ` Cédric Le Goater
1 sibling, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-01-05 10:34 UTC (permalink / raw)
To: Thomas Huth, Cédric Le Goater, qemu-s390x
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Eduardo Habkost,
Marcel Apfelbaum, Yanan Wang
On 5/1/23 09:46, Thomas Huth wrote:
> On 04/01/2023 12.51, Cédric Le Goater wrote:
>> From: Cédric Le Goater <clg@redhat.com>
>>
>> Some machines have specific requirements to activate confidential
>> guest support. Add a class handler to the confidential guest support
>> interface to let the arch implementation perform extra checks.
>>
>> Cc: Eduardo Habkost <eduardo@habkost.net>
>> Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
>> Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>
>> Cc: Yanan Wang <wangyanan55@huawei.com>
>> Signed-off-by: Cédric Le Goater <clg@redhat.com>
>> ---
>> include/exec/confidential-guest-support.h | 4 +++-
>> hw/core/machine.c | 11 ++++++-----
>> 2 files changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/include/exec/confidential-guest-support.h
>> b/include/exec/confidential-guest-support.h
>> index ba2dd4b5df..9e6d362b26 100644
>> --- a/include/exec/confidential-guest-support.h
>> +++ b/include/exec/confidential-guest-support.h
>> @@ -23,7 +23,8 @@
>> #include "qom/object.h"
>> #define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
>> -OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport,
>> CONFIDENTIAL_GUEST_SUPPORT)
>> +OBJECT_DECLARE_TYPE(ConfidentialGuestSupport,
>> ConfidentialGuestSupportClass,
>> + CONFIDENTIAL_GUEST_SUPPORT)
>> struct ConfidentialGuestSupport {
>> Object parent;
>> @@ -55,6 +56,7 @@ struct ConfidentialGuestSupport {
>> typedef struct ConfidentialGuestSupportClass {
>> ObjectClass parent;
>> + bool (*check)(const Object *obj, Error **errp);
>> } ConfidentialGuestSupportClass;
>> #endif /* !CONFIG_USER_ONLY */
>> diff --git a/hw/core/machine.c b/hw/core/machine.c
>> index f589b92909..bab43cd675 100644
>> --- a/hw/core/machine.c
>> +++ b/hw/core/machine.c
>> @@ -502,11 +502,12 @@ static void
>> machine_check_confidential_guest_support(const Object *obj,
>> Object
>> *new_target,
>> Error **errp)
>> {
>> - /*
>> - * So far the only constraint is that the target has the
>> - * TYPE_CONFIDENTIAL_GUEST_SUPPORT interface, and that's checked
>> - * by the QOM core
>> - */
>> + ConfidentialGuestSupportClass *cgsc =
>> + CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(new_target);
>> +
>> + if (cgsc->check) {
>> + cgsc->check(obj, errp);
>
> I assume the caller is checking *errp, so it's ok to ignore the return
> value of the check function here?
Agreed, can we change by:
if (cgsc->check && !cgsc->check(obj, errp)) {
return;
}
?
Also since the handler name is not very self-descriptive, can we
add a comment in its declaration in ConfidentialGuestSupportClass?
>> + }
>> }
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] s390x/pv: Implement CGS check handler
2023-01-04 11:51 ` [PATCH 2/5] s390x/pv: Implement CGS check handler Cédric Le Goater
@ 2023-01-05 11:42 ` Thomas Huth
2023-01-05 13:58 ` Claudio Imbrenda
0 siblings, 1 reply; 18+ messages in thread
From: Thomas Huth @ 2023-01-05 11:42 UTC (permalink / raw)
To: Cédric Le Goater, qemu-s390x
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
On 04/01/2023 12.51, Cédric Le Goater wrote:
> From: Cédric Le Goater <clg@redhat.com>
>
> 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
>
> Implement a test for this limitation in the ConfidentialGuestSupportClass
> check handler and provide some valid information to the user before the
> machine starts.
>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> hw/s390x/pv.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
> index 8dfe92d8df..3a7ec70634 100644
> --- a/hw/s390x/pv.c
> +++ b/hw/s390x/pv.c
> @@ -266,6 +266,26 @@ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
> return 0;
> }
>
> +static bool s390_pv_check_cpus(Error **errp)
> +{
> + MachineState *ms = MACHINE(qdev_get_machine());
> + MachineClass *mc = MACHINE_GET_CLASS(ms);
> + uint32_t pv_max_cpus = mc->max_cpus - 1;
Not sure whether "mc->max_cpus - 1" is the right approach here. I think it
would be better to calculate the amount of CPUs that we can support.
So AFAIK the problem is that SCLP information that is gathered during
read_SCP_info() in hw/s390x/sclp.c. If protected virtualization is enabled,
everything has to fit in one page (i.e. 4096 bytes) there.
So we have space for
(TARGET_PAGE_SIZE - offset_cpu) / sizeof(CPUEntry)
CPUs.
With S390_FEAT_EXTENDED_LENGTH_SCCB enabled, offset_cpu is 144 (see struct
ReadInfo in sclp.h), otherwise it is 128.
That means, with S390_FEAT_EXTENDED_LENGTH_SCCB we can have a maximum of:
(4096 - 144) / 16 = 247 CPUs
which is what you were trying to check with the mc->max_cpus - 1 here.
But with "-cpu els=off", it sounds like we could fit all 248 also with
protected VMs? Could you please give it a try?
Anyway, instead of using "pv_max_cpus = mc->max_cpus - 1" I'd suggest to use
something like this instead:
int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
offsetof(ReadInfo, entries) :
SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
Thomas
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] s390x/pv: Check for support on the host
2023-01-04 11:51 ` [PATCH 3/5] s390x/pv: Check for support on the host Cédric Le Goater
@ 2023-01-05 11:46 ` Thomas Huth
0 siblings, 0 replies; 18+ messages in thread
From: Thomas Huth @ 2023-01-05 11:46 UTC (permalink / raw)
To: Cédric Le Goater, qemu-s390x
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
On 04/01/2023 12.51, Cédric Le Goater wrote:
> From: Cédric Le Goater <clg@redhat.com>
>
> Support for protected VMs should have been enabled on the host with
> the kernel parameter 'prot_virt=1'. If the hardware supports the
> feature, it is reflected under sysfs.
>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> hw/s390x/pv.c | 23 ++++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
> index 3a7ec70634..8d0d3f4adc 100644
> --- a/hw/s390x/pv.c
> +++ b/hw/s390x/pv.c
> @@ -14,6 +14,7 @@
> #include <linux/kvm.h>
>
> #include "qapi/error.h"
> +#include "qemu/cutils.h"
> #include "qemu/error-report.h"
> #include "sysemu/kvm.h"
> #include "qom/object_interfaces.h"
> @@ -281,9 +282,29 @@ static bool s390_pv_check_cpus(Error **errp)
> return true;
> }
>
> +#define S390_PV_HOST "/sys/firmware/uv/prot_virt_host"
> +
> +static bool s390_pv_check_host(Error **errp)
> +{
> + gchar *s = NULL;
> + uint64_t pv_host = 0;
> +
> + if (g_file_get_contents(S390_PV_HOST, &s, NULL, NULL)) {
> + pv_host = g_ascii_strtoull(s, NULL, 10);
> + }
> + g_free(s);
> +
> + if (pv_host != 1) {
> + error_setg(errp, "Host does not support protected VMs");
> + return false;
> + }
> +
> + return true;
> +}
> +
> static bool s390_pv_guest_check(const Object *obj, Error **errp)
> {
> - return s390_pv_check_cpus(errp);
> + return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
> }
>
> OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime
2023-01-04 11:51 ` [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime Cédric Le Goater
@ 2023-01-05 12:33 ` Thomas Huth
2023-01-05 14:24 ` Claudio Imbrenda
1 sibling, 0 replies; 18+ messages in thread
From: Thomas Huth @ 2023-01-05 12:33 UTC (permalink / raw)
To: Cédric Le Goater, qemu-s390x, Janosch Frank, Claudio Imbrenda
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Nico Boehr
On 04/01/2023 12.51, Cédric Le Goater wrote:
> From: Cédric Le Goater <clg@redhat.com>
>
> If a secure kernel is started in a non-protected VM, the OS will hang
> during boot without giving a proper error message to the user.
>
> Perform the checks on Confidential Guest support at runtime with an
> helper called from the service call switching the guest to protected
> mode.
>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> include/hw/s390x/pv.h | 2 ++
> hw/s390x/pv.c | 14 ++++++++++++++
> target/s390x/diag.c | 7 +++++++
> 3 files changed, 23 insertions(+)
>
> diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
> index 9360aa1091..ca7dac2e20 100644
> --- a/include/hw/s390x/pv.h
> +++ b/include/hw/s390x/pv.h
> @@ -55,6 +55,7 @@ int kvm_s390_dump_init(void);
> int kvm_s390_dump_cpu(S390CPU *cpu, void *buff);
> int kvm_s390_dump_mem_state(uint64_t addr, size_t len, void *dest);
> int kvm_s390_dump_completion_data(void *buff);
> +bool s390_pv_check(Error **errp);
> #else /* CONFIG_KVM */
> static inline bool s390_is_pv(void) { return false; }
> static inline int s390_pv_query_info(void) { return 0; }
> @@ -75,6 +76,7 @@ static inline int kvm_s390_dump_cpu(S390CPU *cpu, void *buff) { return 0; }
> static inline int kvm_s390_dump_mem_state(uint64_t addr, size_t len,
> void *dest) { return 0; }
> static inline int kvm_s390_dump_completion_data(void *buff) { return 0; }
> +static inline bool s390_pv_check(Error **errp) { return false; }
> #endif /* CONFIG_KVM */
>
> int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp);
> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
> index 8d0d3f4adc..96c0728ec9 100644
> --- a/hw/s390x/pv.c
> +++ b/hw/s390x/pv.c
> @@ -307,6 +307,20 @@ static bool s390_pv_guest_check(const Object *obj, Error **errp)
> return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
> }
>
> +bool s390_pv_check(Error **errp)
> +{
> + MachineState *ms = MACHINE(qdev_get_machine());
> + Object *obj = OBJECT(ms->cgs);
> +
> + if (!obj) {
> + error_setg(errp, "Protected VM started without a Confidential"
> + " Guest support interface");
> + return false;
> + }
> +
> + return s390_pv_guest_check(obj, errp);
> +}
> +
> OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
> s390_pv_guest,
> S390_PV_GUEST,
> diff --git a/target/s390x/diag.c b/target/s390x/diag.c
> index 76b01dcd68..9b16e25930 100644
> --- a/target/s390x/diag.c
> +++ b/target/s390x/diag.c
> @@ -79,6 +79,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
> uint64_t addr = env->regs[r1];
> uint64_t subcode = env->regs[r3];
> IplParameterBlock *iplb;
> + Error *local_err = NULL;
>
> if (env->psw.mask & PSW_MASK_PSTATE) {
> s390_program_interrupt(env, PGM_PRIVILEGED, ra);
> @@ -176,6 +177,12 @@ out:
> return;
> }
>
> + if (!s390_pv_check(&local_err)) {
> + error_report_err(local_err);
> + env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
I hope someone from IBM can double-check whether that return code is fine in
this case here.
If so, the patch looks fine to me.
Thomas
> + return;
> + }
> +
> s390_ipl_reset_request(cs, S390_RESET_PV);
> break;
> default:
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 5/5] s390x/pv: Move check on hugepage under s390_pv_guest_check()
2023-01-04 11:51 ` [PATCH 5/5] s390x/pv: Move check on hugepage under s390_pv_guest_check() Cédric Le Goater
@ 2023-01-05 12:37 ` Thomas Huth
0 siblings, 0 replies; 18+ messages in thread
From: Thomas Huth @ 2023-01-05 12:37 UTC (permalink / raw)
To: Cédric Le Goater, qemu-s390x
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Claudio Imbrenda,
Janosch Frank
On 04/01/2023 12.51, Cédric Le Goater wrote:
> From: Cédric Le Goater <clg@redhat.com>
>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> hw/s390x/pv.c | 14 +++++++++++++-
> target/s390x/diag.c | 7 -------
> 2 files changed, 13 insertions(+), 8 deletions(-)
>
> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
> index 96c0728ec9..4e1f991d98 100644
> --- a/hw/s390x/pv.c
> +++ b/hw/s390x/pv.c
> @@ -302,9 +302,21 @@ static bool s390_pv_check_host(Error **errp)
> return true;
> }
>
> +static bool s390_pv_check_hpage(Error **errp)
> +{
> + if (kvm_s390_get_hpage_1m()) {
> + error_setg(errp, "Protected VMs can currently not be backed with "
> + "huge pages");
> + return false;
> + }
> +
> + return true;
> +}
> +
> static bool s390_pv_guest_check(const Object *obj, Error **errp)
> {
> - return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
> + return s390_pv_check_cpus(errp) && s390_pv_check_host(errp) &&
> + s390_pv_check_hpage(errp);
> }
>
> bool s390_pv_check(Error **errp)
> diff --git a/target/s390x/diag.c b/target/s390x/diag.c
> index 9b16e25930..28f4350aed 100644
> --- a/target/s390x/diag.c
> +++ b/target/s390x/diag.c
> @@ -170,13 +170,6 @@ out:
> return;
> }
>
> - if (kvm_enabled() && 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;
> - }
> -
> if (!s390_pv_check(&local_err)) {
> error_report_err(local_err);
> env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] confidential guest support: Introduce a 'check' class handler
2023-01-05 8:46 ` Thomas Huth
2023-01-05 10:34 ` Philippe Mathieu-Daudé
@ 2023-01-05 13:56 ` Cédric Le Goater
1 sibling, 0 replies; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-05 13:56 UTC (permalink / raw)
To: Thomas Huth, qemu-s390x
Cc: qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Eduardo Habkost,
Marcel Apfelbaum, Philippe Mathieu-Daudé,
Yanan Wang
On 1/5/23 09:46, Thomas Huth wrote:
> On 04/01/2023 12.51, Cédric Le Goater wrote:
>> From: Cédric Le Goater <clg@redhat.com>
>>
>> Some machines have specific requirements to activate confidential
>> guest support. Add a class handler to the confidential guest support
>> interface to let the arch implementation perform extra checks.
>>
>> Cc: Eduardo Habkost <eduardo@habkost.net>
>> Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
>> Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>
>> Cc: Yanan Wang <wangyanan55@huawei.com>
>> Signed-off-by: Cédric Le Goater <clg@redhat.com>
>> ---
>> include/exec/confidential-guest-support.h | 4 +++-
>> hw/core/machine.c | 11 ++++++-----
>> 2 files changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h
>> index ba2dd4b5df..9e6d362b26 100644
>> --- a/include/exec/confidential-guest-support.h
>> +++ b/include/exec/confidential-guest-support.h
>> @@ -23,7 +23,8 @@
>> #include "qom/object.h"
>> #define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
>> -OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT)
>> +OBJECT_DECLARE_TYPE(ConfidentialGuestSupport, ConfidentialGuestSupportClass,
>> + CONFIDENTIAL_GUEST_SUPPORT)
>> struct ConfidentialGuestSupport {
>> Object parent;
>> @@ -55,6 +56,7 @@ struct ConfidentialGuestSupport {
>> typedef struct ConfidentialGuestSupportClass {
>> ObjectClass parent;
>> + bool (*check)(const Object *obj, Error **errp);
>> } ConfidentialGuestSupportClass;
>> #endif /* !CONFIG_USER_ONLY */
>> diff --git a/hw/core/machine.c b/hw/core/machine.c
>> index f589b92909..bab43cd675 100644
>> --- a/hw/core/machine.c
>> +++ b/hw/core/machine.c
>> @@ -502,11 +502,12 @@ static void machine_check_confidential_guest_support(const Object *obj,
>> Object *new_target,
>> Error **errp)
>> {
>> - /*
>> - * So far the only constraint is that the target has the
>> - * TYPE_CONFIDENTIAL_GUEST_SUPPORT interface, and that's checked
>> - * by the QOM core
>> - */
>> + ConfidentialGuestSupportClass *cgsc =
>> + CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(new_target);
>> +
>> + if (cgsc->check) {
>> + cgsc->check(obj, errp);
>
> I assume the caller is checking *errp, so it's ok to ignore the return value of the check function here?
yes. routine machine_check_confidential_guest_support() is a direct parameter
of object_class_property_add_link() call, which checks *errp. See routine
object_set_link_property().
Thanks,
C.
>
>> + }
>> }
>> static bool machine_get_nvdimm(Object *obj, Error **errp)
>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] s390x/pv: Implement CGS check handler
2023-01-05 11:42 ` Thomas Huth
@ 2023-01-05 13:58 ` Claudio Imbrenda
2023-01-05 14:47 ` Cédric Le Goater
0 siblings, 1 reply; 18+ messages in thread
From: Claudio Imbrenda @ 2023-01-05 13:58 UTC (permalink / raw)
To: Thomas Huth
Cc: Cédric Le Goater, qemu-s390x, qemu-devel, Halil Pasic,
Christian Borntraeger, Richard Henderson, David Hildenbrand,
Ilya Leoshkevich, Eric Farman, Cédric Le Goater
On Thu, 5 Jan 2023 12:42:54 +0100
Thomas Huth <thuth@redhat.com> wrote:
> On 04/01/2023 12.51, Cédric Le Goater wrote:
> > From: Cédric Le Goater <clg@redhat.com>
> >
> > 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
> >
> > Implement a test for this limitation in the ConfidentialGuestSupportClass
> > check handler and provide some valid information to the user before the
> > machine starts.
> >
> > Signed-off-by: Cédric Le Goater <clg@redhat.com>
> > ---
> > hw/s390x/pv.c | 23 +++++++++++++++++++++++
> > 1 file changed, 23 insertions(+)
> >
> > diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
> > index 8dfe92d8df..3a7ec70634 100644
> > --- a/hw/s390x/pv.c
> > +++ b/hw/s390x/pv.c
> > @@ -266,6 +266,26 @@ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
> > return 0;
> > }
> >
> > +static bool s390_pv_check_cpus(Error **errp)
> > +{
> > + MachineState *ms = MACHINE(qdev_get_machine());
> > + MachineClass *mc = MACHINE_GET_CLASS(ms);
> > + uint32_t pv_max_cpus = mc->max_cpus - 1;
>
> Not sure whether "mc->max_cpus - 1" is the right approach here. I think it
> would be better to calculate the amount of CPUs that we can support.
>
> So AFAIK the problem is that SCLP information that is gathered during
> read_SCP_info() in hw/s390x/sclp.c. If protected virtualization is enabled,
> everything has to fit in one page (i.e. 4096 bytes) there.
>
> So we have space for
>
> (TARGET_PAGE_SIZE - offset_cpu) / sizeof(CPUEntry)
>
> CPUs.
>
> With S390_FEAT_EXTENDED_LENGTH_SCCB enabled, offset_cpu is 144 (see struct
> ReadInfo in sclp.h), otherwise it is 128.
>
> That means, with S390_FEAT_EXTENDED_LENGTH_SCCB we can have a maximum of:
>
> (4096 - 144) / 16 = 247 CPUs
>
> which is what you were trying to check with the mc->max_cpus - 1 here.
>
> But with "-cpu els=off", it sounds like we could fit all 248 also with
> protected VMs? Could you please give it a try?
>
> Anyway, instead of using "pv_max_cpus = mc->max_cpus - 1" I'd suggest to use
> something like this instead:
>
> int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
> offsetof(ReadInfo, entries) :
> SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
> pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
I agree with Thomas here
>
> Thomas
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime
2023-01-04 11:51 ` [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime Cédric Le Goater
2023-01-05 12:33 ` Thomas Huth
@ 2023-01-05 14:24 ` Claudio Imbrenda
1 sibling, 0 replies; 18+ messages in thread
From: Claudio Imbrenda @ 2023-01-05 14:24 UTC (permalink / raw)
To: Cédric Le Goater
Cc: qemu-s390x, qemu-devel, Thomas Huth, Halil Pasic,
Christian Borntraeger, Richard Henderson, David Hildenbrand,
Ilya Leoshkevich, Eric Farman, Cédric Le Goater, frankja
On Wed, 4 Jan 2023 12:51:10 +0100
Cédric Le Goater <clg@kaod.org> wrote:
> From: Cédric Le Goater <clg@redhat.com>
>
> If a secure kernel is started in a non-protected VM, the OS will hang
> during boot without giving a proper error message to the user.
>
> Perform the checks on Confidential Guest support at runtime with an
> helper called from the service call switching the guest to protected
> mode.
>
> Signed-off-by: Cédric Le Goater <clg@redhat.com>
> ---
> include/hw/s390x/pv.h | 2 ++
> hw/s390x/pv.c | 14 ++++++++++++++
> target/s390x/diag.c | 7 +++++++
> 3 files changed, 23 insertions(+)
>
> diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
> index 9360aa1091..ca7dac2e20 100644
> --- a/include/hw/s390x/pv.h
> +++ b/include/hw/s390x/pv.h
> @@ -55,6 +55,7 @@ int kvm_s390_dump_init(void);
> int kvm_s390_dump_cpu(S390CPU *cpu, void *buff);
> int kvm_s390_dump_mem_state(uint64_t addr, size_t len, void *dest);
> int kvm_s390_dump_completion_data(void *buff);
> +bool s390_pv_check(Error **errp);
> #else /* CONFIG_KVM */
> static inline bool s390_is_pv(void) { return false; }
> static inline int s390_pv_query_info(void) { return 0; }
> @@ -75,6 +76,7 @@ static inline int kvm_s390_dump_cpu(S390CPU *cpu, void *buff) { return 0; }
> static inline int kvm_s390_dump_mem_state(uint64_t addr, size_t len,
> void *dest) { return 0; }
> static inline int kvm_s390_dump_completion_data(void *buff) { return 0; }
> +static inline bool s390_pv_check(Error **errp) { return false; }
> #endif /* CONFIG_KVM */
>
> int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp);
> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
> index 8d0d3f4adc..96c0728ec9 100644
> --- a/hw/s390x/pv.c
> +++ b/hw/s390x/pv.c
> @@ -307,6 +307,20 @@ static bool s390_pv_guest_check(const Object *obj, Error **errp)
> return s390_pv_check_cpus(errp) && s390_pv_check_host(errp);
> }
>
> +bool s390_pv_check(Error **errp)
> +{
> + MachineState *ms = MACHINE(qdev_get_machine());
> + Object *obj = OBJECT(ms->cgs);
> +
> + if (!obj) {
> + error_setg(errp, "Protected VM started without a Confidential"
> + " Guest support interface");
> + return false;
> + }
> +
> + return s390_pv_guest_check(obj, errp);
> +}
> +
> OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest,
> s390_pv_guest,
> S390_PV_GUEST,
> diff --git a/target/s390x/diag.c b/target/s390x/diag.c
> index 76b01dcd68..9b16e25930 100644
> --- a/target/s390x/diag.c
> +++ b/target/s390x/diag.c
> @@ -79,6 +79,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
> uint64_t addr = env->regs[r1];
> uint64_t subcode = env->regs[r3];
> IplParameterBlock *iplb;
> + Error *local_err = NULL;
>
> if (env->psw.mask & PSW_MASK_PSTATE) {
> s390_program_interrupt(env, PGM_PRIVILEGED, ra);
> @@ -176,6 +177,12 @@ out:
> return;
> }
>
> + if (!s390_pv_check(&local_err)) {
> + error_report_err(local_err);
> + env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
> + return;
> + }
> +
in general yes
however I have noticed that we don't always return a PGM_SPECIFICATION
when PV is not available (we currently do it only for DIAG308_PV_SET). I
think we should return the PGM_SPECIFICATION for all PV subcodes when
the feature is not present (but this is a separate issue)
let me add Janosch in CC since he wrote that code
> s390_ipl_reset_request(cs, S390_RESET_PV);
> break;
> default:
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] s390x/pv: Implement CGS check handler
2023-01-05 13:58 ` Claudio Imbrenda
@ 2023-01-05 14:47 ` Cédric Le Goater
2023-01-05 14:53 ` Thomas Huth
0 siblings, 1 reply; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-05 14:47 UTC (permalink / raw)
To: Claudio Imbrenda, Thomas Huth
Cc: qemu-s390x, qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
On 1/5/23 14:58, Claudio Imbrenda wrote:
> On Thu, 5 Jan 2023 12:42:54 +0100
> Thomas Huth <thuth@redhat.com> wrote:
>
>> On 04/01/2023 12.51, Cédric Le Goater wrote:
>>> From: Cédric Le Goater <clg@redhat.com>
>>>
>>> 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
>>>
>>> Implement a test for this limitation in the ConfidentialGuestSupportClass
>>> check handler and provide some valid information to the user before the
>>> machine starts.
>>>
>>> Signed-off-by: Cédric Le Goater <clg@redhat.com>
>>> ---
>>> hw/s390x/pv.c | 23 +++++++++++++++++++++++
>>> 1 file changed, 23 insertions(+)
>>>
>>> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
>>> index 8dfe92d8df..3a7ec70634 100644
>>> --- a/hw/s390x/pv.c
>>> +++ b/hw/s390x/pv.c
>>> @@ -266,6 +266,26 @@ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
>>> return 0;
>>> }
>>>
>>> +static bool s390_pv_check_cpus(Error **errp)
>>> +{
>>> + MachineState *ms = MACHINE(qdev_get_machine());
>>> + MachineClass *mc = MACHINE_GET_CLASS(ms);
>>> + uint32_t pv_max_cpus = mc->max_cpus - 1;
>>
>> Not sure whether "mc->max_cpus - 1" is the right approach here. I think it
>> would be better to calculate the amount of CPUs that we can support.
>>
>> So AFAIK the problem is that SCLP information that is gathered during
>> read_SCP_info() in hw/s390x/sclp.c. If protected virtualization is enabled,
>> everything has to fit in one page (i.e. 4096 bytes) there.
>>
>> So we have space for
>>
>> (TARGET_PAGE_SIZE - offset_cpu) / sizeof(CPUEntry)
>>
>> CPUs.
>>
>> With S390_FEAT_EXTENDED_LENGTH_SCCB enabled, offset_cpu is 144 (see struct
>> ReadInfo in sclp.h), otherwise it is 128.
>>
>> That means, with S390_FEAT_EXTENDED_LENGTH_SCCB we can have a maximum of:
>>
>> (4096 - 144) / 16 = 247 CPUs
>>
>> which is what you were trying to check with the mc->max_cpus - 1 here.
yes. That's much better.
>> But with "-cpu els=off", it sounds like we could fit all 248 also with
>> protected VMs? Could you please give it a try?
It runs. Unfortunately, QEMU also complains with :
qemu-system-s390x: warning: 'diag318' requires 'els'.
qemu-system-s390x: warning: 'diag318' requires 'els'.
qemu-system-s390x: warning: 'diag318' requires 'els'.
when els is off.
>> Anyway, instead of using "pv_max_cpus = mc->max_cpus - 1" I'd suggest to use
>> something like this instead:
>>
>> int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
>> offsetof(ReadInfo, entries) :
>> SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
>> pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
>
> I agree with Thomas here
The problem is that QEMU doesn't know about the S390_FEAT_EXTENDED_LENGTH_SCCB
feature when the PV object link is first checked. So #248 CPUs is considered
valid, but when DIAG308_PV_START is called, it fails.
Let's simplify and use :
int offset_cpu = offsetof(ReadInfo, entries);
pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
?
Thanks,
C.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] s390x/pv: Implement CGS check handler
2023-01-05 14:47 ` Cédric Le Goater
@ 2023-01-05 14:53 ` Thomas Huth
2023-01-05 17:12 ` Cédric Le Goater
0 siblings, 1 reply; 18+ messages in thread
From: Thomas Huth @ 2023-01-05 14:53 UTC (permalink / raw)
To: Cédric Le Goater, Claudio Imbrenda, Janosch Frank
Cc: qemu-s390x, qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater, Claudio Imbrenda
On 05/01/2023 15.47, Cédric Le Goater wrote:
> On 1/5/23 14:58, Claudio Imbrenda wrote:
>> On Thu, 5 Jan 2023 12:42:54 +0100
>> Thomas Huth <thuth@redhat.com> wrote:
>>
>>> On 04/01/2023 12.51, Cédric Le Goater wrote:
>>>> From: Cédric Le Goater <clg@redhat.com>
>>>>
>>>> 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
>>>>
>>>> Implement a test for this limitation in the ConfidentialGuestSupportClass
>>>> check handler and provide some valid information to the user before the
>>>> machine starts.
>>>>
>>>> Signed-off-by: Cédric Le Goater <clg@redhat.com>
>>>> ---
>>>> hw/s390x/pv.c | 23 +++++++++++++++++++++++
>>>> 1 file changed, 23 insertions(+)
>>>>
>>>> diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
>>>> index 8dfe92d8df..3a7ec70634 100644
>>>> --- a/hw/s390x/pv.c
>>>> +++ b/hw/s390x/pv.c
>>>> @@ -266,6 +266,26 @@ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs,
>>>> Error **errp)
>>>> return 0;
>>>> }
>>>> +static bool s390_pv_check_cpus(Error **errp)
>>>> +{
>>>> + MachineState *ms = MACHINE(qdev_get_machine());
>>>> + MachineClass *mc = MACHINE_GET_CLASS(ms);
>>>> + uint32_t pv_max_cpus = mc->max_cpus - 1;
>>>
>>> Not sure whether "mc->max_cpus - 1" is the right approach here. I think it
>>> would be better to calculate the amount of CPUs that we can support.
>>>
>>> So AFAIK the problem is that SCLP information that is gathered during
>>> read_SCP_info() in hw/s390x/sclp.c. If protected virtualization is enabled,
>>> everything has to fit in one page (i.e. 4096 bytes) there.
>>>
>>> So we have space for
>>>
>>> (TARGET_PAGE_SIZE - offset_cpu) / sizeof(CPUEntry)
>>>
>>> CPUs.
>>>
>>> With S390_FEAT_EXTENDED_LENGTH_SCCB enabled, offset_cpu is 144 (see struct
>>> ReadInfo in sclp.h), otherwise it is 128.
>>>
>>> That means, with S390_FEAT_EXTENDED_LENGTH_SCCB we can have a maximum of:
>>>
>>> (4096 - 144) / 16 = 247 CPUs
>>>
>>> which is what you were trying to check with the mc->max_cpus - 1 here.
>
> yes. That's much better.
>
>>> But with "-cpu els=off", it sounds like we could fit all 248 also with
>>> protected VMs? Could you please give it a try?
>
> It runs. Unfortunately, QEMU also complains with :
>
> qemu-system-s390x: warning: 'diag318' requires 'els'.
> qemu-system-s390x: warning: 'diag318' requires 'els'.
> qemu-system-s390x: warning: 'diag318' requires 'els'.
>
> when els is off.
There is also a switch for that: -cpu els=off,diag318=off
>>> Anyway, instead of using "pv_max_cpus = mc->max_cpus - 1" I'd suggest to use
>>> something like this instead:
>>>
>>> int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
>>> offsetof(ReadInfo, entries) :
>>> SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
>>> pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
>>
>> I agree with Thomas here
>
>
> The problem is that QEMU doesn't know about the S390_FEAT_EXTENDED_LENGTH_SCCB
> feature when the PV object link is first checked. So #248 CPUs is considered
> valid, but when DIAG308_PV_START is called, it fails.
Drat. Is there any chance that the check could be done somewhere later?
> Let's simplify and use :
>
> int offset_cpu = offsetof(ReadInfo, entries);
> pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
>
> ?
Depends ... if it is possible to use 248 CPUs with -cpu els=off,diag318=off
then it would be nicer to allow that, too?
Thomas
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] s390x/pv: Implement CGS check handler
2023-01-05 14:53 ` Thomas Huth
@ 2023-01-05 17:12 ` Cédric Le Goater
0 siblings, 0 replies; 18+ messages in thread
From: Cédric Le Goater @ 2023-01-05 17:12 UTC (permalink / raw)
To: Thomas Huth, Claudio Imbrenda, Janosch Frank
Cc: qemu-s390x, qemu-devel, Halil Pasic, Christian Borntraeger,
Richard Henderson, David Hildenbrand, Ilya Leoshkevich,
Eric Farman, Cédric Le Goater
[ .. ]
>> The problem is that QEMU doesn't know about the S390_FEAT_EXTENDED_LENGTH_SCCB
>> feature when the PV object link is first checked. So #248 CPUs is considered
>> valid, but when DIAG308_PV_START is called, it fails.
>
> Drat. Is there any chance that the check could be done somewhere later?
s390_pv_init() could be the place. It looks like a good option since the CPUs have
been initialized. To be explored.
Thanks,
C.
>> Let's simplify and use :
>>
>> int offset_cpu = offsetof(ReadInfo, entries);
>> pv_max_cpus = (TARGET_PAGE_SIZE - offset_cpu) /sizeof(CPUEntry);
>>
>> ?
>
> Depends ... if it is possible to use 248 CPUs with -cpu els=off,diag318=off then it would be nicer to allow that, too?
>
> Thomas
>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2023-01-05 17:16 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-04 11:51 [PATCH 0/5] s390x/pv: Improve protected VM support Cédric Le Goater
2023-01-04 11:51 ` [PATCH 1/5] confidential guest support: Introduce a 'check' class handler Cédric Le Goater
2023-01-05 8:46 ` Thomas Huth
2023-01-05 10:34 ` Philippe Mathieu-Daudé
2023-01-05 13:56 ` Cédric Le Goater
2023-01-04 11:51 ` [PATCH 2/5] s390x/pv: Implement CGS check handler Cédric Le Goater
2023-01-05 11:42 ` Thomas Huth
2023-01-05 13:58 ` Claudio Imbrenda
2023-01-05 14:47 ` Cédric Le Goater
2023-01-05 14:53 ` Thomas Huth
2023-01-05 17:12 ` Cédric Le Goater
2023-01-04 11:51 ` [PATCH 3/5] s390x/pv: Check for support on the host Cédric Le Goater
2023-01-05 11:46 ` Thomas Huth
2023-01-04 11:51 ` [PATCH 4/5] s390x/pv: Introduce a s390_pv_check() helper for runtime Cédric Le Goater
2023-01-05 12:33 ` Thomas Huth
2023-01-05 14:24 ` Claudio Imbrenda
2023-01-04 11:51 ` [PATCH 5/5] s390x/pv: Move check on hugepage under s390_pv_guest_check() Cédric Le Goater
2023-01-05 12:37 ` Thomas Huth
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.