mbox series

[RFC,v3,0/5] Add PSCI v1.3 SYSTEM_OFF2 support for hibernation

Message ID 20240319130957.1050637-1-dwmw2@infradead.org (mailing list archive)
Headers show
Series Add PSCI v1.3 SYSTEM_OFF2 support for hibernation | expand

Message

David Woodhouse March 19, 2024, 12:59 p.m. UTC
The PSCI v1.3 spec (https://developer.arm.com/documentation/den0022,
currently in Alpha state, hence 'RFC') adds support for a SYSTEM_OFF2
function enabling a HIBERNATE_OFF state which is analogous to ACPI S4.
This will allow hosting environments to determine that a guest is
hibernated rather than just powered off, and ensure that they preserve
the virtual environment appropriately to allow the guest to resume
safely (or bump the hardware_signature in the FACS to trigger a clean
reboot instead).

This updates KVM to support advertising PSCI v1.3, and unconditionally
enables the SYSTEM_OFF2 support when PSCI v1.3 is enabled. For now,
KVM defaults to PSCI v1.2 unless explicitly requested.

For the guest side, add a new SYS_OFF_MODE_POWER_OFF handler with higher
priority than the EFI one, but which *only* triggers when there's a
hibernation in progress. There are other ways to do this (see the commit
message for more details) but this seemed like the simplest.

Version 2 of the patch series splits out the psci.h definitions into a
separate commit (a dependency for both the guest and KVM side), and adds
definitions for the other new functions added in v1.3. It also moves the
pKVM psci-relay support to a separate commit; although in arch/arm64/kvm
that's actually about the *guest* side of SYSTEM_OFF2 (i.e. using it
from the host kernel, relayed through nVHE).

Version 3 dropped the KVM_CAP which allowed userspace to explicitly opt
in to the new feature like with SYSTEM_SUSPEND, and makes it depend only
on PSCI v1.3 being exposed to the guest.

David Woodhouse (5):
      firmware/psci: Add definitions for PSCI v1.3 specification (ALPHA)
      KVM: arm64: Add support for PSCI v1.2 and v1.3
      KVM: arm64: Add PSCI v1.3 SYSTEM_OFF2 function for hibernation
      KVM: arm64: nvhe: Pass through PSCI v1.3 SYSTEM_OFF2 call
      arm64: Use SYSTEM_OFF2 PSCI call to power off for hibernate

 Documentation/virt/kvm/api.rst       | 11 +++++++++
 arch/arm64/include/uapi/asm/kvm.h    |  6 +++++
 arch/arm64/kvm/hyp/nvhe/psci-relay.c |  2 ++
 arch/arm64/kvm/hypercalls.c          |  2 ++
 arch/arm64/kvm/psci.c                | 43 +++++++++++++++++++++++++++++++++++-
 drivers/firmware/psci/psci.c         | 35 +++++++++++++++++++++++++++++
 include/kvm/arm_psci.h               |  4 +++-
 include/uapi/linux/psci.h            | 20 +++++++++++++++++
 kernel/power/hibernate.c             |  5 ++++-
 9 files changed, 125 insertions(+), 3 deletions(-)

Comments

Oliver Upton March 19, 2024, 3:27 p.m. UTC | #1
On Tue, Mar 19, 2024 at 12:59:01PM +0000, David Woodhouse wrote:
> David Woodhouse (5):
>       firmware/psci: Add definitions for PSCI v1.3 specification (ALPHA)
>       KVM: arm64: Add support for PSCI v1.2 and v1.3
>       KVM: arm64: Add PSCI v1.3 SYSTEM_OFF2 function for hibernation
>       KVM: arm64: nvhe: Pass through PSCI v1.3 SYSTEM_OFF2 call
>       arm64: Use SYSTEM_OFF2 PSCI call to power off for hibernate

If we're going down the route of having this PSCI call live in KVM, it
really deserves a test. I think you can just pile on the existing
psci_test selftest.
David Woodhouse March 19, 2024, 5:14 p.m. UTC | #2
On Tue, 2024-03-19 at 08:27 -0700, Oliver Upton wrote:
> If we're going down the route of having this PSCI call live in KVM, it
> really deserves a test. I think you can just pile on the existing
> psci_test selftest.

Added to
https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/psci-hibernate
for next time.

