* Re: [PATCH v1 01/26] coco/tdx-host: Introduce a "tdx_host" device
From: Jonathan Cameron @ 2025-12-19 11:19 UTC (permalink / raw)
To: Xu Yilun
Cc: linux-coco, linux-pci, chao.gao, dave.jiang, baolu.lu, yilun.xu,
zhenzhong.duan, kvm, rick.p.edgecombe, dave.hansen,
dan.j.williams, kas, x86
In-Reply-To: <20251117022311.2443900-2-yilun.xu@linux.intel.com>
On Mon, 17 Nov 2025 10:22:45 +0800
Xu Yilun <yilun.xu@linux.intel.com> wrote:
> From: Chao Gao <chao.gao@intel.com>
>
> TDX depends on a platform firmware module that is invoked via instructions
> similar to vmenter (i.e. enter into a new privileged "root-mode" context to
> manage private memory and private device mechanisms). It is a software
> construct that depends on the CPU vmxon state to enable invocation of
> TDX-module ABIs. Unlike other Trusted Execution Environment (TEE) platform
> implementations that employ a firmware module running on a PCI device with
> an MMIO mailbox for communication, TDX has no hardware device to point to
> as the TEE Secure Manager (TSM).
>
> Create a virtual device not only to align with other implementations but
> also to make it easier to
>
> - expose metadata (e.g., TDX module version, seamldr version etc) to
> the userspace as device attributes
>
> - implement firmware uploader APIs which are tied to a device. This is
> needed to support TDX module runtime updates
>
> - enable TDX Connect which will share a common infrastructure with other
> platform implementations. In the TDX Connect context, every
> architecture has a TSM, represented by a PCIe or virtual device. The
> new "tdx_host" device will serve the TSM role.
>
> A faux device is used as for TDX because the TDX module is singular within
> the system and lacks associated platform resources. Using a faux device
> eliminates the need to create a stub bus.
>
> The call to tdx_enable() makes the new module independent of kvm_intel.ko.
> For example, TDX Connect may be used to established to PCIe link encryption
> even if a TVM is never launched. For now, just create the common loading
> infrastructure.
>
> [ Yilun: Remove unnecessary head files ]
> Co-developed-by: Xu Yilun <yilun.xu@linux.intel.com>
> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
LGTM
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
^ permalink raw reply
* Re: [PATCH v1 03/26] coco/tdx-host: Support Link TSM for TDX host
From: Jonathan Cameron @ 2025-12-19 11:18 UTC (permalink / raw)
To: Xu Yilun
Cc: linux-coco, linux-pci, chao.gao, dave.jiang, baolu.lu, yilun.xu,
zhenzhong.duan, kvm, rick.p.edgecombe, dave.hansen,
dan.j.williams, kas, x86
In-Reply-To: <20251117022311.2443900-4-yilun.xu@linux.intel.com>
On Mon, 17 Nov 2025 10:22:47 +0800
Xu Yilun <yilun.xu@linux.intel.com> wrote:
> Register a Link TSM instance to support host side TSM operations for
> TDISP, when the TDX Connect support bit is set by TDX Module in
> tdx_feature0.
>
> This is the main purpose of an independent tdx-host module out of TDX
> core. Recall that a TEE Security Manager (TSM) is a platform agent that
> speaks the TEE Device Interface Security Protocol (TDISP) to PCIe
> devices and manages private memory resources for the platform. An
> independent tdx-host module allows for device-security enumeration and
> initialization flows to be deferred from other TDX Module initialization
> requirements. Crucially, when / if TDX Module init moves earlier in x86
> initialization flow this driver is still guaranteed to run after IOMMU
> and PCI init (i.e. subsys_initcall() vs device_initcall()).
>
> The ability to unload the module, or unbind the driver is also useful
> for debug and coarse grained transitioning between PCI TSM operation and
> PCI CMA operation (native kernel PCI device authentication).
>
> For now this is the basic boilerplate with operation flows to be added
> later.
>
> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
> Co-developed-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
All very standard looking which is just what we want to see!
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
^ permalink raw reply
* Re: [RFC PATCH 4/5] firmware: smccc: register as platform driver
From: Sudeep Holla @ 2025-12-19 10:40 UTC (permalink / raw)
To: Vedashree Vidwans
Cc: salman.nabi, andre.przywara, Sudeep Holla, lpieralisi,
mark.rutland, ardb, chao.gao, linux-arm-kernel, linux-coco,
linux-kernel, sdonthineni, vsethi, vwadekar
In-Reply-To: <29248f8c-b57d-4818-851c-7905dc9f8317@nvidia.com>
On Fri, Dec 19, 2025 at 12:26:30AM -0800, Vedashree Vidwans wrote:
>
> On 12/9/25 03:47, Sudeep Holla wrote:
> > On Mon, Dec 08, 2025 at 10:13:14PM +0000, Vedashree Vidwans wrote:
> > > - Update driver to be in-built kernel module. This will ensure driver is
> > > installed in kernel and would not require any user intervention.
> > > - Register the LFA driver as a platform driver corresponding to
> > > 'armhf000' device. The driver will be invoked when the device is
> > > detected on a platform.
> > > - Add functionality to register LFA interrupt in the driver probe().
> > > This LFA IRQ number will be retrived from the LFA device node.
> > > - On IRQ, driver will query FW component details and trigger activation
> > > of capable and pending FW component. The driver will loop to update FW
> > > component details after every successful FW component activation.
> > > - Mutex synchronization is implemented to avoid concurrent LFA updates
> > > through interrupt and sysfs interfaces.
> > >
> > > Device node snippet from LFA spec[1]:
> > > fwu0 {
> > > compatible = "arm,armhf000";
> > > memory-region = <&fwu_payload>;
> > > interrupt-parent = <&ic>;
> > > interrupts = <0 100 1>; // SPI, Interrupt #100, Edge Rising
> > > };
> > >
> >
> > This will be gone in the latest beta of LFA, so please discuss and get
> > an agreement for the LFA device tree bindings.
> >
> > We don't just use ACPI HID as devicetree compatibles. There are more
> > aligned with ACPI CID IIUC but I don't expect you to use ACPI CID just to
> > match DT compatible as ACPI HID will be defined for LFA.
> >
> Thank you for your comment.
> Sorry I haven't completely understood the concern here. I am using the ACPI
> HID and device node compatible string provided by the LFA spec.
Yes I know, but take a look at updated specification please [1].
> Please find below ACPI and device tree node from the spec for reference.
Yes they are obsolete as they no longer align with the latest specification.
> In case the LFA spec is updated, I will revise the driver implementation.
Indeed, that is the expectation. That's exactly what I meant.
--
Regards,
Sudeep
[1] https://developer.arm.com/documentation/den0147/1-0bet1
^ permalink raw reply
* Re: [RFC PATCH 1/5] firmware: smccc: LFA: use smcc 1.2
From: Sudeep Holla @ 2025-12-19 10:37 UTC (permalink / raw)
To: Vedashree Vidwans
Cc: salman.nabi, andre.przywara, Sudeep Holla, lpieralisi,
mark.rutland, ardb, chao.gao, linux-arm-kernel, linux-coco,
linux-kernel, sdonthineni, vsethi, vwadekar
In-Reply-To: <b8fdec67-584f-492e-b2a7-8c932871f459@nvidia.com>
On Fri, Dec 19, 2025 at 12:47:52AM -0800, Vedashree Vidwans wrote:
>
>
> On 12/9/25 03:42, Sudeep Holla wrote:
> > On Mon, Dec 08, 2025 at 10:13:11PM +0000, Vedashree Vidwans wrote:
> > > Update driver to use SMCCC 1.2+ version as mentioned in the LFA spec.
> > >
> >
> > I would prefer if you work with Salman Nabi and get this incorporated
> > in the original patch by providing this as a review feedback.
> >
> > There is no point in having this independent of the original patch as it
> > is not yet merged.
> >
> > --
> > Regards,
> > Sudeep
>
> Thank you for the suggestion.
>
> Hi Salman,
> Could we come up with a strategy to combine the LFA driver patches? I have
> been working on this recently and I would be happy to revise all the patches
> so that we are followiing the specification from the start.
>
> Please let me know if you think of any other approach.
>
Ideally, you should comment directly on the original submission, outlining the
specific changes you would like to see - just as you would when reviewing a
patch. This helps document your requests clearly and allows the author to
address them and post a revised version, ensuring that all changes are
properly tracked on the mailing list.
--
Regards,
Sudeep
^ permalink raw reply
* Re: [RFC PATCH 0/5] Arm LFA: Improvements and interrupt support
From: Sudeep Holla @ 2025-12-19 10:32 UTC (permalink / raw)
To: Vedashree Vidwans
Cc: salman.nabi, andre.przywara, Sudeep Holla, lpieralisi,
mark.rutland, ardb, chao.gao, linux-arm-kernel, linux-coco,
linux-kernel, sdonthineni, vsethi, vwadekar
In-Reply-To: <8bca8c4b-52b8-4a1d-9f21-176c994a58bb@nvidia.com>
On Fri, Dec 19, 2025 at 12:38:39AM -0800, Vedashree Vidwans wrote:
>
>
> On 12/9/25 03:39, Sudeep Holla wrote:
> > On Mon, Dec 08, 2025 at 10:13:10PM +0000, Vedashree Vidwans wrote:
> > > Hello,
> > >
> > > The patches update the proposed Arm Live Firmware Activation (LFA)
> > > kernel driver [1] to incorporate review feedback [2] and refine the
> > > activation flow while remaining aligned with the LFA specification
> > > DEN0147 [3] and the SMCCC 1.2 calling convention. The series keeps
> > > the existing functionality but restructures and extends it to improve
> > > robustness, reviewability, and future extensibility.
> > >
> > > The SMCCC usage in the driver is updated to consistently use the
> > > SMCCC 1.2 register-based calling convention, consolidating arguments
> > > and results into a single struct to reduce stack usage and simplify
> > > the SMC interface. The patches also split the original changes into
> > > focused pieces and document the device node bindings in the commit
> > > messages, making it easier to follow and validate the implementation
> > > against the specification.
> > >
> > > The kernel driver is registered as a platform driver in accordence to
> > > the LFA device defined by the specification [3]. The driver now extends
> > > interface for interrupt-based enablement of LFA. During LFA, the
> > > interrupt
> > > thread refreshes firmware component details after each activation step
> > > and iterates over all activable components until no further activation
> > > is pending, matching the spec’s allowance for component detail changes
> > > after activation. This ensures that sysfs exposure of LFA components
> > > remains consistent with the authoritative information provided by the
> > > secure firmware.
> > >
> > > The handling of CPU rendezvous is adjusted so that the kernel now
> > > honors the rendezvous policy chosen by the firmware, instead of
> > > unconditionally forcing a rendezvous. This reflects experience with
> > > existing firmware deployments where mandatory rendezvous is not
> > > required, while still allowing the firmware to request it when
> > > needed.
> > >
> > > Thank you,
> > > Veda
> > >
> > > [1] https://lore.kernel.org/lkml/20250926123145.268728-1-salman.nabi@arm.com/
> > > [2] https://lkml.org/lkml/2025/10/8/980
> > > [3] https://developer.arm.com/documentation/den0147/latest/
> > >
> > > Vedashree Vidwans (5):
> > > firmware: smccc: LFA: use smcc 1.2
> > > firmware: smccc: LFA: refactor
> > > firmware: smccc: add timeout, touch wdt
> > > firmware: smccc: register as platform driver
> > > firmware: smccc: lfa: refresh fw details
> > >
> > > drivers/firmware/smccc/Kconfig | 3 +-
> > > drivers/firmware/smccc/lfa_fw.c | 478 +++++++++++++++++++++++++-------
> >
> > Same comment as before[1], looks like the feedback got ignored or missed.
> >
> > --
> > Regards,
> > Sudeep
> >
> > [1]https://lore.kernel.org/all/20251009-calculating-glorious-oriole-ceccf6@sudeepholla
>
> Thank you for your comment.
> I did include DT binding in commit message of the patch. Please let me know
> if there's anything else I can elaborate.
>
Sure. I meant I don't see any patch titled "dt-bindings: firmware: Add LFA...."
or something similar. I also checked the delta for the files under
Documentation/devicetree/bindings/ to rule out the possibility that the
patch title may not be following the DT binding upstreaming process.
--
Regards,
Sudeep
^ permalink raw reply
* Re: [RFC PATCH 1/5] firmware: smccc: LFA: use smcc 1.2
From: Vedashree Vidwans @ 2025-12-19 8:47 UTC (permalink / raw)
To: Sudeep Holla, salman.nabi
Cc: andre.przywara, lpieralisi, mark.rutland, ardb, chao.gao,
linux-arm-kernel, linux-coco, linux-kernel, sdonthineni, vsethi,
vwadekar
In-Reply-To: <20251209-curvy-walrus-of-wonder-dbb178@sudeepholla>
On 12/9/25 03:42, Sudeep Holla wrote:
> On Mon, Dec 08, 2025 at 10:13:11PM +0000, Vedashree Vidwans wrote:
>> Update driver to use SMCCC 1.2+ version as mentioned in the LFA spec.
>>
>
> I would prefer if you work with Salman Nabi and get this incorporated
> in the original patch by providing this as a review feedback.
>
> There is no point in having this independent of the original patch as it
> is not yet merged.
>
> --
> Regards,
> Sudeep
Thank you for the suggestion.
Hi Salman,
Could we come up with a strategy to combine the LFA driver patches? I
have been working on this recently and I would be happy to revise all
the patches so that we are followiing the specification from the start.
Please let me know if you think of any other approach.
Regards,
Veda
^ permalink raw reply
* Re: [RFC PATCH 0/5] Arm LFA: Improvements and interrupt support
From: Vedashree Vidwans @ 2025-12-19 8:38 UTC (permalink / raw)
To: Sudeep Holla
Cc: salman.nabi, andre.przywara, lpieralisi, mark.rutland, ardb,
chao.gao, linux-arm-kernel, linux-coco, linux-kernel, sdonthineni,
vsethi, vwadekar
In-Reply-To: <20251209-miniature-curassow-of-energy-b6a303@sudeepholla>
On 12/9/25 03:39, Sudeep Holla wrote:
> On Mon, Dec 08, 2025 at 10:13:10PM +0000, Vedashree Vidwans wrote:
>> Hello,
>>
>> The patches update the proposed Arm Live Firmware Activation (LFA)
>> kernel driver [1] to incorporate review feedback [2] and refine the
>> activation flow while remaining aligned with the LFA specification
>> DEN0147 [3] and the SMCCC 1.2 calling convention. The series keeps
>> the existing functionality but restructures and extends it to improve
>> robustness, reviewability, and future extensibility.
>>
>> The SMCCC usage in the driver is updated to consistently use the
>> SMCCC 1.2 register-based calling convention, consolidating arguments
>> and results into a single struct to reduce stack usage and simplify
>> the SMC interface. The patches also split the original changes into
>> focused pieces and document the device node bindings in the commit
>> messages, making it easier to follow and validate the implementation
>> against the specification.
>>
>> The kernel driver is registered as a platform driver in accordence to
>> the LFA device defined by the specification [3]. The driver now extends
>> interface for interrupt-based enablement of LFA. During LFA, the
>> interrupt
>> thread refreshes firmware component details after each activation step
>> and iterates over all activable components until no further activation
>> is pending, matching the spec’s allowance for component detail changes
>> after activation. This ensures that sysfs exposure of LFA components
>> remains consistent with the authoritative information provided by the
>> secure firmware.
>>
>> The handling of CPU rendezvous is adjusted so that the kernel now
>> honors the rendezvous policy chosen by the firmware, instead of
>> unconditionally forcing a rendezvous. This reflects experience with
>> existing firmware deployments where mandatory rendezvous is not
>> required, while still allowing the firmware to request it when
>> needed.
>>
>> Thank you,
>> Veda
>>
>> [1] https://lore.kernel.org/lkml/20250926123145.268728-1-salman.nabi@arm.com/
>> [2] https://lkml.org/lkml/2025/10/8/980
>> [3] https://developer.arm.com/documentation/den0147/latest/
>>
>> Vedashree Vidwans (5):
>> firmware: smccc: LFA: use smcc 1.2
>> firmware: smccc: LFA: refactor
>> firmware: smccc: add timeout, touch wdt
>> firmware: smccc: register as platform driver
>> firmware: smccc: lfa: refresh fw details
>>
>> drivers/firmware/smccc/Kconfig | 3 +-
>> drivers/firmware/smccc/lfa_fw.c | 478 +++++++++++++++++++++++++-------
>
> Same comment as before[1], looks like the feedback got ignored or missed.
>
> --
> Regards,
> Sudeep
>
> [1]https://lore.kernel.org/all/20251009-calculating-glorious-oriole-
> ceccf6@sudeepholla
Thank you for your comment.
I did include DT binding in commit message of the patch. Please let me
know if there's anything else I can elaborate.
Regards,
Veda
^ permalink raw reply
* Re: [RFC PATCH 4/5] firmware: smccc: register as platform driver
From: Vedashree Vidwans @ 2025-12-19 8:26 UTC (permalink / raw)
To: Sudeep Holla
Cc: salman.nabi, andre.przywara, lpieralisi, mark.rutland, ardb,
chao.gao, linux-arm-kernel, linux-coco, linux-kernel, sdonthineni,
vsethi, vwadekar
In-Reply-To: <20251209-hysterical-cobalt-viper-54433c@sudeepholla>
On 12/9/25 03:47, Sudeep Holla wrote:
> On Mon, Dec 08, 2025 at 10:13:14PM +0000, Vedashree Vidwans wrote:
>> - Update driver to be in-built kernel module. This will ensure driver is
>> installed in kernel and would not require any user intervention.
>> - Register the LFA driver as a platform driver corresponding to
>> 'armhf000' device. The driver will be invoked when the device is
>> detected on a platform.
>> - Add functionality to register LFA interrupt in the driver probe().
>> This LFA IRQ number will be retrived from the LFA device node.
>> - On IRQ, driver will query FW component details and trigger activation
>> of capable and pending FW component. The driver will loop to update FW
>> component details after every successful FW component activation.
>> - Mutex synchronization is implemented to avoid concurrent LFA updates
>> through interrupt and sysfs interfaces.
>>
>> Device node snippet from LFA spec[1]:
>> fwu0 {
>> compatible = "arm,armhf000";
>> memory-region = <&fwu_payload>;
>> interrupt-parent = <&ic>;
>> interrupts = <0 100 1>; // SPI, Interrupt #100, Edge Rising
>> };
>>
>
> This will be gone in the latest beta of LFA, so please discuss and get
> an agreement for the LFA device tree bindings.
>
> We don't just use ACPI HID as devicetree compatibles. There are more
> aligned with ACPI CID IIUC but I don't expect you to use ACPI CID just to
> match DT compatible as ACPI HID will be defined for LFA.
>
Thank you for your comment.
Sorry I haven't completely understood the concern here. I am using the
ACPI HID and device node compatible string provided by the LFA spec.
Please find below ACPI and device tree node from the spec for reference.
In case the LFA spec is updated, I will revise the driver implementation.
LFA spec: https://developer.arm.com/documentation/den0147/latest/
ACPI node:
DefinitionBlock ("", "SSDT", 2, "XXXXXX", "XXXXXXXX", 1) {
Scope (\_SB)
{
Device (FWU0) {
Name (_HID, "ARMHF000") // Arm HAFW DSDT table identifier.
Name (_CRS, ResourceTemplate () {
// Payload buffer description.
QWordMemory (,
,
MinFixed,
MaxFixed,
NonCacheable,
ReadWrite,
0x0,
0x2000, // base PA of payload buffer
0x2FFF, // top PA of payload buffer
0,
0x1000, // payload buffer length
,
,
)
// Interrupt signaling the updated Live Activation Store.
Interrupt(,
Edge, // Interrupt type (or interrupt mode)
ActiveHigh, // Interrupt level
,
,
,
) {100} // Note that this is an example interrupt.
// The interrupt ID is defined per-platform.
})
// _DSD -- Holds map between field names and objects within
the _CRS
Name (_DSD, Package () {
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa30") ,
Package() {
// Contains a set of packages of 2 entries each,
// the second entry is an index into the _CRS.
Package (2) {"payload-buffer", 1},
Package (2) {"fw-store-updated-interrupt", 2},
},
})
}
}
}
Device Tree node:
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <2>;
ic: interrupt-controller@2f000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
#address-cells = <2>;
#size-cells = <2>;
interrupt-controller;
reg = <0x0 0x2f000000 0x0 0x10000>,
<0x0 0x2f100000 0x0 0x200000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
fwu_payload: fwu_payload@2000 {
reg = <0x0 0x2000 0x0 0x1000>;
no-map;
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
ranges;
fwu0 {
compatible = "arm,armhf000";
memory-region = <&fwu_payload>;
interrupt-parent = <&ic>;
interrupts = <0 100 1>; // SPI, Interrupt #100, Edge Rising
};
};
};
>> [1] https://developer.arm.com/documentation/den0147/latest/
>>
>> Signed-off-by: Vedashree Vidwans <vvidwans@nvidia.com>
>> ---
>> drivers/firmware/smccc/Kconfig | 3 +-
>> drivers/firmware/smccc/lfa_fw.c | 124 +++++++++++++++++++++++++++++++-
>> 2 files changed, 125 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/firmware/smccc/Kconfig b/drivers/firmware/smccc/Kconfig
>> index 48b98c14f770..c21be43fbfed 100644
>> --- a/drivers/firmware/smccc/Kconfig
>> +++ b/drivers/firmware/smccc/Kconfig
>> @@ -25,8 +25,9 @@ config ARM_SMCCC_SOC_ID
>> platforms providing some sysfs information about the SoC variant.
>>
>> config ARM_LFA
>> - tristate "Arm Live Firmware activation support"
>> + bool "Arm Live Firmware activation support"
>> depends on HAVE_ARM_SMCCC_DISCOVERY
>> + default y
>> help
>> Include support for triggering Live Firmware Activation, which
>> allows to upgrade certain firmware components without a reboot.
>> diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_fw.c
>> index 0e420cefa260..24916fc53420 100644
>> --- a/drivers/firmware/smccc/lfa_fw.c
>> +++ b/drivers/firmware/smccc/lfa_fw.c
>> @@ -19,7 +19,12 @@
>> #include <linux/nmi.h>
>> #include <linux/ktime.h>
>> #include <linux/delay.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/acpi.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/mutex.h>
>>
>> +#define DRIVER_NAME "ARM_LFA"
>> #define LFA_ERROR_STRING(name) \
>> [name] = #name
>> #undef pr_fmt
>> @@ -129,6 +134,7 @@ static const struct fw_image_uuid {
>> };
>>
>> static struct kobject *lfa_dir;
>> +static DEFINE_MUTEX(lfa_lock);
>>
>> static int get_nr_lfa_components(void)
>> {
>> @@ -374,17 +380,23 @@ static ssize_t activate_store(struct kobject *kobj, struct kobj_attribute *attr,
>> image_attrs[LFA_ATTR_ACTIVATE]);
>> int ret;
>>
>> + if (!mutex_trylock(&lfa_lock)) {
>> + pr_err("Mutex locked, try again");
>> + return -EAGAIN;
>> + }
>> +
>> ret = activate_fw_image(attrs);
>> if (ret) {
>> pr_err("Firmware activation failed: %s\n",
>> lfa_error_strings[-ret]);
>> -
>> + mutex_unlock(&lfa_lock);
>> return -ECANCELED;
>> }
>>
>> pr_info("Firmware activation succeeded\n");
>>
>> /* TODO: refresh image flags here*/
>> + mutex_unlock(&lfa_lock);
>> return count;
>> }
>>
>> @@ -510,6 +522,106 @@ static int create_fw_images_tree(void)
>> return 0;
>> }
>>
>> +static irqreturn_t lfa_irq_thread(int irq, void *data)
>> +{
>> + struct image_props *attrs = NULL;
>> + int ret;
>> + int num_of_components, curr_component;
>> +
>> + mutex_lock(&lfa_lock);
>> +
>> + /*
>> + * As per LFA spec, after activation of a component, the caller
>> + * is expected to re-enumerate the component states (using
>> + * LFA_GET_INFO then LFA_GET_INVENTORY).
>> + * Hence we need an unconditional loop.
>> + */
>> +
>> + do {
>> + /* TODO: refresh image flags here */
>> + /* If refresh fails goto exit_unlock */
>> +
>> + /* Initialize counters to track list traversal */
>> + num_of_components = get_nr_lfa_components();
>> + curr_component = 0;
>> +
>> + /* Execute PRIME and ACTIVATE for activable FW component */
>> + list_for_each_entry(attrs, &lfa_fw_images, image_node) {
>> + curr_component++;
>> + if ((!attrs->activation_capable) || (!attrs->activation_pending)) {
>> + /* LFA not applicable for this FW component */
>> + continue;
>> + }
>> +
>> + ret = activate_fw_image(attrs);
>> + if (ret) {
>> + pr_err("Firmware %s activation failed: %s\n",
>> + attrs->image_name, lfa_error_strings[-ret]);
>> + goto exit_unlock;
>> + }
>> +
>> + pr_info("Firmware %s activation succeeded", attrs->image_name);
>> + /* Refresh FW component details */
>> + break;
>> + }
>> + } while (curr_component < num_of_components);
>> +
>> + /* TODO: refresh image flags here */
>> + /* If refresh fails goto exit_unlock */
>> +
>> +exit_unlock:
>> + mutex_unlock(&lfa_lock);
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int __init lfa_probe(struct platform_device *pdev)
>> +{
>> + int err;
>> + unsigned int irq;
>> +
>> + err = platform_get_irq_byname_optional(pdev, "fw-store-updated-interrupt");
>
> Nice, "fw-store-updated-interrupt" is not even mentioned in the example DT
> node above, let alone proper DT bindings.
>
Thank you for pointing this out. The DT binding would have to be updated
to below or the driver will fall back to platform_get_irq().
fwu0 {
compatible = "arm,armhf000";
memory-region = <&fwu_payload>;
interrupt-parent = <&ic>;
interrupts = <0 100 1>; // SPI, Interrupt #100, Edge Rising
interrupt-names = "fw-store-updated-interrupt";
};
Regards,
Veda
^ permalink raw reply
* Re: [PATCH v2 2/7] KVM: x86: Extract VMXON and EFER.SVME enablement to kernel
From: Xu Yilun @ 2025-12-19 2:14 UTC (permalink / raw)
To: Sean Christopherson
Cc: Chao Gao, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, Kiryl Shutsemau, Paolo Bonzini, linux-kernel,
linux-coco, kvm, Dan Williams
In-Reply-To: <aUL-J-MvdCrCtDp4@google.com>
On Wed, Dec 17, 2025 at 11:01:59AM -0800, Sean Christopherson wrote:
> On Wed, Dec 17, 2025, Xu Yilun wrote:
> > > >+#define x86_virt_call(fn) \
> > > >+({ \
> > > >+ int __r; \
> > > >+ \
> > > >+ if (IS_ENABLED(CONFIG_KVM_INTEL) && \
> > > >+ cpu_feature_enabled(X86_FEATURE_VMX)) \
> > > >+ __r = x86_vmx_##fn(); \
> > > >+ else if (IS_ENABLED(CONFIG_KVM_AMD) && \
> > > >+ cpu_feature_enabled(X86_FEATURE_SVM)) \
> > > >+ __r = x86_svm_##fn(); \
> > > >+ else \
> > > >+ __r = -EOPNOTSUPP; \
> > > >+ \
> > > >+ __r; \
> > > >+})
> > > >+
> > > >+int x86_virt_get_cpu(int feat)
> > > >+{
> > > >+ int r;
> > > >+
> > > >+ if (!x86_virt_feature || x86_virt_feature != feat)
> > > >+ return -EOPNOTSUPP;
> > > >+
> > > >+ if (this_cpu_inc_return(virtualization_nr_users) > 1)
> > > >+ return 0;
> > >
> > > Should we assert that preemption is disabled? Calling this API when preemption
> > > is enabled is wrong.
> > >
> > > Maybe use __this_cpu_inc_return(), which already verifies preemption status.
>
> I always forget that the double-underscores have the checks.
>
> > Is it better we explicitly assert the preemption for x86_virt_get_cpu()
> > rather than embed the check in __this_cpu_inc_return()? We are not just
> > protecting the racing for the reference counter. We should ensure the
> > "counter increase + x86_virt_call(get_cpu)" can't be preempted.
>
> I don't have a strong preference. Using __this_cpu_inc_return() without any
> nearby preemption_{enable,disable}() calls makes it quite clears that preemption
> is expected to be disabled by the caller. But I'm also ok being explicit.
Looking into __this_cpu_inc_return(), it finally calls
check_preemption_disabled() which doesn't strictly requires preemption.
It only ensures the context doesn't switch to another CPU. If the caller
is in cpuhp context, preemption is possible.
But in this x86_virt_get_cpu(), we need to ensure preemption disabled,
otherwise caller A increases counter but hasn't do actual VMXON yet and
get preempted. Caller B opts in and get the wrong info that VMX is
already on, and fails on following vmx operations.
On a second thought, maybe we disable preemption inside
x86_virt_get_cpu() to protect the counter-vmxon racing, this is pure
internal thing for this kAPI.
Thanks,
Yilun
^ permalink raw reply
* Re: [PATCH v2 0/5] KVM: guest_memfd: Rework preparation/population flows in prep for in-place conversion
From: Huang, Kai @ 2025-12-18 22:55 UTC (permalink / raw)
To: kvm@vger.kernel.org, michael.roth@amd.com
Cc: david@redhat.com, liam.merwick@oracle.com, seanjc@google.com,
aik@amd.com, linux-mm@kvack.org, Annapurve, Vishal,
linux-kernel@vger.kernel.org, thomas.lendacky@amd.com,
vbabka@suse.cz, ashish.kalra@amd.com, linux-coco@lists.linux.dev,
Weiny, Ira, pbonzini@redhat.com, ackerleytng@google.com,
Zhao, Yan Y
In-Reply-To: <20251215153411.3613928-1-michael.roth@amd.com>
On Mon, 2025-12-15 at 09:34 -0600, Michael Roth wrote:
> Known issues / TODO
> -------------------
>
> - Compile-tested only for the TDX bits (testing/feedback welcome!)
Applied this series to 6.19-rc1, and tested booting/destroying TD worked
fine, so:
Tested-by: Kai Huang <kai.huang@intel.com>
^ permalink raw reply
* Re: [PATCH v2 2/5] KVM: guest_memfd: Remove preparation tracking
From: Huang, Kai @ 2025-12-18 22:53 UTC (permalink / raw)
To: kvm@vger.kernel.org, michael.roth@amd.com
Cc: david@redhat.com, liam.merwick@oracle.com, seanjc@google.com,
aik@amd.com, linux-mm@kvack.org, Annapurve, Vishal,
linux-kernel@vger.kernel.org, thomas.lendacky@amd.com,
vbabka@suse.cz, ashish.kalra@amd.com, linux-coco@lists.linux.dev,
Weiny, Ira, pbonzini@redhat.com, ackerleytng@google.com,
Zhao, Yan Y
In-Reply-To: <20251215153411.3613928-3-michael.roth@amd.com>
> /*
> * Process @folio, which contains @gfn, so that the guest can use it.
> * The folio must be locked and the gfn must be contained in @slot.
> @@ -90,13 +85,7 @@ static inline void kvm_gmem_mark_prepared(struct folio *folio)
> static int kvm_gmem_prepare_folio(struct kvm *kvm, struct kvm_memory_slot *slot,
> gfn_t gfn, struct folio *folio)
> {
> - unsigned long nr_pages, i;
> pgoff_t index;
> - int r;
> -
> - nr_pages = folio_nr_pages(folio);
> - for (i = 0; i < nr_pages; i++)
> - clear_highpage(folio_page(folio, i));
>
Here the entire folio is cleared, but ...
[...]
> - folio = __kvm_gmem_get_pfn(file, slot, index, pfn, &is_prepared, max_order);
> + folio = __kvm_gmem_get_pfn(file, slot, index, pfn, max_order);
> if (IS_ERR(folio))
> return PTR_ERR(folio);
>
> - if (!is_prepared)
> - r = kvm_gmem_prepare_folio(kvm, slot, gfn, folio);
> + if (!folio_test_uptodate(folio)) {
> + clear_highpage(folio_page(folio, 0));
> + folio_mark_uptodate(folio);
> + }
... here only the first page is cleared.
I understand currently there's no huge folio coming out of gmem now, but
since both __kvm_gmem_get_pfn() and kvm_gmem_get_pfn() still have
@max_level as output, it's kinda inconsistent here.
I also see kvm_gmem_fault_user_mapping() only clears the first page too,
but I think that already has assumption that folio can never be huge
currently?
Given this, and the fact that the first patch of this series has
introduced
WARN_ON_ONCE(folio_order(folio));
in kvm_gmem_get_folio(), I think it's fine to only clear the first page,
but for the sake of consistency, perhaps we should just remove @max_order
from __kvm_gmem_get_pfn() and kvm_gmem_get_pfn()?
Then we can handle huge folio logic when that comes to play.
Btw:
I actually looked into the RFC v1 discussion but the code there actually
does a loop to clear all pages in the folio. There were some other
discussions about AFAICT they were more related to issues regarding to
"mark entire folio as uptodate while only one page is processed in
post_populate()".
Btw2:
There was also discussion that clearing page isn't required for TDX. To
that end, maybe we can remove clearing page from gmem common code but to
SEV code, e.g., as part of "folio preparation"?
^ permalink raw reply
* Re: [PATCH v2 5/5] KVM: guest_memfd: GUP source pages prior to populating guest memory
From: Huang, Kai @ 2025-12-18 22:24 UTC (permalink / raw)
To: kvm@vger.kernel.org, michael.roth@amd.com
Cc: david@redhat.com, liam.merwick@oracle.com, seanjc@google.com,
aik@amd.com, linux-mm@kvack.org, Annapurve, Vishal,
linux-kernel@vger.kernel.org, thomas.lendacky@amd.com,
vbabka@suse.cz, ashish.kalra@amd.com, linux-coco@lists.linux.dev,
Weiny, Ira, pbonzini@redhat.com, ackerleytng@google.com,
Zhao, Yan Y
In-Reply-To: <20251215153411.3613928-6-michael.roth@amd.com>
On Mon, 2025-12-15 at 09:34 -0600, Michael Roth wrote:
> Currently the post-populate callbacks handle copying source pages into
> private GPA ranges backed by guest_memfd, where kvm_gmem_populate()
> acquires the filemap invalidate lock, then calls a post-populate
> callback which may issue a get_user_pages() on the source pages prior to
> copying them into the private GPA (e.g. TDX).
>
> This will not be compatible with in-place conversion, where the
> userspace page fault path will attempt to acquire filemap invalidate
> lock while holding the mm->mmap_lock, leading to a potential ABBA
> deadlock[1].
Nit: there's no link to mention [1].
[...]
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Co-developed-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> Co-developed-by: Vishal Annapurve <vannapurve@google.com>
> Signed-off-by: Vishal Annapurve <vannapurve@google.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
>
[...]
> + if (src_page) {
> + void *src_vaddr = kmap_local_pfn(page_to_pfn(src_page));
Nit: maybe you can use kmap_local_page(src_page) directly.
> + void *dst_vaddr = kmap_local_pfn(pfn);
>
> - if (copy_from_user(vaddr, src, PAGE_SIZE)) {
> - ret = -EFAULT;
> - goto out;
> - }
> - kunmap_local(vaddr);
> + memcpy(dst_vaddr, src_vaddr, PAGE_SIZE);
> +
> + kunmap_local(src_vaddr);
> + kunmap_local(dst_vaddr);
> }
>
> ret = rmp_make_private(pfn, gfn << PAGE_SHIFT, PG_LEVEL_4K,
> @@ -2325,17 +2325,19 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
> if (ret && !snp_page_reclaim(kvm, pfn) &&
> sev_populate_args->type == KVM_SEV_SNP_PAGE_TYPE_CPUID &&
> sev_populate_args->fw_error == SEV_RET_INVALID_PARAM) {
> - void *vaddr = kmap_local_pfn(pfn);
> + void *src_vaddr = kmap_local_pfn(page_to_pfn(src_page));
Ditto.
^ permalink raw reply
* Re: [RFC PATCH 4/5] firmware: smccc: register as platform driver
From: Vedashree Vidwans @ 2025-12-18 21:41 UTC (permalink / raw)
To: Matt Ochs
Cc: salman.nabi@arm.com, sudeep.holla@arm.com, andre.przywara@arm.com,
lpieralisi@kernel.org, mark.rutland@arm.com,
linux-kernel@vger.kernel.org, Varun Wadekar, Shanker Donthineni,
Vikram Sethi, linux-coco@lists.linux.dev, ardb@kernel.org,
linux-arm-kernel@lists.infradead.org, chao.gao@intel.com
In-Reply-To: <7E7A2433-67DC-4AED-94E0-E096DA9CF3EB@nvidia.com>
On 12/12/25 07:31, Matt Ochs wrote:
>> On Dec 8, 2025, at 16:13, Vedashree Vidwans <vvidwans@nvidia.com> wrote:
>>
>> diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_fw.c
>> index 0e420cefa260..24916fc53420 100644
>> --- a/drivers/firmware/smccc/lfa_fw.c
>> +++ b/drivers/firmware/smccc/lfa_fw.c
> ...
>> +
>> +static int __init lfa_probe(struct platform_device *pdev)
>> +{
>
> WARNING: modpost: vmlinux: section mismatch in reference: lfa_driver+0x0 (section: .data) -> lfa_probe (section: .init.text)
>
> __init is not needed here, please remove.
Thank you, I will include this change in next update.
Veda
^ permalink raw reply
* Re: [RFC PATCH 5/5] firmware: smccc: lfa: refresh fw details
From: Vedashree Vidwans @ 2025-12-18 21:40 UTC (permalink / raw)
To: Matt Ochs
Cc: salman.nabi@arm.com, sudeep.holla@arm.com, andre.przywara@arm.com,
lpieralisi@kernel.org, mark.rutland@arm.com,
linux-kernel@vger.kernel.org, Varun Wadekar, Shanker Donthineni,
Vikram Sethi, linux-coco@lists.linux.dev, ardb@kernel.org,
linux-arm-kernel@lists.infradead.org, chao.gao@intel.com
In-Reply-To: <44635975-326C-4DD2-BCEC-EB04188E954A@nvidia.com>
On 12/12/25 07:37, Matt Ochs wrote:
>> On Dec 8, 2025, at 16:13, Vedashree Vidwans <vvidwans@nvidia.com> wrote:
>>
>> diff --git a/drivers/firmware/smccc/lfa_fw.c b/drivers/firmware/smccc/lfa_fw.c
>> index 24916fc53420..334090708405 100644
>> --- a/drivers/firmware/smccc/lfa_fw.c
>> +++ b/drivers/firmware/smccc/lfa_fw.c
> ...
>> + /*
>> + * Pass 2:
>> + * If current FW components number is more than previous list, add new component nodes.
>> + */
>> + for (node_idx; node_idx < num_of_components; node_idx++) {
>
> drivers/firmware/smccc/lfa_fw.c: In function ‘update_fw_images_tree’:
> drivers/firmware/smccc/lfa_fw.c:554:9: warning: statement with no effect [-Wunused-value]
> 554 | for (node_idx; node_idx < num_of_components; node_idx++) {
> | ^~~
>
> Please drop “node_idx” from the initializer statement.
>
Thank you, I will include this change in next update.
Veda
^ permalink raw reply
* Re: [PATCH v4] page_alloc: allow migration of smaller hugepages during contig_alloc
From: Gregory Price @ 2025-12-18 15:40 UTC (permalink / raw)
To: David Hildenbrand (Red Hat)
Cc: Frank van der Linden, Johannes Weiner, linux-mm, kernel-team,
linux-kernel, akpm, vbabka, surenb, mhocko, jackmanb, ziy, kas,
dave.hansen, rick.p.edgecombe, muchun.song, osalvador, x86,
linux-coco, kvm, Wei Yang, David Rientjes, Joshua Hahn
In-Reply-To: <b5a925c5-523e-41e1-a3ce-0bb51ce0e995@kernel.org>
On Wed, Dec 03, 2025 at 08:43:29PM +0100, David Hildenbrand (Red Hat) wrote:
> > Yeah, the function itself makes sense: "check if this is actually a
> > contiguous range available within this zone, so no holes and/or
> > reserved pages".
> >
> > The PageHuge() check seems a bit out of place there, if you just
> > removed it altogether you'd get the same results, right? The isolation
> > code will deal with it. But sure, it does potentially avoid doing some
> > unnecessary work.
In separate discussion with Johannes, he also noted that this allocation
code is the right place to do this check - as you might want to move a
1GB page if you're trying to reserve a specific region of memory.
So this much I'm confident in now. But going back to Mel's comment:
>
> commit 4d73ba5fa710fe7d432e0b271e6fecd252aef66e
> Author: Mel Gorman <mgorman@techsingularity.net>
> Date: Fri Apr 14 15:14:29 2023 +0100
>
> mm: page_alloc: skip regions with hugetlbfs pages when allocating 1G pages
> A bug was reported by Yuanxi Liu where allocating 1G pages at runtime is
> taking an excessive amount of time for large amounts of memory. Further
> testing allocating huge pages that the cost is linear i.e. if allocating
> 1G pages in batches of 10 then the time to allocate nr_hugepages from
> 10->20->30->etc increases linearly even though 10 pages are allocated at
> each step. Profiles indicated that much of the time is spent checking the
> validity within already existing huge pages and then attempting a
> migration that fails after isolating the range, draining pages and a whole
> lot of other useless work.
> Commit eb14d4eefdc4 ("mm,page_alloc: drop unnecessary checks from
> pfn_range_valid_contig") removed two checks, one which ignored huge pages
> for contiguous allocations as huge pages can sometimes migrate. While
> there may be value on migrating a 2M page to satisfy a 1G allocation, it's
> potentially expensive if the 1G allocation fails and it's pointless to try
> moving a 1G page for a new 1G allocation or scan the tail pages for valid
> PFNs.
> Reintroduce the PageHuge check and assume any contiguous region with
> hugetlbfs pages is unsuitable for a new 1G allocation.
>
Mel is pointing out that allowing 2MB region scans can cause 1GB page
allocation to take a very long time - specifically if no 2MB pages are
available as migration targets.
Joshua's test demonstrates at least that if the pages are reserved, the
migration code will move those reservations around accordingly. Now that
I look at it, it's unclear whether he tested if this still works when
those pages are actually reserved AND allocated.
I would presume we would end up in the position Mel describes (where
migrations fail and allocation takes a long time). That does seem
problematic unless we can reserve a new 2MB page outside the current
region and destroy the old one.
This at least would not cause a recursive call into this code as only
the gigantic page reservation interface hits this code.
So I'm at a bit of an impasse. I understand the performance issue here,
but being able to reliably allocate gigantic pages when a ton of 2MB
pages are already being used is also really nice.
Maybe we could do a first-pass / second-pass attempt where we filter on
PageHuge() on the first go, and then filter on (PageHuge() < alloc_size)
on the second go?
~Gregory
^ permalink raw reply
* COCONUT-SVSM Development Release v2025.12-devel
From: Jörg Rödel @ 2025-12-18 11:38 UTC (permalink / raw)
To: coconut-svsm, linux-coco
Hi,
The last development release of COCONUT-SVSM for this year has been tagged. Due
to the upcoming holidays in the western parts of the world this release
happened a few weeks earlier than ususal and turned out to be smaller as well.
This time it features 47 non-merge commits since the November release, the
changes include (but are not limited to):
* Fixed formal verification. This has been broken for the last two
releases, so I am excited to report that it works again.
* Rust safety improvements
* Initial steps towards a UEFI variable store service with merging the
SVSM protocol number definition.
* Fixed the idle-halt loop. It had a bug that could have caused COCONUT
to go into halt while another task is runnable.
* Improvements in x86 platform support.
With verification working again this is a pretty solid release which received a
good amount of testing as well.
A big "Thank You!" goes to the COCONUT-SVSM community for another year of solid
progress on the project due to all the hard work being done. I'd also like to
thank the Technical Steering Committee for all their help and dedication in
managing the project with PR reviews and setting the technical direction.
I wish everyone a restful time with their loved ones, see you all again next
year!
Regards,
Joerg
^ permalink raw reply
* Re: SVSM Development Call December 17th, 2025
From: Jörg Rödel @ 2025-12-18 9:08 UTC (permalink / raw)
To: coconut-svsm, linux-coco
In-Reply-To: <wr5g22qmztj3mqiiwzxvqw22tdypqtu4rd7biwcbrbvv2m52o5@ok3fldp5auo5>
Meeting Minutes are now posted:
https://github.com/coconut-svsm/governance/pull/90
Have fun and enjoy the holidays!
-Joerg
^ permalink raw reply
* Re: [PATCH v2 2/7] KVM: x86: Extract VMXON and EFER.SVME enablement to kernel
From: Sean Christopherson @ 2025-12-17 19:01 UTC (permalink / raw)
To: Xu Yilun
Cc: Chao Gao, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, Kiryl Shutsemau, Paolo Bonzini, linux-kernel,
linux-coco, kvm, Dan Williams
In-Reply-To: <aUJUbcyz2DXmphtU@yilunxu-OptiPlex-7050>
On Wed, Dec 17, 2025, Xu Yilun wrote:
> > >+#define x86_virt_call(fn) \
> > >+({ \
> > >+ int __r; \
> > >+ \
> > >+ if (IS_ENABLED(CONFIG_KVM_INTEL) && \
> > >+ cpu_feature_enabled(X86_FEATURE_VMX)) \
> > >+ __r = x86_vmx_##fn(); \
> > >+ else if (IS_ENABLED(CONFIG_KVM_AMD) && \
> > >+ cpu_feature_enabled(X86_FEATURE_SVM)) \
> > >+ __r = x86_svm_##fn(); \
> > >+ else \
> > >+ __r = -EOPNOTSUPP; \
> > >+ \
> > >+ __r; \
> > >+})
> > >+
> > >+int x86_virt_get_cpu(int feat)
> > >+{
> > >+ int r;
> > >+
> > >+ if (!x86_virt_feature || x86_virt_feature != feat)
> > >+ return -EOPNOTSUPP;
> > >+
> > >+ if (this_cpu_inc_return(virtualization_nr_users) > 1)
> > >+ return 0;
> >
> > Should we assert that preemption is disabled? Calling this API when preemption
> > is enabled is wrong.
> >
> > Maybe use __this_cpu_inc_return(), which already verifies preemption status.
I always forget that the double-underscores have the checks.
> Is it better we explicitly assert the preemption for x86_virt_get_cpu()
> rather than embed the check in __this_cpu_inc_return()? We are not just
> protecting the racing for the reference counter. We should ensure the
> "counter increase + x86_virt_call(get_cpu)" can't be preempted.
I don't have a strong preference. Using __this_cpu_inc_return() without any
nearby preemption_{enable,disable}() calls makes it quite clears that preemption
is expected to be disabled by the caller. But I'm also ok being explicit.
^ permalink raw reply
* Re: [PATCH v12 00/46] arm64: Support for Arm CCA in KVM
From: Steven Price @ 2025-12-17 15:28 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvm, kvmarm, Catalin Marinas, Will Deacon, James Morse,
Oliver Upton, Suzuki K Poulose, Zenghui Yu, linux-arm-kernel,
linux-kernel, Joey Gouly, Alexandru Elisei, Christoffer Dall,
Fuad Tabba, linux-coco, Ganapatrao Kulkarni, Gavin Shan,
Shanker Donthineni, Alper Gun, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve
In-Reply-To: <86y0n1ma2q.wl-maz@kernel.org>
On 17/12/2025 14:55, Marc Zyngier wrote:
> On Wed, 17 Dec 2025 10:10:37 +0000,
> Steven Price <steven.price@arm.com> wrote:
>>
>> This series adds support for running protected VMs using KVM under the
>> Arm Confidential Compute Architecture (CCA). I've changed the uAPI
>> following feedback from Marc.
>>
>> The main change is that rather than providing a multiplex CAP and
>> expecting the VMM to drive the different stages of realm construction,
>> there's now just a minimal interface and KVM performs the necessary
>> operations when needed.
>
> What are the relevant patches? I'd rather not look at the non-2.0
> patches at all, given that they are pretty meaningless for KVM.
Sorry, I really should have included that in the cover letter.
Patch 6 defines the uAPI - so I'd welcome feedback on whether that is
now the right shape.
Patch 11 shows how the "first VCPU run" is handled with a hook in
kvm_arch_vcpu_run_pid_change() (similar to pKVM).
Patch 20 is implementation of the new populate ioctl.
Patch 21 handles the INIT_RIPAS by assuming that any memslot with gmem
is private and should be RIPAS_RAM.
Patch 27 handles the PSCI requests which is the other ioctl. No real
change from the previous posting, but it would be good to know if there
are any issues with the uAPI here.
I think other than those there's either very little change from the
previous series, or it's likely to change with RMM v2.0.
Thanks,
Steve
^ permalink raw reply
* Re: [PATCH v12 00/46] arm64: Support for Arm CCA in KVM
From: Marc Zyngier @ 2025-12-17 14:55 UTC (permalink / raw)
To: Steven Price
Cc: kvm, kvmarm, Catalin Marinas, Will Deacon, James Morse,
Oliver Upton, Suzuki K Poulose, Zenghui Yu, linux-arm-kernel,
linux-kernel, Joey Gouly, Alexandru Elisei, Christoffer Dall,
Fuad Tabba, linux-coco, Ganapatrao Kulkarni, Gavin Shan,
Shanker Donthineni, Alper Gun, Aneesh Kumar K . V, Emi Kisanuki,
Vishal Annapurve
In-Reply-To: <20251217101125.91098-1-steven.price@arm.com>
On Wed, 17 Dec 2025 10:10:37 +0000,
Steven Price <steven.price@arm.com> wrote:
>
> This series adds support for running protected VMs using KVM under the
> Arm Confidential Compute Architecture (CCA). I've changed the uAPI
> following feedback from Marc.
>
> The main change is that rather than providing a multiplex CAP and
> expecting the VMM to drive the different stages of realm construction,
> there's now just a minimal interface and KVM performs the necessary
> operations when needed.
What are the relevant patches? I'd rather not look at the non-2.0
patches at all, given that they are pretty meaningless for KVM.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v12 11/46] arm64: RMI: Activate realm on first VCPU run
From: Suzuki K Poulose @ 2025-12-17 14:29 UTC (permalink / raw)
To: Steven Price, kvm, kvmarm
Cc: Catalin Marinas, Marc Zyngier, Will Deacon, James Morse,
Oliver Upton, Zenghui Yu, linux-arm-kernel, linux-kernel,
Joey Gouly, Alexandru Elisei, Christoffer Dall, Fuad Tabba,
linux-coco, Ganapatrao Kulkarni, Gavin Shan, Shanker Donthineni,
Alper Gun, Aneesh Kumar K . V, Emi Kisanuki, Vishal Annapurve
In-Reply-To: <20251217101125.91098-12-steven.price@arm.com>
On 17/12/2025 10:10, Steven Price wrote:
> When a VCPU migrates to another physical CPU check if this is the first
> time the guest has run, and if so activate the realm.
>
> Before the realm can be activated it must first be created, this is a
> stub in this patch and will be filled in by a later patch.
>
> Signed-off-by: Steven Price <steven.price@arm.com>
> ---
> New patch for v12
> ---
> arch/arm64/include/asm/kvm_rmi.h | 1 +
> arch/arm64/kvm/arm.c | 6 +++++
> arch/arm64/kvm/rmi.c | 42 ++++++++++++++++++++++++++++++++
> 3 files changed, 49 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_rmi.h
> index cb7350f8a01a..e4534af06d96 100644
> --- a/arch/arm64/include/asm/kvm_rmi.h
> +++ b/arch/arm64/include/asm/kvm_rmi.h
> @@ -69,6 +69,7 @@ void kvm_init_rmi(void);
> u32 kvm_realm_ipa_limit(void);
>
> int kvm_init_realm_vm(struct kvm *kvm);
> +int kvm_activate_realm(struct kvm *kvm);
> void kvm_destroy_realm(struct kvm *kvm);
> void kvm_realm_destroy_rtts(struct kvm *kvm);
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 941d1bec8e77..542df37b9e82 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -951,6 +951,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> return ret;
> }
>
> + if (kvm_is_realm(vcpu->kvm)) {
> + ret = kvm_activate_realm(kvm);
> + if (ret)
> + return ret;
> + }
> +
> mutex_lock(&kvm->arch.config_lock);
> set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags);
> mutex_unlock(&kvm->arch.config_lock);
> diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
> index e57e8b7eafa9..98929382c365 100644
> --- a/arch/arm64/kvm/rmi.c
> +++ b/arch/arm64/kvm/rmi.c
> @@ -223,6 +223,48 @@ void kvm_realm_destroy_rtts(struct kvm *kvm)
> WARN_ON(realm_tear_down_rtt_range(realm, 0, (1UL << ia_bits)));
> }
>
> +static int realm_ensure_created(struct kvm *kvm)
> +{
> + /* Provided in later patch */
> + return -ENXIO;
> +}
> +
> +int kvm_activate_realm(struct kvm *kvm)
> +{
> + struct realm *realm = &kvm->arch.realm;
> + int ret;
> +
> + if (!kvm_is_realm(kvm))
> + return -ENXIO;
> +
> + if (kvm_realm_state(kvm) == REALM_STATE_ACTIVE)
> + return 0;
> +
> + guard(mutex)(&kvm->arch.config_lock);
> + /* Check again with the lock held */
> + if (kvm_realm_state(kvm) == REALM_STATE_ACTIVE)
> + return 0;
> +
> + ret = realm_ensure_created(kvm);
> + if (ret)
> + return ret;
> +
> + /* Mark state as dead in case we fail */
> + WRITE_ONCE(realm->state, REALM_STATE_DEAD);
> +
> + if (!irqchip_in_kernel(kvm)) {
> + /* Userspace irqchip not yet supported with realms */
> + return -EOPNOTSUPP;
> + }
super minor nit: We could do this check before create the realm, within
the config_lock'ed region.
Suzuki
^ permalink raw reply
* Re: [PATCH 1/2] x86/split_lock: Don't try to handle user split lock in TDX guest
From: Xiaoyao Li @ 2025-12-17 10:56 UTC (permalink / raw)
To: Dave Hansen
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, Rick Edgecombe, linux-kernel, linux-coco, kvm,
Reinette Chatre, Chenyi Qiang, chao.p.peng, Kiryl Shutsemau
In-Reply-To: <lvobu4gpfsjg63syubgy2jwcja72folflrst7bu2eqv6rhaqre@ttbkykphu32f>
On 11/26/2025 7:25 PM, Kiryl Shutsemau wrote:
> On Wed, Nov 26, 2025 at 06:02:03PM +0800, Xiaoyao Li wrote:
>> When the host enables split lock detection feature, the split lock from
>> guests (normal or TDX) triggers #AC. The #AC caused by split lock access
>> within a normal guest triggers a VM Exit and is handled in the host.
>> The #AC caused by split lock access within a TDX guest does not trigger
>> a VM Exit and instead it's delivered to the guest self.
>>
>> The default "warning" mode of handling split lock depends on being able
>> to temporarily disable detection to recover from the split lock event.
>> But the MSR that disables detection is not accessible to a guest.
>>
>> This means that TDX guests today can not disable the feature or use
>> the "warning" mode (which is the default). But, they can use the "fatal"
>> mode.
>>
>> Force TDX guests to use the "fatal" mode.
>>
>> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
>> ---
>> arch/x86/kernel/cpu/bus_lock.c | 17 ++++++++++++++++-
>> 1 file changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/kernel/cpu/bus_lock.c
>> index 981f8b1f0792..f278e4ea3dd4 100644
>> --- a/arch/x86/kernel/cpu/bus_lock.c
>> +++ b/arch/x86/kernel/cpu/bus_lock.c
>> @@ -315,9 +315,24 @@ void bus_lock_init(void)
>> wrmsrq(MSR_IA32_DEBUGCTLMSR, val);
>> }
>>
>> +static bool split_lock_fatal(void)
>> +{
>> + if (sld_state == sld_fatal)
>> + return true;
>> +
>> + /*
>> + * TDX guests can not disable split lock detection.
>> + * Force them into the fatal behavior.
>> + */
>> + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
>> + return true;
>> +
>> + return false;
>> +}
>> +
>> bool handle_user_split_lock(struct pt_regs *regs, long error_code)
>> {
>> - if ((regs->flags & X86_EFLAGS_AC) || sld_state == sld_fatal)
>> + if ((regs->flags & X86_EFLAGS_AC) || split_lock_fatal())
>> return false;
>
> Maybe it would be cleaner to make it conditional on
> cpu_model_supports_sld instead of special-casing TDX guest?
>
> #AC on any platfrom when we didn't asked for it suppose to be fatal, no?
Hi Dave,
Do you like this suggestion from Kiryl? If you don't object it, I will
do it in v2.
^ permalink raw reply
* [PATCH v12 46/46] arm64: RMI: Enable realms to be created
From: Steven Price @ 2025-12-17 10:11 UTC (permalink / raw)
To: kvm, kvmarm
Cc: Steven Price, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Joey Gouly, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Alper Gun, Aneesh Kumar K . V,
Emi Kisanuki, Vishal Annapurve
In-Reply-To: <20251217101125.91098-1-steven.price@arm.com>
All the pieces are now in place, so enable kvm_rmi_is_available when the
RMM is detected.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm64/kvm/rmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
index 657d70eab0ab..0e470f31d46a 100644
--- a/arch/arm64/kvm/rmi.c
+++ b/arch/arm64/kvm/rmi.c
@@ -1659,5 +1659,5 @@ void kvm_init_rmi(void)
if (rmi_vmid_init())
return;
- /* Future patch will enable static branch kvm_rmi_is_available */
+ static_branch_enable(&kvm_rmi_is_available);
}
--
2.43.0
^ permalink raw reply related
* [PATCH v12 45/46] KVM: arm64: Expose KVM_ARM_VCPU_REC to user space
From: Steven Price @ 2025-12-17 10:11 UTC (permalink / raw)
To: kvm, kvmarm
Cc: Steven Price, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Joey Gouly, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Alper Gun, Aneesh Kumar K . V,
Emi Kisanuki, Vishal Annapurve
In-Reply-To: <20251217101125.91098-1-steven.price@arm.com>
Increment KVM_VCPU_MAX_FEATURES to expose the new capability to user
space.
Signed-off-by: Steven Price <steven.price@arm.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
---
Changes since v8:
* Since NV is now merged and enabled, this no longer conflicts with it.
---
arch/arm64/include/asm/kvm_host.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 97c747cfb5be..7e3221d102a9 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -40,7 +40,7 @@
#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
-#define KVM_VCPU_MAX_FEATURES 9
+#define KVM_VCPU_MAX_FEATURES 10
#define KVM_VCPU_VALID_FEATURES (BIT(KVM_VCPU_MAX_FEATURES) - 1)
#define KVM_REQ_SLEEP \
--
2.43.0
^ permalink raw reply related
* [PATCH v12 44/46] arm64: RMI: Provide accurate register list
From: Steven Price @ 2025-12-17 10:11 UTC (permalink / raw)
To: kvm, kvmarm
Cc: Jean-Philippe Brucker, Catalin Marinas, Marc Zyngier, Will Deacon,
James Morse, Oliver Upton, Suzuki K Poulose, Zenghui Yu,
linux-arm-kernel, linux-kernel, Joey Gouly, Alexandru Elisei,
Christoffer Dall, Fuad Tabba, linux-coco, Ganapatrao Kulkarni,
Gavin Shan, Shanker Donthineni, Alper Gun, Aneesh Kumar K . V,
Emi Kisanuki, Vishal Annapurve, Steven Price
In-Reply-To: <20251217101125.91098-1-steven.price@arm.com>
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
Userspace can set a few registers with KVM_SET_ONE_REG (9 GP registers
at runtime, and 3 system registers during initialization). Update the
register list returned by KVM_GET_REG_LIST.
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Steven Price <steven.price@arm.com>
---
Changes since v11:
* Reworked due to upstream changes.
Changes since v8:
* Minor type changes following review.
Changes since v7:
* Reworked on upstream changes.
---
arch/arm64/kvm/guest.c | 6 ++++++
arch/arm64/kvm/hypercalls.c | 4 ++--
arch/arm64/kvm/sys_regs.c | 29 +++++++++++++++++++++++------
3 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 2c4db2d1a6ca..23fdb2ee8a61 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -620,6 +620,9 @@ static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
if (!kvm_arm_vcpu_sve_finalized(vcpu))
return 1; /* KVM_REG_ARM64_SVE_VLS */
+ if (kvm_is_realm(vcpu->kvm))
+ return 1; /* KVM_REG_ARM64_SVE_VLS */
+
return slices * (SVE_NUM_PREGS + SVE_NUM_ZREGS + 1 /* FFR */)
+ 1; /* KVM_REG_ARM64_SVE_VLS */
}
@@ -647,6 +650,9 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *vcpu,
if (!kvm_arm_vcpu_sve_finalized(vcpu))
return num_regs;
+ if (kvm_is_realm(vcpu->kvm))
+ return num_regs;
+
for (i = 0; i < slices; i++) {
for (n = 0; n < SVE_NUM_ZREGS; n++) {
reg = KVM_REG_ARM64_SVE_ZREG(n, i);
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 58c5fe7d7572..70ac7971416c 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -414,14 +414,14 @@ void kvm_arm_teardown_hypercalls(struct kvm *kvm)
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
{
- return ARRAY_SIZE(kvm_arm_fw_reg_ids);
+ return kvm_is_realm(vcpu->kvm) ? 0 : ARRAY_SIZE(kvm_arm_fw_reg_ids);
}
int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
{
int i;
- for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) {
+ for (i = 0; i < kvm_arm_get_fw_num_regs(vcpu); i++) {
if (put_user(kvm_arm_fw_reg_ids[i], uindices++))
return -EFAULT;
}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f93e37bc77aa..32b7be718e54 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -5401,18 +5401,18 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
}
-static unsigned int num_demux_regs(void)
+static inline unsigned int num_demux_regs(struct kvm_vcpu *vcpu)
{
- return CSSELR_MAX;
+ return kvm_is_realm(vcpu->kvm) ? 0 : CSSELR_MAX;
}
-static int write_demux_regids(u64 __user *uindices)
+static int write_demux_regids(struct kvm_vcpu *vcpu, u64 __user *uindices)
{
u64 val = KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX;
unsigned int i;
val |= KVM_REG_ARM_DEMUX_ID_CCSIDR;
- for (i = 0; i < CSSELR_MAX; i++) {
+ for (i = 0; i < num_demux_regs(vcpu); i++) {
if (put_user(val | i, uindices))
return -EFAULT;
uindices++;
@@ -5456,11 +5456,28 @@ static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **uind)
return true;
}
+static inline bool kvm_realm_sys_reg_hidden_user(const struct kvm_vcpu *vcpu,
+ u64 reg)
+{
+ if (!kvm_is_realm(vcpu->kvm))
+ return false;
+
+ switch (reg) {
+ case SYS_ID_AA64DFR0_EL1:
+ case SYS_PMCR_EL0:
+ return false;
+ }
+ return true;
+}
+
static int walk_one_sys_reg(const struct kvm_vcpu *vcpu,
const struct sys_reg_desc *rd,
u64 __user **uind,
unsigned int *total)
{
+ if (kvm_realm_sys_reg_hidden_user(vcpu, reg_to_encoding(rd)))
+ return 0;
+
/*
* Ignore registers we trap but don't save,
* and for which no custom user accessor is provided.
@@ -5498,7 +5515,7 @@ static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind)
unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu)
{
- return num_demux_regs()
+ return num_demux_regs(vcpu)
+ walk_sys_regs(vcpu, (u64 __user *)NULL);
}
@@ -5511,7 +5528,7 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
return err;
uindices += err;
- return write_demux_regids(uindices);
+ return write_demux_regids(vcpu, uindices);
}
#define KVM_ARM_FEATURE_ID_RANGE_INDEX(r) \
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox