Add the transport-agnostic Virtualization-Based Security (VBS) core: a small dispatch layer between the guest OS (plane-0) and a secure kernel running in a higher-privileged plane-1. Backends register a struct vbs_ops via vbs_register_backend(); the core exposes vbs_available() and a generic vbs_vtl_call() that forwards to the active backend. No backend is registered yet. Gated by CONFIG_VBS (off by default). --- include/linux/vbs.h | 74 +++++++++++++++++++++++++++++++++++++++++++ security/Kconfig | 2 ++ security/Makefile | 1 + security/vbs/Kconfig | 16 ++++++++++ security/vbs/Makefile | 3 ++ security/vbs/core.c | 56 ++++++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+) create mode 100644 include/linux/vbs.h create mode 100644 security/vbs/Kconfig create mode 100644 security/vbs/Makefile create mode 100644 security/vbs/core.c diff --git a/include/linux/vbs.h b/include/linux/vbs.h new file mode 100644 index 000000000000..a154396bf070 --- /dev/null +++ b/include/linux/vbs.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * VBS — Virtualization-Based Security + * + * Transport-agnostic interface between the guest OS (plane-0) and a secure + * kernel running in a higher-privileged plane-1. The guest kernel calls the + * vbs_*() functions; the active backend translates them into the appropriate + * transport (e.g. a KVM paravirt hypercall). + * + * This is the core framework only. VBS is software-only: backends are + * software/hypervisor planes (KVM software planes now, Hyper-V VSM later). + * Backends register via vbs_register_backend(). + */ + +#ifndef _LINUX_VBS_H +#define _LINUX_VBS_H + +#include +#include + +/* VTL-call request codes (plane-0 -> plane-1 direction). */ +enum vbs_call_id { + VBS_CALL_INIT = 0x0001, /* plane-0 boot complete: load plane */ + VBS_CALL_SHUTDOWN = 0x0002, /* plane-0 shutting down: unload */ +}; + +/** + * struct vbs_ops - operations provided by a VBS backend + * @name: backend name, e.g. "kvm-planes" + * @init: load/connect the secure plane; called once after drivers init + * @shutdown: unload the secure plane; called on reboot/halt + * @vtl_call: send an arbitrary request to the secure kernel and wait for a + * response. Returns 0 on success, negative errno on failure. + * + * Callbacks run from process context with preemption enabled. + */ +struct vbs_ops { + const char *name; + + int (*init)(void); + void (*shutdown)(void); + + int (*vtl_call)(enum vbs_call_id id, + const void *arg, size_t arg_size, + void *resp, size_t resp_size); +}; + +#ifdef CONFIG_VBS + +/** + * vbs_register_backend() - register the platform-specific backend. + * + * Called once during boot by the platform detection code. Only one backend + * can be active at a time. + */ +int vbs_register_backend(const struct vbs_ops *ops); + +/** vbs_available() - true if a backend is registered. */ +bool vbs_available(void); + +/** vbs_vtl_call() - dispatch a raw VTL call through the active backend. */ +int vbs_vtl_call(enum vbs_call_id id, + const void *arg, size_t arg_size, + void *resp, size_t resp_size); + +#else /* !CONFIG_VBS */ + +static inline bool vbs_available(void) { return false; } +static inline int vbs_vtl_call(enum vbs_call_id id, + const void *arg, size_t arg_size, + void *resp, size_t resp_size) { return -ENOSYS; } + +#endif /* CONFIG_VBS */ +#endif /* _LINUX_VBS_H */ diff --git a/security/Kconfig b/security/Kconfig index f7bf6cdc6229..31ab9b0fa7d0 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -299,6 +299,8 @@ config SECURITY_COMMONCAP_KUNIT_TEST If unsure, say N. +source "security/vbs/Kconfig" + source "security/Kconfig.hardening" endmenu diff --git a/security/Makefile b/security/Makefile index 4601230ba442..80214c702ddc 100644 --- a/security/Makefile +++ b/security/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_CGROUPS) += device_cgroup.o obj-$(CONFIG_BPF_LSM) += bpf/ obj-$(CONFIG_SECURITY_LANDLOCK) += landlock/ obj-$(CONFIG_SECURITY_IPE) += ipe/ +obj-$(CONFIG_VBS) += vbs/ # Object integrity file lists obj-$(CONFIG_INTEGRITY) += integrity/ diff --git a/security/vbs/Kconfig b/security/vbs/Kconfig new file mode 100644 index 000000000000..0e482196c5b7 --- /dev/null +++ b/security/vbs/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config VBS + bool "Virtualization-Based Security (VBS) support" + depends on X86_64 + help + Enable a transport-agnostic interface between the guest OS + (plane-0) and a secure kernel running in a higher-privileged + plane-1. + + The core VBS layer dispatches calls from kernel subsystems to a + platform-specific backend. VBS is software-only: backends are + software/hypervisor planes (KVM software planes now, Hyper-V VSM + later). Hardware confidential-compute is out of scope. + + If unsure, say N. diff --git a/security/vbs/Makefile b/security/vbs/Makefile new file mode 100644 index 000000000000..952c2b855465 --- /dev/null +++ b/security/vbs/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_VBS) += vbs.o +vbs-y := core.o diff --git a/security/vbs/core.c b/security/vbs/core.c new file mode 100644 index 000000000000..407d49a91b8f --- /dev/null +++ b/security/vbs/core.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * VBS — Virtualization-Based Security core + * + * Dispatches calls from guest kernel subsystems to the active + * platform-specific backend. + */ + +#include +#include +#include +#include + +static const struct vbs_ops *vbs_backend; +static DEFINE_MUTEX(vbs_lock); + +int vbs_register_backend(const struct vbs_ops *ops) +{ + int ret = 0; + + if (!ops || !ops->name) + return -EINVAL; + + mutex_lock(&vbs_lock); + if (vbs_backend) { + pr_err("vbs: backend \"%s\" already registered, rejecting \"%s\"\n", + vbs_backend->name, ops->name); + ret = -EBUSY; + } else { + vbs_backend = ops; + pr_info("vbs: registered backend \"%s\"\n", ops->name); + } + mutex_unlock(&vbs_lock); + return ret; +} +EXPORT_SYMBOL_GPL(vbs_register_backend); + +bool vbs_available(void) +{ + return READ_ONCE(vbs_backend) != NULL; +} +EXPORT_SYMBOL_GPL(vbs_available); + +int vbs_vtl_call(enum vbs_call_id id, + const void *arg, size_t arg_size, + void *resp, size_t resp_size) +{ + const struct vbs_ops *ops = READ_ONCE(vbs_backend); + + if (!ops) + return -ENODEV; + if (!ops->vtl_call) + return -EOPNOTSUPP; + return ops->vtl_call(id, arg, arg_size, resp, resp_size); +} +EXPORT_SYMBOL_GPL(vbs_vtl_call); -- 2.55.0