From 8c72a78e6179bc8970edc66a85ab6bee26f581fb Mon Sep 17 00:00:00 2001
From: David Woodhouse <dwmw@amazon.co.uk>
Date: Tue, 19 Mar 2024 17:07:46 +0000
Subject: [PATCH 4/8] KVM: selftests: Add test for PSCI SYSTEM_OFF2

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 .../testing/selftests/kvm/aarch64/psci_test.c | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/tools/testing/selftests/kvm/aarch64/psci_test.c b/tools/testing/selftests/kvm/aarch64/psci_test.c
index 9b004905d1d3..1c1cf1580d70 100644
--- a/tools/testing/selftests/kvm/aarch64/psci_test.c
+++ b/tools/testing/selftests/kvm/aarch64/psci_test.c
@@ -54,6 +54,15 @@ static uint64_t psci_system_suspend(uint64_t entry_addr, uint64_t context_id)
 	return res.a0;
 }
 
+static uint64_t psci_system_off2(uint64_t type)
+{
+	struct arm_smccc_res res;
+
+	smccc_hvc(PSCI_1_3_FN64_SYSTEM_OFF2, type, 0, 0, 0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
 static uint64_t psci_features(uint32_t func_id)
 {
 	struct arm_smccc_res res;
@@ -188,11 +197,63 @@ static void host_test_system_suspend(void)
 	kvm_vm_free(vm);
 }
 
+static void guest_test_system_off2(void)
+{
+	uint64_t ret;
+
+	/* assert that SYSTEM_OFF2 is discoverable */
+	GUEST_ASSERT(psci_features(PSCI_1_3_FN_SYSTEM_OFF2) &
+		     (1UL << PSCI_1_3_HIBERNATE_TYPE_OFF));
+	GUEST_ASSERT(psci_features(PSCI_1_3_FN64_SYSTEM_OFF2) &
+		     (1UL << PSCI_1_3_HIBERNATE_TYPE_OFF));
+
+	ret = psci_system_off2(PSCI_1_3_HIBERNATE_TYPE_OFF);
+	GUEST_SYNC(ret);
+}
+
+static void host_test_system_off2(void)
+{
+	struct kvm_vcpu *source, *target;
+	uint64_t psci_version = 0;
+	struct kvm_run *run;
+	struct kvm_vm *vm;
+
+	vm = setup_vm(guest_test_system_off2, &source, &target);
+	vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION, &psci_version);
+	TEST_ASSERT(psci_version >= PSCI_VERSION(0, 2),
+		    "Unexpected PSCI version %lu.%lu",
+		    PSCI_VERSION_MAJOR(psci_version),
+		    PSCI_VERSION_MINOR(psci_version));
+
+	if (psci_version < PSCI_VERSION(1,3))
+		goto skip;
+
+	vcpu_power_off(target);
+	run = source->run;
+
+	enter_guest(source);
+
+	TEST_ASSERT_KVM_EXIT_REASON(source, KVM_EXIT_SYSTEM_EVENT);
+	TEST_ASSERT(run->system_event.type == KVM_SYSTEM_EVENT_SHUTDOWN,
+		    "Unhandled system event: %u (expected: %u)",
+		    run->system_event.type, KVM_SYSTEM_EVENT_SHUTDOWN);
+	TEST_ASSERT(run->system_event.ndata >= 1,
+		    "Unexpected amount of system event data: %u (expected, >= 1)",
+		    run->system_event.ndata);
+	TEST_ASSERT(run->system_event.data[0] & KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2,
+		    "PSCI_OFF2 flag not set. Flags %llu (expected %llu)",
+		    run->system_event.data[0], KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2);
+
+ skip:
+	kvm_vm_free(vm);
+}
+
 int main(void)
 {
 	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_SYSTEM_SUSPEND));
 
 	host_test_cpu_on();
 	host_test_system_suspend();
+	host_test_system_off2();
 	return 0;
 }
Oliver Upton March 19, 2024, 7:41 p.m. UTC | #3
On Tue, Mar 19, 2024 at 05:14:42PM +0000, David Woodhouse wrote:
> On Tue, 2024-03-19 at 08:27 -0700, Oliver Upton wrote:
> > If we're going down the route of having this PSCI call live in KVM, it
> > really deserves a test. I think you can just pile on the existing
> > psci_test selftest.
> 
> Added to
> https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/psci-hibernate
> for next time.
> 
> From 8c72a78e6179bc8970edc66a85ab6bee26f581fb Mon Sep 17 00:00:00 2001
> From: David Woodhouse <dwmw@amazon.co.uk>
> Date: Tue, 19 Mar 2024 17:07:46 +0000
> Subject: [PATCH 4/8] KVM: selftests: Add test for PSCI SYSTEM_OFF2
> 
> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>

