* Re: "Paravisor" Feature Enumeration
From: Dave Hansen @ 2026-01-06 0:36 UTC (permalink / raw)
To: dan.j.williams, Lange, Jon
Cc: Sean Christopherson, Paolo Bonzini, john.starks, Will Deacon,
Mark Rutland, linux-coco@lists.linux.dev, LKML,
Kirill A. Shutemov, Edgecombe, Rick P, Andrew Cooper
In-Reply-To: <695c50eee68e3_4b7a100e8@dwillia2-mobl4.notmuch>
On 1/5/26 16:01, dan.j.williams@intel.com wrote:
> Dave Hansen wrote:
...
>> X86_FEATURE_KVM_CLOCKSOURCE in arm,pvclock
>> or
>> X86_FEATURE_KVM_STEAL_TIME in arm,kvm-steal-time
>>
>> As far as I can tell, these aliases are all done ad-hoc. This approach
>> could obviously be extended to paravisor features, but it would probably
>> be on the slow side to do it for each new feature.
>
> "Slow" as in standardization time?
Yes.
...
>> Is there anything stopping us from carving out a chunk of CPUID for
>> this purpose?
>
> At what point does an ACPI property become a CPUID? In other words if
> there is an ACPI / DeviceTree enumeration of CPU/platform capabilities
> in firmware that can supsersede / extend native enumeration, does it
> matter if x86 maps that to extended CPUID space and ARM maps it however
> is convenient?
>
> I have no problem with an extended CPUID concept, just trying to
> understand more about the assumptions.
The way it _seems_ to have worked until now is that KVM/x86 has led the
way by defining a CPUID bit for things like KVM_CLOCK of KVM_STEAL_TIME.
Then, the ARM folks came along and DeviceTree enumerations. Last, ACPI
came along with a way to package up all the DeviceTree enumerations into
a single table.
So, maybe that's a hack on a hack on a hack and we should just start
with ACPI this time. That would certainly make this pretty straightforward.
I'd love to hear a take from the x86/KVM folks, though.
^ permalink raw reply
* RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration
From: Jon Lange @ 2026-01-06 0:10 UTC (permalink / raw)
To: dan.j.williams@intel.com, Dave Hansen
Cc: Sean Christopherson, Paolo Bonzini, John Starks, Will Deacon,
Mark Rutland, linux-coco@lists.linux.dev, LKML,
Kirill A. Shutemov, Edgecombe, Rick P, Andrew Cooper
In-Reply-To: <695c50eee68e3_4b7a100e8@dwillia2-mobl4.notmuch>
It's not clear to me what advantages are gained by reflecting ACPI information into CPUID. ACPI is already available and is usable across architectures, unlike CPUID. What advantage is gained by replicating the information into CPUID? Any advantage that doesn't have an equivalent on Arm just seems like it would perpetuate the cross-architecture problem and would lead right back to some other proposal that works on multiple architectures, so I'm very curious to understand how CPUID provides a meaningful advantage that doesn't invite new problems.
In the LPC session that Dave cites, Dan (I think it was Dan) threw out another suggestion: have the hypervisor driver detect the paravisor configuration using whatever is appropriate for that hypervisor architecture. I find this to be a very attractive direction because it eliminates the need to define standards that can be supported across hypervisors (and across virtual firmware implementations), and reduces it just to a small set of concepts that can be fed into the kernel. This could keep the enumeration out of the hands of ACPI altogether - thus no slow standards development. Are there downsides to this approach that make it unattractive?
-Jon
-----Original Message-----
From: dan.j.williams@intel.com <dan.j.williams@intel.com>
Sent: Monday, January 5, 2026 4:02 PM
To: Dave Hansen <dave.hansen@intel.com>; Jon Lange <jlange@microsoft.com>
Cc: Williams, Dan J <dan.j.williams@intel.com>; Sean Christopherson <seanjc@google.com>; Paolo Bonzini <pbonzini@redhat.com>; John Starks <John.Starks@microsoft.com>; Will Deacon <will@kernel.org>; Mark Rutland <mark.rutland@arm.com>; linux-coco@lists.linux.dev; LKML <linux-kernel@vger.kernel.org>; Kirill A. Shutemov <kirill.shutemov@linux.intel.com>; Edgecombe, Rick P <rick.p.edgecombe@intel.com>; Andrew Cooper <andrew.cooper3@citrix.com>
Subject: [EXTERNAL] Re: "Paravisor" Feature Enumeration
[You don't often get email from dan.j.williams@intel.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
Dave Hansen wrote:
> First,
>
> Jon and John gave a talk in Tokyo about feature enumeration under
> paravisors:
>
> > https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Flp
> > c.events%2Fevent%2F19%2Fcontributions%2F2188%2Fattachments%2F1896%2F
> > 4057%2F05-Paravisor-Integration-with-Confidential-Services.pdf&data=
> > 05%7C02%7Cjlange%40microsoft.com%7C2dfafa359d6b4bc7488308de4cb6e7ed%
> > 7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639032545637571280%7CUn
> > known%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAi
> > OiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=JKT2
> > 2S031BpC1gwBHMFOOHfA%2Fx91vXaysS6Gg2kMVeE%3D&reserved=0
>
> The tl;dr for me at least was that they'd like a common and consistent
> means of enumerating these features in OSes, regardless of the
> environment: TDX, SEV-SNP or even ARM CCA.
>
> I wanted to explore one corner of the solution space a bit. There was
> a pretty limited audience of folks in the room. Please feel free to
> flesh out the cc list with anyone I missed.
>
> Dan Williams' first thought seemed to revolve around having some kind
> of platform-independent device that could do the enumeration. Maybe a
> synthetic PCI device. I'm sure Dan can chime in to fill in the details
> that I missed.
More that it sounded like "just another firmware enumeration" problem, where a platform device is one of the results along with related firmware tables and objects.
> I immediately just thought of CPUID. We already have a whole region of
> CPUID (0x40000000) that hypervisors use to enumerate stuff to guests
> by convention. It wouldn't be a large leap at all to carve out a chunk
> of that so that paravisors can use it.
>
> But the biggest barrier I see there is that our ARM friends don't have
> CPUID. It seems like they _mostly_ have bit-by-bit aliases in ACPI or
> DeviceTree for the x86 CPUID bits, like:
>
> X86_FEATURE_KVM_CLOCKSOURCE in arm,pvclock or
> X86_FEATURE_KVM_STEAL_TIME in arm,kvm-steal-time
>
> As far as I can tell, these aliases are all done ad-hoc. This approach
> could obviously be extended to paravisor features, but it would
> probably be on the slow side to do it for each new feature.
"Slow" as in standardization time?
> It _seems_ like we could pick a chunk of CPUID space (say 32-bits of
> it) and alias it 1:1 with some DeviceTree/ACPI property, say
> "arm,paravisor-features". Kernel code would just be written to say
> "check feature 13" and the arch-specific helpers would either steer
> that to CPUID or DeviceTree.
>
> Is there anything like that today that's cross-architecture and
> cross-hypervisor?
That seems the definition of an ACPI description.
> Is there anything stopping us from carving out a chunk of CPUID for
> this purpose?
At what point does an ACPI property become a CPUID? In other words if there is an ACPI / DeviceTree enumeration of CPU/platform capabilities in firmware that can supsersede / extend native enumeration, does it matter if x86 maps that to extended CPUID space and ARM maps it however is convenient?
I have no problem with an extended CPUID concept, just trying to understand more about the assumptions.
^ permalink raw reply
* Re: "Paravisor" Feature Enumeration
From: dan.j.williams @ 2026-01-06 0:01 UTC (permalink / raw)
To: Dave Hansen, Lange, Jon
Cc: Williams, Dan J, Sean Christopherson, Paolo Bonzini, john.starks,
Will Deacon, Mark Rutland, linux-coco@lists.linux.dev, LKML,
Kirill A. Shutemov, Edgecombe, Rick P, Andrew Cooper
In-Reply-To: <c4ef08a6-5600-4604-9e40-bd3263a0dcd3@intel.com>
Dave Hansen wrote:
> First,
>
> Jon and John gave a talk in Tokyo about feature enumeration under
> paravisors:
>
> > https://lpc.events/event/19/contributions/2188/attachments/1896/4057/05-Paravisor-Integration-with-Confidential-Services.pdf
>
> The tl;dr for me at least was that they'd like a common and consistent
> means of enumerating these features in OSes, regardless of the
> environment: TDX, SEV-SNP or even ARM CCA.
>
> I wanted to explore one corner of the solution space a bit. There was a
> pretty limited audience of folks in the room. Please feel free to flesh
> out the cc list with anyone I missed.
>
> Dan Williams' first thought seemed to revolve around having some kind of
> platform-independent device that could do the enumeration. Maybe a
> synthetic PCI device. I'm sure Dan can chime in to fill in the details
> that I missed.
More that it sounded like "just another firmware enumeration" problem,
where a platform device is one of the results along with related
firmware tables and objects.
> I immediately just thought of CPUID. We already have a whole region of
> CPUID (0x40000000) that hypervisors use to enumerate stuff to guests by
> convention. It wouldn't be a large leap at all to carve out a chunk of
> that so that paravisors can use it.
>
> But the biggest barrier I see there is that our ARM friends don't have
> CPUID. It seems like they _mostly_ have bit-by-bit aliases in ACPI or
> DeviceTree for the x86 CPUID bits, like:
>
> X86_FEATURE_KVM_CLOCKSOURCE in arm,pvclock
> or
> X86_FEATURE_KVM_STEAL_TIME in arm,kvm-steal-time
>
> As far as I can tell, these aliases are all done ad-hoc. This approach
> could obviously be extended to paravisor features, but it would probably
> be on the slow side to do it for each new feature.
"Slow" as in standardization time?
> It _seems_ like we could pick a chunk of CPUID space (say 32-bits of it)
> and alias it 1:1 with some DeviceTree/ACPI property, say
> "arm,paravisor-features". Kernel code would just be written to say
> "check feature 13" and the arch-specific helpers would either steer that
> to CPUID or DeviceTree.
>
> Is there anything like that today that's cross-architecture and
> cross-hypervisor?
That seems the definition of an ACPI description.
> Is there anything stopping us from carving out a chunk of CPUID for
> this purpose?
At what point does an ACPI property become a CPUID? In other words if
there is an ACPI / DeviceTree enumeration of CPU/platform capabilities
in firmware that can supsersede / extend native enumeration, does it
matter if x86 maps that to extended CPUID space and ARM maps it however
is convenient?
I have no problem with an extended CPUID concept, just trying to
understand more about the assumptions.
^ permalink raw reply
* Re: [PATCH v4 04/16] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT
From: Edgecombe, Rick P @ 2026-01-05 22:06 UTC (permalink / raw)
To: yilun.xu@linux.intel.com
Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Huang, Kai,
Li, Xiaoyao, Hansen, Dave, Zhao, Yan Y, Wu, Binbin,
kas@kernel.org, seanjc@google.com, mingo@redhat.com,
linux-kernel@vger.kernel.org, pbonzini@redhat.com,
Yamahata, Isaku, kirill.shutemov@linux.intel.com,
tglx@linutronix.de, Annapurve, Vishal, Gao, Chao, bp@alien8.de,
x86@kernel.org
In-Reply-To: <aUut+PYnX3jrSO0i@yilunxu-OptiPlex-7050>
On Wed, 2025-12-24 at 17:10 +0800, Xu Yilun wrote:
> Is it better we seal the awkward pattern inside the if (dpamt supported) block:
>
> if (tdx_support_dynamic_pamt(&tdx_sysinfo))
> if (!ret && !(ret = read_sys_metadata_field(0x9100000100000013, &val)))
> sysinfo_tdmr->pamt_page_bitmap_entry_bits = val;
The extra indentation might be objectionable.
But I agree that line is too hard to read. It actually already caused some
confusion, which precipitated the comment. I played around with it and was
thinking to go with this instead to make it fit the pattern better. What do you
think?
static int get_tdx_sys_info_dpamt_bits(struct tdx_sys_info_tdmr *sysinfo_tdmr,
u64 *val)
{
/*
* Don't let the metadata reading fail if dynamic PAMT isn't
* supported. The TDX code can fallback to normal PAMT in
* this case.
*/
if (!tdx_supports_dynamic_pamt(&tdx_sysinfo)) {
*val = 0;
return 0;
}
return read_sys_metadata_field(0x9100000100000013, val);
}
static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000008, &val)))
sysinfo_tdmr->max_tdmrs = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000009, &val)))
sysinfo_tdmr->max_reserved_per_tdmr = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000010, &val)))
sysinfo_tdmr->pamt_4k_entry_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000011, &val)))
sysinfo_tdmr->pamt_2m_entry_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000012, &val)))
sysinfo_tdmr->pamt_1g_entry_size = val;
if (!ret && !(ret = get_tdx_sys_info_dpamt_bits(sysinfo_tdmr, &val)))
sysinfo_tdmr->pamt_page_bitmap_entry_bits = val;
return ret;
}
^ permalink raw reply
* "Paravisor" Feature Enumeration
From: Dave Hansen @ 2026-01-05 21:42 UTC (permalink / raw)
To: Lange, Jon
Cc: Williams, Dan J, Sean Christopherson, Paolo Bonzini, john.starks,
Will Deacon, Mark Rutland, linux-coco@lists.linux.dev, LKML,
Kirill A. Shutemov, Edgecombe, Rick P, Andrew Cooper
First,
Jon and John gave a talk in Tokyo about feature enumeration under
paravisors:
> https://lpc.events/event/19/contributions/2188/attachments/1896/4057/05-Paravisor-Integration-with-Confidential-Services.pdf
The tl;dr for me at least was that they'd like a common and consistent
means of enumerating these features in OSes, regardless of the
environment: TDX, SEV-SNP or even ARM CCA.
I wanted to explore one corner of the solution space a bit. There was a
pretty limited audience of folks in the room. Please feel free to flesh
out the cc list with anyone I missed.
Dan Williams' first thought seemed to revolve around having some kind of
platform-independent device that could do the enumeration. Maybe a
synthetic PCI device. I'm sure Dan can chime in to fill in the details
that I missed.
I immediately just thought of CPUID. We already have a whole region of
CPUID (0x40000000) that hypervisors use to enumerate stuff to guests by
convention. It wouldn't be a large leap at all to carve out a chunk of
that so that paravisors can use it.
But the biggest barrier I see there is that our ARM friends don't have
CPUID. It seems like they _mostly_ have bit-by-bit aliases in ACPI or
DeviceTree for the x86 CPUID bits, like:
X86_FEATURE_KVM_CLOCKSOURCE in arm,pvclock
or
X86_FEATURE_KVM_STEAL_TIME in arm,kvm-steal-time
As far as I can tell, these aliases are all done ad-hoc. This approach
could obviously be extended to paravisor features, but it would probably
be on the slow side to do it for each new feature.
It _seems_ like we could pick a chunk of CPUID space (say 32-bits of it)
and alias it 1:1 with some DeviceTree/ACPI property, say
"arm,paravisor-features". Kernel code would just be written to say
"check feature 13" and the arch-specific helpers would either steer that
to CPUID or DeviceTree.
Is there anything like that today that's cross-architecture and
cross-hypervisor? Is there anything stopping us from carving out a chunk
of CPUID for this purpose?
^ permalink raw reply
* Re: [PATCH v2 0/3] Expose TDX Module version
From: Kiryl Shutsemau @ 2026-01-05 18:03 UTC (permalink / raw)
To: Dave Hansen
Cc: Chao Gao, kvm, linux-coco, linux-kernel, x86, vishal.l.verma,
kai.huang, dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
Thomas Gleixner
In-Reply-To: <7cbac499-6145-4b83-873c-c2d283f9cb79@intel.com>
On Mon, Jan 05, 2026 at 09:19:07AM -0800, Dave Hansen wrote:
> On 1/5/26 09:04, Kiryl Shutsemau wrote:
> >> What are other CPU vendors doing for this? SEV? CCA? S390? How are their
> >> firmware versions exposed? What about other things in the Intel world
> >> like CPU microcode or the billion other chunks of firmware? How about
> >> hypervisors? Do they expose their versions to guests with an explicit
> >> ABI? Are those exposed to userspace?
> > My first thought was that it should be under /sys/hypervisor/, no?
> >
> > So far hypervisor_kobj only used by Xen and S390.
>
> As with everything else around TDX, it's not clear to me. The TDX module
> is a new middle ground between the hypervisor and CPU. It's literally
> there to arbitrate between the trusted CPU world and the untrusted
> hypervisor world.
The TDX module has absorbed some functionality that was traditionally
provided by the hypervisor. Treating it as a hypervisor is a valid
option. But, yeah, I agree that it is not an exact match.
> It's messy because there was (previously) no component there. It's new
> space. We could (theoretically) a Linux guest running under Xen the
> hypervisor using TDX. So we can't trivially just take over
> /sys/hypervisor for TDX.
Note that Xen uses /sys/hypervisor/xen, so there's no conflict, we can
have both xen and tdx_whatever there.
--
Kiryl Shutsemau / Kirill A. Shutemov
^ permalink raw reply
* Re: [PATCH v2 1/7] KVM: x86: Move kvm_rebooting to x86
From: Dave Hansen @ 2026-01-05 17:48 UTC (permalink / raw)
To: Sean Christopherson, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Kiryl Shutsemau, Paolo Bonzini
Cc: linux-kernel, linux-coco, kvm, Chao Gao, Dan Williams
In-Reply-To: <20251206011054.494190-2-seanjc@google.com>
On 12/5/25 17:10, Sean Christopherson wrote:
> Move kvm_rebooting, which is only read by x86, to KVM x86 so that it can
> be moved again to core x86 code. Add a "shutdown" arch hook to facilate
> setting the flag in KVM x86.
For the pure code move:
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
That said, I wouldn't mind some clarification around 'kvm_rebooting' and
a small bit of documentation about what kvm_arch_shutdown() is conceptually.
It doesn't have to be in this set, but maybe:
/*
* Override this to make global, arch-specific changes which
* prepare the system to disable hardware virtualization support.
*/
__weak void kvm_arch_shutdown(void)
{
}
and something like:
void kvm_arch_shutdown(void)
{
/*
* Indicate that hardware virtualization support will soon be
* disabled asynchronously. Attempts to use hardware
* virtualization will start generating errors and exceptions.
*
* Start being more tolerant of those conditions.
*/
kvm_rebooting = true;
smp_wmb();
}
The barrier is almost certainly not needed in practice. But I do find it
helpful as an indicator that other CPUs are going to be reading this
thing and we have zero clue what they're doing.
^ permalink raw reply
* Re: [PATCH v2 0/3] Expose TDX Module version
From: Dave Hansen @ 2026-01-05 17:19 UTC (permalink / raw)
To: Kiryl Shutsemau
Cc: Chao Gao, kvm, linux-coco, linux-kernel, x86, vishal.l.verma,
kai.huang, dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
Thomas Gleixner
In-Reply-To: <zhsopfh4qddsg2q5xj26koahf2xzyg2qvn7oo4sqyd3z4mhnly@u7bwmrzxqbhx>
On 1/5/26 09:04, Kiryl Shutsemau wrote:
>> What are other CPU vendors doing for this? SEV? CCA? S390? How are their
>> firmware versions exposed? What about other things in the Intel world
>> like CPU microcode or the billion other chunks of firmware? How about
>> hypervisors? Do they expose their versions to guests with an explicit
>> ABI? Are those exposed to userspace?
> My first thought was that it should be under /sys/hypervisor/, no?
>
> So far hypervisor_kobj only used by Xen and S390.
As with everything else around TDX, it's not clear to me. The TDX module
is a new middle ground between the hypervisor and CPU. It's literally
there to arbitrate between the trusted CPU world and the untrusted
hypervisor world.
It's messy because there was (previously) no component there. It's new
space. We could (theoretically) a Linux guest running under Xen the
hypervisor using TDX. So we can't trivially just take over
/sys/hypervisor for TDX.
It's equally valid to sit here and claim that the TDX module is CPU
microcode. Sure, there's source code for it, but only Intel can bless
it, a version of it is loaded by the BIOS and can be updated by the OS.
It's not _super_ different conceptually than SGX XuCode.
The main thing that makes the TDX module _not_ CPU microcode is that
it's managed completely separately and there's almost no connection
between this:
/sys/devices/system/cpu/cpu*/microcode/version
and the TDX module version.
Since there's a dearth of discussion of this topic in the changelog or
cover letter, my working assumption is that Chao did not consider any of
this before posting.
^ permalink raw reply
* Re: [PATCH v2 0/3] Expose TDX Module version
From: Kiryl Shutsemau @ 2026-01-05 17:04 UTC (permalink / raw)
To: Dave Hansen
Cc: Chao Gao, kvm, linux-coco, linux-kernel, x86, vishal.l.verma,
kai.huang, dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
Thomas Gleixner
In-Reply-To: <d45cc504-509c-48a7-88e2-374e00068e79@intel.com>
On Mon, Jan 05, 2026 at 08:04:21AM -0800, Dave Hansen wrote:
> On 1/5/26 02:38, Kiryl Shutsemau wrote:
> >> To address this issue, this series exposes the TDX Module version as
> >> sysfs attributes of the tdx_host device [*] and also prints it in dmesg
> >> to keep a record.
> > The version information is also useful for the guest. Maybe we should
> > provide consistent interface for both sides?
>
> Could you elaborate a bit on what constitutes consistency here?
>
> Do you mean simply ensuring that the TDX module version _is_ exposed on
> both hosts and guests, like in:
>
> /sys/devices/faux/tdx_host/version
>
> and (making this one up):
>
> /sys/devices/faux/tdx_guest/version
>
> Note the "host" vs. "guest" ^^^^^
>
> Or, that the TDX module version be exposed in the *same* ABI in both
> host and guest, like:
>
> /sys/devices/faux/tdx/version
I am not sure. It depends on what will be in these directories besides
the version. We might want to dump TDX features too, they are common for
host and guest. But there are going to be guest/td specific things (like
attributes or TD CTLS) and stuff that is only relevant for the host.
Maybe it is better to keep them separate, but with the common scheme. It
will keep door open for nested TDs (not partitioning) if they ever happen.
It might require two directories in the same environment.
I also wounder if it is possible to share code of this metadata retrieval
between guest and host. It should be doable.
> Generally, I find myself really wanting to know how this fits into the
> larger picture. Using this "faux" device really seems novel and
> TDX-specific. Should it be?
>
> What are other CPU vendors doing for this? SEV? CCA? S390? How are their
> firmware versions exposed? What about other things in the Intel world
> like CPU microcode or the billion other chunks of firmware? How about
> hypervisors? Do they expose their versions to guests with an explicit
> ABI? Are those exposed to userspace?
My first thought was that it should be under /sys/hypervisor/, no?
So far hypervisor_kobj only used by Xen and S390.
> For instance, I hear a lot of talk about updating the TDX module. But is
> this interface consistent with doing updates? Long term, I was hoping
> that TDX firmware could get treated like any other blob of modern
> firmware and have fwupd manage it, so I asked:
>
> https://chatgpt.com/share/695be06c-3d40-8012-97c9-2089fc33cbb3
>
> My read on your approach here is that our new LLM overlords might
> consider it the "last resort".
--
Kiryl Shutsemau / Kirill A. Shutemov
^ permalink raw reply
* Re: [PATCH v2 0/3] Expose TDX Module version
From: Dave Hansen @ 2026-01-05 16:04 UTC (permalink / raw)
To: Kiryl Shutsemau, Chao Gao
Cc: kvm, linux-coco, linux-kernel, x86, vishal.l.verma, kai.huang,
dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
Thomas Gleixner
In-Reply-To: <dfb66mcbxqw2a6qjyg74jqp7aucmnkztl224rj3u6znrcr7ukw@yy65kqagdsoh>
On 1/5/26 02:38, Kiryl Shutsemau wrote:
>> To address this issue, this series exposes the TDX Module version as
>> sysfs attributes of the tdx_host device [*] and also prints it in dmesg
>> to keep a record.
> The version information is also useful for the guest. Maybe we should
> provide consistent interface for both sides?
Could you elaborate a bit on what constitutes consistency here?
Do you mean simply ensuring that the TDX module version _is_ exposed on
both hosts and guests, like in:
/sys/devices/faux/tdx_host/version
and (making this one up):
/sys/devices/faux/tdx_guest/version
Note the "host" vs. "guest" ^^^^^
Or, that the TDX module version be exposed in the *same* ABI in both
host and guest, like:
/sys/devices/faux/tdx/version
Generally, I find myself really wanting to know how this fits into the
larger picture. Using this "faux" device really seems novel and
TDX-specific. Should it be?
What are other CPU vendors doing for this? SEV? CCA? S390? How are their
firmware versions exposed? What about other things in the Intel world
like CPU microcode or the billion other chunks of firmware? How about
hypervisors? Do they expose their versions to guests with an explicit
ABI? Are those exposed to userspace?
For instance, I hear a lot of talk about updating the TDX module. But is
this interface consistent with doing updates? Long term, I was hoping
that TDX firmware could get treated like any other blob of modern
firmware and have fwupd manage it, so I asked:
https://chatgpt.com/share/695be06c-3d40-8012-97c9-2089fc33cbb3
My read on your approach here is that our new LLM overlords might
consider it the "last resort".
^ permalink raw reply
* Re: [PATCH v2 0/3] Expose TDX Module version
From: Kiryl Shutsemau @ 2026-01-05 10:38 UTC (permalink / raw)
To: Chao Gao
Cc: kvm, linux-coco, linux-kernel, x86, vishal.l.verma, kai.huang,
dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
Thomas Gleixner
In-Reply-To: <20260105074350.98564-1-chao.gao@intel.com>
On Sun, Jan 04, 2026 at 11:43:43PM -0800, Chao Gao wrote:
> Hi reviewers,
>
> This series is quite straightforward and I believe it's well-polished.
> Please consider providing your ack tags. However, since it depends on
> two other series (listed below), please review those dependencies first if
> you haven't already.
>
> Changes in v2:
> - Print TDX Module version in demsg (Vishal)
> - Remove all descriptions about autogeneration (Rick)
> - Fix typos (Kai)
> - Stick with TDH.SYS.RD (Dave/Yilun)
> - Rebase onto Sean's VMXON v2 series
>
> === Problem & Solution ===
>
> Currently, there is no user interface to get the TDX Module version.
> However, in bug reporting or analysis scenarios, the first question
> normally asked is which TDX Module version is on your system, to determine
> if this is a known issue or a new regression.
>
> To address this issue, this series exposes the TDX Module version as
> sysfs attributes of the tdx_host device [*] and also prints it in dmesg
> to keep a record.
The version information is also useful for the guest. Maybe we should
provide consistent interface for both sides?
--
Kiryl Shutsemau / Kirill A. Shutemov
^ permalink raw reply
* Re: [PATCH v2] PCI/IDE: Fix duplicate stream symlink names for TSM class devices
From: Jonathan Cameron @ 2026-01-05 10:13 UTC (permalink / raw)
To: Xu Yilun
Cc: linux-coco, linux-pci, dan.j.williams, yilun.xu, baolu.lu,
zhenzhong.duan, linux-kernel, yi1.lai, helgaas
In-Reply-To: <20260105093516.2645397-1-yilun.xu@linux.intel.com>
On Mon, 5 Jan 2026 17:35:16 +0800
Xu Yilun <yilun.xu@linux.intel.com> wrote:
> The name streamH.R.E is used for 2 symlinks:
>
> 1. TSM class devices: /sys/class/tsm/tsmN/streamH.R.E
> 2. host bridge devices: /sys/devices/pciDDDD:BB/streamH.R.E
For those who have managed to completely forget, it would be useful
to just mention what H R and E are. Given the docs
say H is the host bridge number I'm a little confused why it
isn't unique. At least at first glance I'd expect to see
stream0.0.0 and stream 1.0.0 your example.
Maybe H isn't unique across segments / PCI Domains? (DDDD in the above)
Maybe it should be?
Jonathan.
>
> The first usage is broken cause streamH.R.E is only unique within a
> specific host bridge but not across the system. Error occurs e.g. when
> creating the first stream on a second host bridge:
>
> sysfs: cannot create duplicate filename '/devices/faux/tdx_host/tsm/tsm0/stream0.0.0'
>
> Fix this by adding host bridge name into symlink name for TSM class
> devices so they show up as:
>
> /sys/class/tsm/tsmN/pciDDDD:BB:streamH.R.E
>
> It should be OK to change the uAPI since it's new and has few users.
>
> The symlink name for host bridge devices keeps unchanged. Keep concise
> as it is already in host bridge context.
>
> Internally in the IDE library, store the full name in struct pci_ide
> so TSM symlinks can use it directly as before, while host bridge
> symlinks use only the streamH.R.E portion to preserve the existing name.
>
> Fixes: a4438f06b1db ("PCI/TSM: Report active IDE streams")
> Reported-by: Yi Lai <yi1.lai@intel.com>
> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
> ---
> v2: Changelog improvements
>
> v1: https://lore.kernel.org/linux-coco/20251223085601.2607455-1-yilun.xu@linux.intel.com/
> ---
> Documentation/ABI/testing/sysfs-class-tsm | 2 +-
> drivers/pci/ide.c | 12 +++++++++---
> 2 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/testing/sysfs-class-tsm
> index 6fc1a5ac6da1..eff71e42c60e 100644
> --- a/Documentation/ABI/testing/sysfs-class-tsm
> +++ b/Documentation/ABI/testing/sysfs-class-tsm
> @@ -8,7 +8,7 @@ Description:
> link encryption and other device-security features coordinated
> through a platform tsm.
>
> -What: /sys/class/tsm/tsmN/streamH.R.E
> +What: /sys/class/tsm/tsmN/pciDDDD:BB:streamH.R.E
> Contact: linux-pci@vger.kernel.org
> Description:
> (RO) When a host bridge has established a secure connection via
> diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c
> index f0ef474e1a0d..58fbe9cfd68c 100644
> --- a/drivers/pci/ide.c
> +++ b/drivers/pci/ide.c
> @@ -425,6 +425,7 @@ int pci_ide_stream_register(struct pci_ide *ide)
> struct pci_host_bridge *hb = pci_find_host_bridge(pdev->bus);
> struct pci_ide_stream_id __sid;
> u8 ep_stream, rp_stream;
> + const char *short_name;
> int rc;
>
> if (ide->stream_id < 0 || ide->stream_id > U8_MAX) {
> @@ -441,13 +442,16 @@ int pci_ide_stream_register(struct pci_ide *ide)
>
> ep_stream = ide->partner[PCI_IDE_EP].stream_index;
> rp_stream = ide->partner[PCI_IDE_RP].stream_index;
> - const char *name __free(kfree) = kasprintf(GFP_KERNEL, "stream%d.%d.%d",
> + const char *name __free(kfree) = kasprintf(GFP_KERNEL, "%s:stream%d.%d.%d",
> + dev_name(&hb->dev),
> ide->host_bridge_stream,
> rp_stream, ep_stream);
> if (!name)
> return -ENOMEM;
>
> - rc = sysfs_create_link(&hb->dev.kobj, &pdev->dev.kobj, name);
> + /* Strip host bridge name in the host bridge context */
> + short_name = name + strlen(dev_name(&hb->dev)) + 1;
> + rc = sysfs_create_link(&hb->dev.kobj, &pdev->dev.kobj, short_name);
> if (rc)
> return rc;
>
> @@ -471,8 +475,10 @@ void pci_ide_stream_unregister(struct pci_ide *ide)
> {
> struct pci_dev *pdev = ide->pdev;
> struct pci_host_bridge *hb = pci_find_host_bridge(pdev->bus);
> + const char *short_name;
>
> - sysfs_remove_link(&hb->dev.kobj, ide->name);
> + short_name = ide->name + strlen(dev_name(&hb->dev)) + 1;
> + sysfs_remove_link(&hb->dev.kobj, short_name);
> kfree(ide->name);
> ida_free(&hb->ide_stream_ids_ida, ide->stream_id);
> ide->name = NULL;
>
> base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
^ permalink raw reply
* [PATCH v2] PCI/IDE: Fix duplicate stream symlink names for TSM class devices
From: Xu Yilun @ 2026-01-05 9:35 UTC (permalink / raw)
To: linux-coco, linux-pci, dan.j.williams
Cc: yilun.xu, yilun.xu, baolu.lu, zhenzhong.duan, linux-kernel,
yi1.lai, helgaas
The name streamH.R.E is used for 2 symlinks:
1. TSM class devices: /sys/class/tsm/tsmN/streamH.R.E
2. host bridge devices: /sys/devices/pciDDDD:BB/streamH.R.E
The first usage is broken cause streamH.R.E is only unique within a
specific host bridge but not across the system. Error occurs e.g. when
creating the first stream on a second host bridge:
sysfs: cannot create duplicate filename '/devices/faux/tdx_host/tsm/tsm0/stream0.0.0'
Fix this by adding host bridge name into symlink name for TSM class
devices so they show up as:
/sys/class/tsm/tsmN/pciDDDD:BB:streamH.R.E
It should be OK to change the uAPI since it's new and has few users.
The symlink name for host bridge devices keeps unchanged. Keep concise
as it is already in host bridge context.
Internally in the IDE library, store the full name in struct pci_ide
so TSM symlinks can use it directly as before, while host bridge
symlinks use only the streamH.R.E portion to preserve the existing name.
Fixes: a4438f06b1db ("PCI/TSM: Report active IDE streams")
Reported-by: Yi Lai <yi1.lai@intel.com>
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
---
v2: Changelog improvements
v1: https://lore.kernel.org/linux-coco/20251223085601.2607455-1-yilun.xu@linux.intel.com/
---
Documentation/ABI/testing/sysfs-class-tsm | 2 +-
drivers/pci/ide.c | 12 +++++++++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/testing/sysfs-class-tsm
index 6fc1a5ac6da1..eff71e42c60e 100644
--- a/Documentation/ABI/testing/sysfs-class-tsm
+++ b/Documentation/ABI/testing/sysfs-class-tsm
@@ -8,7 +8,7 @@ Description:
link encryption and other device-security features coordinated
through a platform tsm.
-What: /sys/class/tsm/tsmN/streamH.R.E
+What: /sys/class/tsm/tsmN/pciDDDD:BB:streamH.R.E
Contact: linux-pci@vger.kernel.org
Description:
(RO) When a host bridge has established a secure connection via
diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c
index f0ef474e1a0d..58fbe9cfd68c 100644
--- a/drivers/pci/ide.c
+++ b/drivers/pci/ide.c
@@ -425,6 +425,7 @@ int pci_ide_stream_register(struct pci_ide *ide)
struct pci_host_bridge *hb = pci_find_host_bridge(pdev->bus);
struct pci_ide_stream_id __sid;
u8 ep_stream, rp_stream;
+ const char *short_name;
int rc;
if (ide->stream_id < 0 || ide->stream_id > U8_MAX) {
@@ -441,13 +442,16 @@ int pci_ide_stream_register(struct pci_ide *ide)
ep_stream = ide->partner[PCI_IDE_EP].stream_index;
rp_stream = ide->partner[PCI_IDE_RP].stream_index;
- const char *name __free(kfree) = kasprintf(GFP_KERNEL, "stream%d.%d.%d",
+ const char *name __free(kfree) = kasprintf(GFP_KERNEL, "%s:stream%d.%d.%d",
+ dev_name(&hb->dev),
ide->host_bridge_stream,
rp_stream, ep_stream);
if (!name)
return -ENOMEM;
- rc = sysfs_create_link(&hb->dev.kobj, &pdev->dev.kobj, name);
+ /* Strip host bridge name in the host bridge context */
+ short_name = name + strlen(dev_name(&hb->dev)) + 1;
+ rc = sysfs_create_link(&hb->dev.kobj, &pdev->dev.kobj, short_name);
if (rc)
return rc;
@@ -471,8 +475,10 @@ void pci_ide_stream_unregister(struct pci_ide *ide)
{
struct pci_dev *pdev = ide->pdev;
struct pci_host_bridge *hb = pci_find_host_bridge(pdev->bus);
+ const char *short_name;
- sysfs_remove_link(&hb->dev.kobj, ide->name);
+ short_name = ide->name + strlen(dev_name(&hb->dev)) + 1;
+ sysfs_remove_link(&hb->dev.kobj, short_name);
kfree(ide->name);
ida_free(&hb->ide_stream_ids_ida, ide->stream_id);
ide->name = NULL;
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v2 00/21] Runtime TDX Module update support
From: Chao Gao @ 2026-01-05 7:54 UTC (permalink / raw)
To: Dave Hansen
Cc: Edgecombe, Rick P, Huang, Kai, x86@kernel.org,
yilun.xu@linux.intel.com, Chatre, Reinette,
linux-kernel@vger.kernel.org, Williams, Dan J, Weiny, Ira,
Annapurve, Vishal, linux-coco@lists.linux.dev, paulmck@kernel.org,
nik.borisov@suse.com, sagis@google.com, hpa@zytor.com,
tglx@linutronix.de, mingo@redhat.com, kas@kernel.org,
pbonzini@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com
In-Reply-To: <8d7817ea-317c-4ddb-bb5c-a7b2fab1ad3d@intel.com>
On Fri, Jan 02, 2026 at 01:15:33PM -0800, Dave Hansen wrote:
>On 1/2/26 12:52, Edgecombe, Rick P wrote:>> Would you be able to take a
>look at this series when you get a
>>> chance? I'd appreciate your feedback.
>> I can't apply it. The source commit is gone from the tsm repo, but
>> besides that it requires applying a bunch of dependencies.
>If there are dependencies, is this the right thing for reviewers to be
>spending time on? Shouldn't they be making sure the dependencies are
>reviewed and merged first?
Agreed. Please review the dependencies first.
TDX Module update series has three dependencies:
1. Sean's VMXON series:
https://lore.kernel.org/kvm/20251206011054.494190-1-seanjc@google.com/#t
2. TDX host virtual device (the first patch in the series below)
https://lore.kernel.org/kvm/20251117022311.2443900-2-yilun.xu@linux.intel.com/
3. TDX Module version reporting
https://lore.kernel.org/linux-coco/20260105074350.98564-1-chao.gao@intel.com/
^ permalink raw reply
* [PATCH v2 3/3] x86/virt/tdx: Print TDX Module version during init
From: Chao Gao @ 2026-01-05 7:43 UTC (permalink / raw)
To: linux-kernel, linux-coco, kvm
Cc: vishal.l.verma, kai.huang, dan.j.williams, yilun.xu, vannapurve,
Chao Gao, Rick Edgecombe, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Kiryl Shutsemau
In-Reply-To: <20260105074350.98564-1-chao.gao@intel.com>
From: Vishal Verma <vishal.l.verma@intel.com>
Alongside exposing the TDX Module version via sysfs, it is useful to
have a record of it in dmesg logs. This allows for a quick spot check
for whether the correct/expected TDX module is being loaded, and also
creates a record for any future problems being investigated. This was
also requested in [1].
The log message will look like:
virt/tdx: TDX-Module version: 1.5.24
Print this early in init_tdx_module(), right after the global metadata
is read, which makes it available even if there are subsequent
initialization failures.
Based on a patch by Kai Huang <kai.huang@intel.com> [2]
[ Chao: s/TDX module/TDX-Module in the log message
tag print_module_version() as __init ]
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: Kai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/all/CAGtprH8eXwi-TcH2+-Fo5YdbEwGmgLBh9ggcDvd6N=bsKEJ_WQ@mail.gmail.com/ # [1]
Link: https://lore.kernel.org/all/6b5553756f56a8e3222bfc36d0bdb3e5192137b7.1731318868.git.kai.huang@intel.com # [2]
---
v2
- new
arch/x86/virt/vmx/tdx/tdx.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index ef77135ec373..3282dce5003b 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -352,6 +352,13 @@ static __init int read_sys_metadata_field(u64 field_id, u64 *data)
#include "tdx_global_metadata.c"
+static __init void print_module_version(struct tdx_sys_info_version *version)
+{
+ pr_info("TDX-Module version: %u.%u.%02u\n",
+ version->major_version, version->minor_version,
+ version->update_version);
+}
+
static __init int check_features(struct tdx_sys_info *sysinfo)
{
u64 tdx_features0 = sysinfo->features.tdx_features0;
@@ -1158,6 +1165,8 @@ static __init int init_tdx_module(void)
if (ret)
return ret;
+ print_module_version(&tdx_sysinfo.version);
+
/* Check whether the kernel can support this module */
ret = check_features(&tdx_sysinfo);
if (ret)
--
2.47.3
^ permalink raw reply related
* [PATCH v2 2/3] coco/tdx-host: Expose TDX Module version
From: Chao Gao @ 2026-01-05 7:43 UTC (permalink / raw)
To: x86, linux-coco, kvm, linux-kernel
Cc: vishal.l.verma, kai.huang, dan.j.williams, yilun.xu, vannapurve,
Chao Gao, Kiryl Shutsemau, Dave Hansen, Rick Edgecombe
In-Reply-To: <20260105074350.98564-1-chao.gao@intel.com>
Currently there is no way to know the TDX Module version from the
userspace. Such information is always helpful for bug reporting or
debugging.
With the tdx-host device in place, expose the TDX Module version as
a device attribute via sysfs.
Signed-off-by: Chao Gao <chao.gao@intel.com>
---
v2:
- No need to update MAINTAINERS to include sysfs-devices-faux-tdx-host
explicitly (Kirill)
.../ABI/testing/sysfs-devices-faux-tdx-host | 6 +++++
drivers/virt/coco/tdx-host/tdx-host.c | 26 ++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-devices-faux-tdx-host
diff --git a/Documentation/ABI/testing/sysfs-devices-faux-tdx-host b/Documentation/ABI/testing/sysfs-devices-faux-tdx-host
new file mode 100644
index 000000000000..35ef21f53c2e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-faux-tdx-host
@@ -0,0 +1,6 @@
+What: /sys/devices/faux/tdx_host/version
+Contact: linux-coco@lists.linux.dev
+Description: (RO) Report the version of the loaded TDX Module. The TDX Module
+ version is formatted as x.y.z, where "x" is the major version,
+ "y" is the minor version and "z" is the update version. Versions
+ are used for bug reporting, TD-Preserving updates and etc.
diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c
index ced1c980dc6f..2883c6638faf 100644
--- a/drivers/virt/coco/tdx-host/tdx-host.c
+++ b/drivers/virt/coco/tdx-host/tdx-host.c
@@ -9,6 +9,7 @@
#include <linux/mod_devicetable.h>
#include <linux/device/faux.h>
#include <asm/cpu_device_id.h>
+#include <asm/tdx.h>
static const struct x86_cpu_id tdx_host_ids[] = {
X86_MATCH_FEATURE(X86_FEATURE_TDX_HOST_PLATFORM, NULL),
@@ -18,12 +19,35 @@ MODULE_DEVICE_TABLE(x86cpu, tdx_host_ids);
static struct faux_device *fdev;
+static ssize_t version_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ const struct tdx_sys_info *tdx_sysinfo = tdx_get_sysinfo();
+ const struct tdx_sys_info_version *ver;
+
+ if (!tdx_sysinfo)
+ return -ENXIO;
+
+ ver = &tdx_sysinfo->version;
+
+ return sysfs_emit(buf, "%u.%u.%02u\n", ver->major_version,
+ ver->minor_version,
+ ver->update_version);
+}
+static DEVICE_ATTR_RO(version);
+
+static struct attribute *tdx_host_attrs[] = {
+ &dev_attr_version.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(tdx_host);
+
static int __init tdx_host_init(void)
{
if (!x86_match_cpu(tdx_host_ids))
return -ENODEV;
- fdev = faux_device_create(KBUILD_MODNAME, NULL, NULL);
+ fdev = faux_device_create_with_groups(KBUILD_MODNAME, NULL, NULL, tdx_host_groups);
if (!fdev)
return -ENODEV;
--
2.47.3
^ permalink raw reply related
* [PATCH v2 1/3] x86/virt/tdx: Retrieve TDX Module version
From: Chao Gao @ 2026-01-05 7:43 UTC (permalink / raw)
To: linux-kernel, linux-coco, kvm
Cc: vishal.l.verma, kai.huang, dan.j.williams, yilun.xu, vannapurve,
Chao Gao, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Kiryl Shutsemau, Rick Edgecombe
In-Reply-To: <20260105074350.98564-1-chao.gao@intel.com>
Each TDX Module is associated with a version in the x.y.z format, where x
represents the major version, y the minor version, and z the update
version. Knowing the running TDX Module version is valuable for bug
reporting and debugging.
Retrieve the TDX Module version using the existing metadata reading
interface, in preparation for exposing it to userspace via sysfs.
Signed-off-by: Chao Gao <chao.gao@intel.com>
---
v2:
- Remove all descriptions about autogeneration (Rick)
- TDH.SYS.RDALL isn't worth the code churn. So, stick with TDH.SYS.RD
(Dave/Yilun)
arch/x86/include/asm/tdx_global_metadata.h | 7 +++++++
arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
index 060a2ad744bf..40689c8dc67e 100644
--- a/arch/x86/include/asm/tdx_global_metadata.h
+++ b/arch/x86/include/asm/tdx_global_metadata.h
@@ -5,6 +5,12 @@
#include <linux/types.h>
+struct tdx_sys_info_version {
+ u16 minor_version;
+ u16 major_version;
+ u16 update_version;
+};
+
struct tdx_sys_info_features {
u64 tdx_features0;
};
@@ -35,6 +41,7 @@ struct tdx_sys_info_td_conf {
};
struct tdx_sys_info {
+ struct tdx_sys_info_version version;
struct tdx_sys_info_features features;
struct tdx_sys_info_tdmr tdmr;
struct tdx_sys_info_td_ctrl td_ctrl;
diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
index 360963bc9328..85ab17b36c81 100644
--- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
+++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
@@ -7,6 +7,21 @@
* Include this file to other C file instead.
*/
+static __init int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version)
+{
+ int ret = 0;
+ u64 val;
+
+ if (!ret && !(ret = read_sys_metadata_field(0x0800000100000003, &val)))
+ sysinfo_version->minor_version = val;
+ if (!ret && !(ret = read_sys_metadata_field(0x0800000100000004, &val)))
+ sysinfo_version->major_version = val;
+ if (!ret && !(ret = read_sys_metadata_field(0x0800000100000005, &val)))
+ sysinfo_version->update_version = val;
+
+ return ret;
+}
+
static __init int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features)
{
int ret = 0;
@@ -89,6 +104,7 @@ static __init int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
{
int ret = 0;
+ ret = ret ?: get_tdx_sys_info_version(&sysinfo->version);
ret = ret ?: get_tdx_sys_info_features(&sysinfo->features);
ret = ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr);
ret = ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl);
--
2.47.3
^ permalink raw reply related
* [PATCH v2 0/3] Expose TDX Module version
From: Chao Gao @ 2026-01-05 7:43 UTC (permalink / raw)
To: kvm, linux-coco, linux-kernel, x86
Cc: vishal.l.verma, kai.huang, dan.j.williams, yilun.xu, vannapurve,
Chao Gao, Borislav Petkov, Dave Hansen, H. Peter Anvin,
Ingo Molnar, Kiryl Shutsemau, Rick Edgecombe, Thomas Gleixner
Hi reviewers,
This series is quite straightforward and I believe it's well-polished.
Please consider providing your ack tags. However, since it depends on
two other series (listed below), please review those dependencies first if
you haven't already.
Changes in v2:
- Print TDX Module version in demsg (Vishal)
- Remove all descriptions about autogeneration (Rick)
- Fix typos (Kai)
- Stick with TDH.SYS.RD (Dave/Yilun)
- Rebase onto Sean's VMXON v2 series
=== Problem & Solution ===
Currently, there is no user interface to get the TDX Module version.
However, in bug reporting or analysis scenarios, the first question
normally asked is which TDX Module version is on your system, to determine
if this is a known issue or a new regression.
To address this issue, this series exposes the TDX Module version as
sysfs attributes of the tdx_host device [*] and also prints it in dmesg
to keep a record.
=== Dependency ===
This series has two dependencies:
1. Have TDX handle VMXON during bringup
https://lore.kernel.org/kvm/20251206011054.494190-1-seanjc@google.com/#t
2. TDX host virtual device (the first patch in the series below)
https://lore.kernel.org/kvm/20251117022311.2443900-2-yilun.xu@linux.intel.com/
For your convenience, both dependencies and the series are also
available at
https://github.com/gaochaointel/linux-dev/tree/tdx-module-version-v2
Chao Gao (2):
x86/virt/tdx: Retrieve TDX Module version
coco/tdx-host: Expose TDX Module version
Vishal Verma (1):
x86/virt/tdx: Print TDX Module version during init
.../ABI/testing/sysfs-devices-faux-tdx-host | 6 +++++
arch/x86/include/asm/tdx_global_metadata.h | 7 +++++
arch/x86/virt/vmx/tdx/tdx.c | 9 +++++++
arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++
drivers/virt/coco/tdx-host/tdx-host.c | 26 ++++++++++++++++++-
5 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-devices-faux-tdx-host
--
2.47.3
^ permalink raw reply
* Re: [PATCH v2 00/21] Runtime TDX Module update support
From: Chao Gao @ 2026-01-04 1:39 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: Huang, Kai, x86@kernel.org, yilun.xu@linux.intel.com,
Chatre, Reinette, linux-kernel@vger.kernel.org, Williams, Dan J,
Weiny, Ira, Annapurve, Vishal, linux-coco@lists.linux.dev,
paulmck@kernel.org, nik.borisov@suse.com, sagis@google.com,
hpa@zytor.com, tglx@linutronix.de, mingo@redhat.com,
kas@kernel.org, pbonzini@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com
In-Reply-To: <4bb43ec912f3bfb92d0f9071143b4b046d5db08d.camel@intel.com>
On Sat, Jan 03, 2026 at 04:52:43AM +0800, Edgecombe, Rick P wrote:
>On Wed, 2025-11-12 at 22:09 +0800, Chao Gao wrote:
>> On Tue, Sep 30, 2025 at 07:52:44PM -0700, Chao Gao wrote:
>> > Hi Reviewers,
>> >
>> > This series adds support for runtime TDX Module updates that
>> > preserve
>> > running TDX guests.
>>
>> Hi Kirill and Rick,
>>
>> Would you be able to take a look at this series when you get a
>> chance?
>> I'd appreciate your feedback.
>
>I can't apply it. The source commit is gone from the tsm repo, but
>besides that it requires applying a bunch of dependencies.
>
>Can you push a branch somewhere? When there is a stack like this, it is
>kind of needed to ease review.
Sure. Here is the branch:
https://github.com/gaochaointel/linux-dev/commits/tdx-module-update-v2/
^ permalink raw reply
* Re: [PATCH v2 00/21] Runtime TDX Module update support
From: Dave Hansen @ 2026-01-02 21:15 UTC (permalink / raw)
To: Edgecombe, Rick P, Gao, Chao, Huang, Kai, x86@kernel.org,
yilun.xu@linux.intel.com, Chatre, Reinette,
linux-kernel@vger.kernel.org, Williams, Dan J, Weiny, Ira,
Annapurve, Vishal, linux-coco@lists.linux.dev, paulmck@kernel.org,
nik.borisov@suse.com, sagis@google.com
Cc: hpa@zytor.com, tglx@linutronix.de, mingo@redhat.com,
kas@kernel.org, pbonzini@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com
In-Reply-To: <4bb43ec912f3bfb92d0f9071143b4b046d5db08d.camel@intel.com>
On 1/2/26 12:52, Edgecombe, Rick P wrote:>> Would you be able to take a
look at this series when you get a
>> chance? I'd appreciate your feedback.
> I can't apply it. The source commit is gone from the tsm repo, but
> besides that it requires applying a bunch of dependencies.
If there are dependencies, is this the right thing for reviewers to be
spending time on? Shouldn't they be making sure the dependencies are
reviewed and merged first?
^ permalink raw reply
* Re: [PATCH v2 00/21] Runtime TDX Module update support
From: Edgecombe, Rick P @ 2026-01-02 20:52 UTC (permalink / raw)
To: Gao, Chao, Huang, Kai, x86@kernel.org, yilun.xu@linux.intel.com,
Chatre, Reinette, linux-kernel@vger.kernel.org, Williams, Dan J,
Weiny, Ira, Annapurve, Vishal, linux-coco@lists.linux.dev,
paulmck@kernel.org, nik.borisov@suse.com, sagis@google.com
Cc: hpa@zytor.com, tglx@linutronix.de, mingo@redhat.com,
kas@kernel.org, pbonzini@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com
In-Reply-To: <aRSVB3TQxpgZPj+F@intel.com>
On Wed, 2025-11-12 at 22:09 +0800, Chao Gao wrote:
> On Tue, Sep 30, 2025 at 07:52:44PM -0700, Chao Gao wrote:
> > Hi Reviewers,
> >
> > This series adds support for runtime TDX Module updates that
> > preserve
> > running TDX guests.
>
> Hi Kirill and Rick,
>
> Would you be able to take a look at this series when you get a
> chance?
> I'd appreciate your feedback.
I can't apply it. The source commit is gone from the tsm repo, but
besides that it requires applying a bunch of dependencies.
Can you push a branch somewhere? When there is a stack like this, it is
kind of needed to ease review.
^ permalink raw reply
* [PATCH] dma-direct: swiotlb: Skip encryption toggles for swiotlb allocations
From: Aneesh Kumar K.V (Arm) @ 2026-01-02 15:54 UTC (permalink / raw)
To: iommu, linux-kernel, linux-coco
Cc: Marek Szyprowski, Robin Murphy, steven.price, Suzuki K Poulose,
Aneesh Kumar K.V (Arm)
Swiotlb backing pages are already mapped decrypted via
swiotlb_update_mem_attributes(), so dma-direct does not need to call
set_memory_decrypted() during allocation or re-encrypt the memory on
free.
Handle swiotlb-backed buffers explicitly: obtain the DMA address and
zero the linear mapping for lowmem pages, and bypass the decrypt/encrypt
transitions when allocating/freeing from the swiotlb pool (detected via
swiotlb_find_pool()).
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
kernel/dma/direct.c | 56 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 46 insertions(+), 10 deletions(-)
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index faf1e41afde8..c4ef4457bd74 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -104,15 +104,27 @@ static void __dma_direct_free_pages(struct device *dev, struct page *page,
dma_free_contiguous(dev, page, size);
}
-static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size)
+static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size,
+ dma_addr_t *dma_handle)
{
- struct page *page = swiotlb_alloc(dev, size);
+ void *lm_addr;
+ struct page *page;
+
+ page = swiotlb_alloc(dev, size);
+ if (!page)
+ return NULL;
- if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+ if (!dma_coherent_ok(dev, page_to_phys(page), size)) {
swiotlb_free(dev, page, size);
return NULL;
}
+ /* If HighMem let caller take care of creating a mapping */
+ if (PageHighMem(page))
+ return page;
+ lm_addr = page_address(page);
+ memset(lm_addr, 0, size);
+ *dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
return page;
}
@@ -125,9 +137,6 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
WARN_ON_ONCE(!PAGE_ALIGNED(size));
- if (is_swiotlb_for_alloc(dev))
- return dma_direct_alloc_swiotlb(dev, size);
-
gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
page = dma_alloc_contiguous(dev, size, gfp);
if (page) {
@@ -204,6 +213,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
bool remap = false, set_uncached = false;
+ bool mark_mem_decrypt = true;
bool allow_highmem = true;
struct page *page;
void *ret;
@@ -251,6 +261,14 @@ void *dma_direct_alloc(struct device *dev, size_t size,
dma_direct_use_pool(dev, gfp))
return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
+ if (is_swiotlb_for_alloc(dev)) {
+ page = dma_direct_alloc_swiotlb(dev, size, dma_handle);
+ if (page) {
+ mark_mem_decrypt = false;
+ goto setup_page;
+ }
+ return NULL;
+ }
if (force_dma_unencrypted(dev))
/*
@@ -266,6 +284,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
if (!page)
return NULL;
+setup_page:
/*
* dma_alloc_contiguous can return highmem pages depending on a
* combination the cma= arguments and per-arch setup. These need to be
@@ -295,7 +314,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
ret = page_address(page);
}
- if (force_dma_unencrypted(dev)) {
+ if (mark_mem_decrypt && force_dma_unencrypted(dev)) {
void *lm_addr;
lm_addr = page_address(page);
@@ -316,7 +335,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
return ret;
out_encrypt_pages:
- if (dma_set_encrypted(dev, page_address(page), size))
+ if (mark_mem_decrypt && dma_set_encrypted(dev, page_address(page), size))
return NULL;
out_free_pages:
__dma_direct_free_pages(dev, page, size);
@@ -328,6 +347,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
void dma_direct_free(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
{
+ bool mark_mem_encrypted = true;
unsigned int page_order = get_order(size);
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
@@ -356,6 +376,9 @@ void dma_direct_free(struct device *dev, size_t size,
dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))
return;
+ if (swiotlb_find_pool(dev, dma_to_phys(dev, dma_addr)))
+ mark_mem_encrypted = false;
+
if (is_vmalloc_addr(cpu_addr)) {
vunmap(cpu_addr);
} else {
@@ -363,7 +386,7 @@ void dma_direct_free(struct device *dev, size_t size,
arch_dma_clear_uncached(cpu_addr, size);
}
- if (force_dma_unencrypted(dev)) {
+ if (mark_mem_encrypted && force_dma_unencrypted(dev)) {
void *lm_addr;
lm_addr = phys_to_virt(dma_to_phys(dev, dma_addr));
@@ -385,6 +408,15 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
if (force_dma_unencrypted(dev) && dma_direct_use_pool(dev, gfp))
return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
+ if (is_swiotlb_for_alloc(dev)) {
+ page = dma_direct_alloc_swiotlb(dev, size, dma_handle);
+ if (page && PageHighMem(page)) {
+ swiotlb_free(dev, page, size);
+ return NULL;
+ }
+ return page;
+ }
+
page = __dma_direct_alloc_pages(dev, size, gfp, false);
if (!page)
return NULL;
@@ -404,13 +436,17 @@ void dma_direct_free_pages(struct device *dev, size_t size,
enum dma_data_direction dir)
{
void *vaddr = page_address(page);
+ bool mark_mem_encrypted = true;
/* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */
if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
dma_free_from_pool(dev, vaddr, size))
return;
- if (dma_set_encrypted(dev, vaddr, size))
+ if (swiotlb_find_pool(dev, page_to_phys(page)))
+ mark_mem_encrypted = false;
+
+ if (mark_mem_encrypted && dma_set_encrypted(dev, vaddr, size))
return;
__dma_direct_free_pages(dev, page, size);
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 2/7] KVM: x86: Extract VMXON and EFER.SVME enablement to kernel
From: Sean Christopherson @ 2025-12-30 22:59 UTC (permalink / raw)
To: Xu Yilun
Cc: dan.j.williams, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, Kiryl Shutsemau, Paolo Bonzini, linux-kernel,
linux-coco, kvm, Chao Gao
In-Reply-To: <aUvJWmZP5wLpvhnw@yilunxu-OptiPlex-7050>
On Wed, Dec 24, 2025, Xu Yilun wrote:
> On Wed, Dec 10, 2025 at 06:20:17AM -0800, Sean Christopherson wrote:
> > On Wed, Dec 10, 2025, dan.j.williams@intel.com wrote:
> > > Sean Christopherson wrote:
> > > > On Sat, Dec 06, 2025, dan.j.williams@intel.com wrote:
> > > > I don't think we need anything at this time. INTEL_TDX_HOST depends on KVM_INTEL,
> > > > and so without a user that needs VMXON without KVM_INTEL, I think we're good as-is.
> > > >
> > > > config INTEL_TDX_HOST
> > > > bool "Intel Trust Domain Extensions (TDX) host support"
> > > > depends on CPU_SUP_INTEL
> > > > depends on X86_64
> > > > depends on KVM_INTEL
> > >
> > > ...but INTEL_TDX_HOST, it turns out, does not have any functional
> > > dependencies on KVM_INTEL. At least, not since I last checked. Yes, it
> > > would be silly and result in dead code today to do a build with:
> > >
> > > CONFIG_INTEL_TDX_HOST=y
> > > CONFIG_KVM_INTEL=n
> > >
> > > However, when the TDX Connect support arrives you could have:
> > >
> > > CONFIG_INTEL_TDX_HOST=y
> > > CONFIG_KVM_INTEL=n
> > > CONFIG_TDX_HOST_SERVICES=y
> > >
> > > Where "TDX Host Services" is a driver for PCIe Link Encryption and TDX
> > > Module update. Whether such configuration freedom has any practical
> > > value is a separate question.
> > >
> > > I am ok if the answer is, "wait until someone shows up who really wants
> > > PCIe Link Encryption without KVM".
> >
> > Ya, that's my answer. At the very least, wait until TDX_HOST_SERVICES comes
> > along.
>
> I've tested the PCIe Link Encryption without KVM, with the kernel
> config:
>
> CONFIG_INTEL_TDX_HOST=y
> CONFIG_KVM_INTEL=n
> CONFIG_TDX_HOST_SERVICES=y
>
> and
>
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-host/Kconfig
> @@ -0,0 +1,10 @@
> +config TDX_HOST_SERVICES
> + tristate "TDX Host Services Driver"
> + depends on INTEL_TDX_HOST
> + default m
>
> Finally I enabled the combination successfully with a patch below, do we
> need the change when TDX_HOST_SERVICES comes?
Ya, we'll need something along those lines. What exactly we want the Kconfig
soup to look like is TBD though, e.g. it may or may not make sense to have a
common config that says "I want virtualization!"?
^ permalink raw reply
* Re: [PATCH v2 4/4] dma: direct: set decrypted flag for remapped dma allocations
From: Aneesh Kumar K.V @ 2025-12-26 8:59 UTC (permalink / raw)
To: Suzuki K Poulose, linux-kernel, iommu, linux-coco
Cc: Catalin Marinas, will, maz, tglx, robin.murphy, akpm, jgg,
steven.price
In-Reply-To: <yq5ams39txvk.fsf@kernel.org>
Aneesh Kumar K.V <aneesh.kumar@kernel.org> writes:
> Suzuki K Poulose <suzuki.poulose@arm.com> writes:
>
>> On 21/12/2025 16:09, Aneesh Kumar K.V (Arm) wrote:
>>> Devices that are DMA non-coherent and need a remap were skipping
>>> dma_set_decrypted(), leaving buffers encrypted even when the device
>>> requires unencrypted access. Move the call after the remap
>>> branch so both paths mark the allocation decrypted (or fail cleanly)
>>> before use.
>>>
>>> Fixes: f3c962226dbe ("dma-direct: clean up the remapping checks in dma_direct_alloc")
>>> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>>> ---
>>> kernel/dma/direct.c | 8 +++-----
>>> 1 file changed, 3 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
>>> index 3448d877c7c6..a62dc25524cc 100644
>>> --- a/kernel/dma/direct.c
>>> +++ b/kernel/dma/direct.c
>>> @@ -271,9 +271,6 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>> if (remap) {
>>> pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs);
>>>
>>> - if (force_dma_unencrypted(dev))
>>> - prot = pgprot_decrypted(prot);
>>
>> This would be problematic, isn't it ? We don't support decrypted on a
>> vmap area for arm64. If we move this down, we might actually use the
>> vmapped area. Not sure if other archs are fine with "decrypting" a
>> "vmap" address.
>>
>> If we map the "vmap" address with pgprot_decrypted, we could go ahead
>> and further map the linear map (i.e., page_address(page)) decrypted
>> and get everything working.
>
> We still have the problem w.r.t free
>
> dma_direct_free():
>
> if (is_vmalloc_addr(cpu_addr)) {
> vunmap(cpu_addr);
> } else {
> if (dma_set_encrypted(dev, cpu_addr, size))
> return;
> }
>
How about the below change?
commit 8261c528961c6959b85de87c5659ce9081dc85b7
Author: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Date: Fri Dec 19 14:46:20 2025 +0530
dma: direct: set decrypted flag for remapped DMA allocations
Devices that are DMA non-coherent and require a remap were skipping
dma_set_decrypted(), leaving DMA buffers encrypted even when the device
requires unencrypted access. Move the call after the if (remap) branch
so that both direct and remapped allocation paths correctly mark the
allocation as decrypted (or fail cleanly) before use.
If CMA allocations return highmem pages, treat this as an allocation
error so that dma_direct_alloc() falls back to the standard allocation
path. This is required because some architectures (e.g. arm64) cannot
mark vmap addresses as decrypted, and highmem pages necessarily require
a vmap remap. As a result, such allocations cannot be safely marked
unencrypted for DMA.
Other architectures (e.g. x86) do not have this limitation, but instead
of making this architecture-specific, I have made the restriction apply
when the device requires unencrypted DMA access. This was done for
simplicity,
Fixes: f3c962226dbe ("dma-direct: clean up the remapping checks in dma_direct_alloc")
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 7c0b55ca121f..811de37ad81c 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -264,6 +264,15 @@ void *dma_direct_alloc(struct device *dev, size_t size,
* remapped to return a kernel virtual address.
*/
if (PageHighMem(page)) {
+ /*
+ * Unencrypted/shared DMA requires a linear-mapped buffer
+ * address to look up the PFN and set architecture-required PFN
+ * attributes. This is not possible with HighMem, so return
+ * failure.
+ */
+ if (force_dma_unencrypted(dev))
+ goto out_free_pages;
+
remap = true;
set_uncached = false;
}
@@ -284,7 +293,13 @@ void *dma_direct_alloc(struct device *dev, size_t size,
goto out_free_pages;
} else {
ret = page_address(page);
- if (dma_set_decrypted(dev, ret, size))
+ }
+
+ if (force_dma_unencrypted(dev)) {
+ void *lm_addr;
+
+ lm_addr = page_address(page);
+ if (set_memory_decrypted((unsigned long)lm_addr, PFN_UP(size)))
goto out_leak_pages;
}
@@ -349,8 +364,16 @@ void dma_direct_free(struct device *dev, size_t size,
} else {
if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED))
arch_dma_clear_uncached(cpu_addr, size);
- if (dma_set_encrypted(dev, cpu_addr, size))
+ }
+
+ if (force_dma_unencrypted(dev)) {
+ void *lm_addr;
+
+ lm_addr = phys_to_virt(dma_to_phys(dev, dma_addr));
+ if (set_memory_encrypted((unsigned long)lm_addr, PFN_UP(size))) {
+ pr_warn_ratelimited("leaking DMA memory that can't be re-encrypted\n");
return;
+ }
}
__dma_direct_free_pages(dev, dma_direct_to_page(dev, dma_addr), size);
^ permalink raw reply related
* Re: [PATCH v2 5/5] KVM: guest_memfd: GUP source pages prior to populating guest memory
From: Yan Zhao @ 2025-12-26 3:09 UTC (permalink / raw)
To: Michael Roth, kvm, linux-coco, linux-mm, linux-kernel,
thomas.lendacky, pbonzini, seanjc, vbabka, ashish.kalra,
liam.merwick, david, vannapurve, ackerleytng, aik, ira.weiny
In-Reply-To: <aU33Y56qBXgrL5/3@yzhao56-desk.sh.intel.com>
On Fri, Dec 26, 2025 at 10:48:03AM +0800, Yan Zhao wrote:
> > @@ -842,47 +881,38 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long
> > if (!file)
> > return -EFAULT;
> >
> > - filemap_invalidate_lock(file->f_mapping);
> > -
> > npages = min_t(ulong, slot->npages - (start_gfn - slot->base_gfn), npages);
> > for (i = 0; i < npages; i++) {
> > - struct folio *folio;
> > - gfn_t gfn = start_gfn + i;
> > - pgoff_t index = kvm_gmem_get_index(slot, gfn);
> > - kvm_pfn_t pfn;
> > + struct page *src_page = NULL;
> > + void __user *p;
> >
> > if (signal_pending(current)) {
> > ret = -EINTR;
> > break;
> > }
> >
> > - folio = __kvm_gmem_get_pfn(file, slot, index, &pfn, NULL);
> > - if (IS_ERR(folio)) {
> > - ret = PTR_ERR(folio);
> > - break;
> > - }
> > + p = src ? src + i * PAGE_SIZE : NULL;
> >
> > - folio_unlock(folio);
> > + if (p) {
> > + ret = get_user_pages_fast((unsigned long)p, 1, 0, &src_page);
> > + if (ret < 0)
> > + break;
> > + if (ret != 1) {
> Put pages in this case? e.g.,
>
> --- a/virt/kvm/guest_memfd.c
> +++ b/virt/kvm/guest_memfd.c
> @@ -1645,6 +1645,9 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long
> if (ret < 0)
> break;
> if (ret != 1) {
> + while (ret--)
Oops. Need to check if ret == 0, and looks put_page() is not required in this
case given nr_pages == 1.
So, please ignore this comment.
> + put_page(src_page++);
> +
> ret = -ENOMEM;
> break;
> }
>
>
>
>
> > + ret = -ENOMEM;
> > + break;
> > + }
> > + }
> >
> > - ret = -EINVAL;
> > - if (!kvm_range_has_memory_attributes(kvm, gfn, gfn + 1,
> > - KVM_MEMORY_ATTRIBUTE_PRIVATE,
> > - KVM_MEMORY_ATTRIBUTE_PRIVATE))
> > - goto put_folio_and_exit;
> > + ret = __kvm_gmem_populate(kvm, slot, file, start_gfn + i, src_page,
> > + post_populate, opaque);
> >
> > - p = src ? src + i * PAGE_SIZE : NULL;
> > - ret = post_populate(kvm, gfn, pfn, p, opaque);
> > - if (!ret)
> > - folio_mark_uptodate(folio);
> > + if (src_page)
> > + put_page(src_page);
> >
> > -put_folio_and_exit:
> > - folio_put(folio);
> > if (ret)
> > break;
> > }
> >
> > - filemap_invalidate_unlock(file->f_mapping);
> > -
> > return ret && !i ? ret : i;
> > }
> > EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_populate);
> > --
> > 2.25.1
> >
^ permalink raw reply
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