For AMD SEV provide ioctl(2) in cpp(4) to shutdown guest.
authorbluhm <bluhm@openbsd.org>
Sun, 1 Sep 2024 19:25:06 +0000 (19:25 +0000)
committerbluhm <bluhm@openbsd.org>
Sun, 1 Sep 2024 19:25:06 +0000 (19:25 +0000)
To shutdown a SEV-enabled guest, first deactivate the guest context
in ccp(4), then decommission the guest context.  Combine these two
operations in a single ioctl to simplify guest shutdown for vmd(8).
As this ioctl does not directly map to a single ccp command, use a
high number for the ioctl.  More ioctls like this one will come.

from hshoexer@; OK mlarkin@

sys/dev/ic/ccp.c
sys/dev/ic/ccpvar.h

index 6829f81..42ae5f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ccp.c,v 1.8 2024/09/01 17:13:46 bluhm Exp $ */
+/*     $OpenBSD: ccp.c,v 1.9 2024/09/01 19:25:06 bluhm Exp $ */
 
 /*
  * Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
@@ -564,6 +564,29 @@ psp_deactivate(struct psp_deactivate *udeact)
        return (0);
 }
 
+int
+psp_guest_shutdown(struct psp_guest_shutdown *ugshutdown)
+{
+       struct psp_deactivate   deact;
+       struct psp_decommission decom;
+       int                     ret;
+
+       bzero(&deact, sizeof(deact));
+       deact.handle = ugshutdown->handle;
+       if ((ret = psp_deactivate(&deact)) != 0)
+               return (ret);
+
+       if ((ret = psp_df_flush()) != 0)
+               return (ret);
+
+       bzero(&decom, sizeof(decom));
+       decom.handle = ugshutdown->handle;
+       if ((ret = psp_decommission(&decom)) != 0)
+               return (ret);
+
+       return (0);
+}
+
 int
 psp_snp_get_pstatus(struct psp_snp_platform_status *ustatus)
 {
@@ -642,6 +665,9 @@ pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
        case PSP_IOC_DEACTIVATE:
                ret = psp_deactivate((struct psp_deactivate *)data);
                break;
+       case PSP_IOC_GUEST_SHUTDOWN:
+               ret = psp_guest_shutdown((struct psp_guest_shutdown *)data);
+               break;
        case PSP_IOC_SNP_GET_PSTATUS:
                ret =
                    psp_snp_get_pstatus((struct psp_snp_platform_status *)data);
@@ -668,6 +694,7 @@ pledge_ioctl_psp(struct proc *p, long com)
        case PSP_IOC_LAUNCH_MEASURE:
        case PSP_IOC_LAUNCH_FINISH:
        case PSP_IOC_ACTIVATE:
+       case PSP_IOC_GUEST_SHUTDOWN:
                return (0);
        default:
                return (pledge_fail(p, EPERM, PLEDGE_VMM));
index 65efe84..7add1e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ccpvar.h,v 1.3 2024/06/13 17:59:08 bluhm Exp $ */
+/*     $OpenBSD: ccpvar.h,v 1.4 2024/09/01 19:25:06 bluhm Exp $ */
 
 /*
  * Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
@@ -243,6 +243,11 @@ struct psp_init {
 } __packed;
 
 
+struct psp_guest_shutdown {
+       /* Input parameter for PSP_CMD_GUEST_SHUTDOWN */
+       uint32_t                handle;
+} __packed;
+
 /* Selection of PSP commands of the SEV-SNP ABI Version 1.55 */
 
 #define PSP_CMD_SNP_PLATFORMSTATUS     0x81
@@ -272,6 +277,7 @@ struct psp_snp_platform_status {
 #define PSP_IOC_ACTIVATE       _IOW('P', 9, struct psp_activate)
 #define PSP_IOC_DEACTIVATE     _IOW('P', 10, struct psp_deactivate)
 #define PSP_IOC_SNP_GET_PSTATUS        _IOR('P', 11, struct psp_snp_platform_status)
+#define PSP_IOC_GUEST_SHUTDOWN _IOW('P', 255, struct psp_guest_shutdown)
 #endif /* __amd64__ */
 
 #ifdef _KERNEL