Looks good, thanks!
David Woodhouse March 22, 2024, 10:17 a.m. UTC | #4
On Tue, 2024-03-19 at 12:41 -0700, Oliver Upton wrote:
> On Tue, Mar 19, 2024 at 05:14:42PM +0000, David Woodhouse wrote:
> > On Tue, 2024-03-19 at 08:27 -0700, Oliver Upton wrote:
> > > If we're going down the route of having this PSCI call live in KVM, it
> > > really deserves a test. I think you can just pile on the existing
> > > psci_test selftest.
> > 
> > Added to
> > https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/psci-hibernate
> > for next time.
> > 
> > From 8c72a78e6179bc8970edc66a85ab6bee26f581fb Mon Sep 17 00:00:00 2001
> > From: David Woodhouse <dwmw@amazon.co.uk>
> > Date: Tue, 19 Mar 2024 17:07:46 +0000
> > Subject: [PATCH 4/8] KVM: selftests: Add test for PSCI SYSTEM_OFF2
> > 
> > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
> 
> Looks good, thanks!

Thanks.

Marc, I think I've also addressed your feedback? Is there anything else
to do other than wait for the spec to be published?

Shall I post a v4 with PSCI v1.3 as default and the self-test? Would
you apply that into a branch ready for merging when the spec is ready,
or should I just wait and repost it all then?
Marc Zyngier March 22, 2024, 4:09 p.m. UTC | #5
On Fri, 22 Mar 2024 10:17:58 +0000,
David Woodhouse <dwmw2@infradead.org> wrote:
> 
> [1  <text/plain; UTF-8 (quoted-printable)>]
> On Tue, 2024-03-19 at 12:41 -0700, Oliver Upton wrote:
> > On Tue, Mar 19, 2024 at 05:14:42PM +0000, David Woodhouse wrote:
> > > On Tue, 2024-03-19 at 08:27 -0700, Oliver Upton wrote:
> > > > If we're going down the route of having this PSCI call live in KVM, it
> > > > really deserves a test. I think you can just pile on the existing
> > > > psci_test selftest.
> > > 
> > > Added to
> > > https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/psci-hibernate
> > > for next time.
> > > 
> > > From 8c72a78e6179bc8970edc66a85ab6bee26f581fb Mon Sep 17 00:00:00 2001
> > > From: David Woodhouse <dwmw@amazon.co.uk>
> > > Date: Tue, 19 Mar 2024 17:07:46 +0000
> > > Subject: [PATCH 4/8] KVM: selftests: Add test for PSCI SYSTEM_OFF2
> > > 
> > > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
> > 
> > Looks good, thanks!
> 
> Thanks.
> 
> Marc, I think I've also addressed your feedback? Is there anything else
> to do other than wait for the spec to be published?

Other than the couple of minor nits I mentioned in replies to the
individual patches, this looks good to me.

> Shall I post a v4 with PSCI v1.3 as default and the self-test? Would
> you apply that into a branch ready for merging when the spec is ready,
> or should I just wait and repost it all then?

I think this can wait for the final spec. I assume that you are
directly tracking this anyway, so we don't need to poll for the spec
update.

Thanks,

	M.
David Woodhouse March 22, 2024, 5:33 p.m. UTC | #6
On Fri, 2024-03-22 at 16:09 +0000, Marc Zyngier wrote:
> 
> > Marc, I think I've also addressed your feedback? Is there anything else
> > to do other than wait for the spec to be published?
> 
> Other than the couple of minor nits I mentioned in replies to the
> individual patches, this looks good to me.

I believe I've handled all that. And also Sudeep's implicit nudge to
use BIT() instead of manually shifting (1<<PSCI_1_3_HIBERNATE_TYPE_OFF).

Rebased onto 6.8 and pushed to
https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/psci-hibernate-6.8

> > Shall I post a v4 with PSCI v1.3 as default and the self-test? Would
> > you apply that into a branch ready for merging when the spec is ready,
> > or should I just wait and repost it all then?
> 
> I think this can wait for the final spec. I assume that you are
> directly tracking this anyway, so we don't need to poll for the spec
> update.

Indeed, will post again when the spec is published. Thanks.