* [PATCH v2 0/2] x86/tdx: Use TDVMCALLs directly for earlyprintk
@ 2026-09-21 19:52 Vishal Verma
2026-09-21 19:52 ` [PATCH v2 1/2] x86/tdx: Move port I/O definitions to a shared header Vishal Verma
2026-09-21 19:52 ` [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs Vishal Verma
0 siblings, 2 replies; 7+ messages in thread
From: Vishal Verma @ 2026-09-21 19:52 UTC (permalink / raw)
To: x86, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Jonathan Corbet, Shuah Khan, Randy Dunlap
Cc: linux-kernel, linux-coco, kvm, linux-doc, Vishal Verma
Background
==========
TDX guests have early_printk support, but it is through a roundabout way
using a #VE exception as a functional mechanism. The exception handler
has to use TDG.VP.VEINFO.GET to find out what faulted, and then issue
the TDVMCALL. Simplify this by using a TDVMCALL from the guest which can
directly perform the port I/O.
Patch details
=============
Patch 1 is a prep patch that moves the port I/O direction constants to
arch/x86/include/asm/shared/tdx.h.
Patch 2: Add a new earlyprintk=tdx option (with sub-options to select
the serial port - same as earlyprintk=serial - tdx[,ttySN[,baud]]).
This calls new tdx_inb() / tdx_outb() helpers, which perform the port
I/O directly using TDVMCALLs.
The serial earlyprintk path is left as is - TD guests using this will
still take a #VE exception, and the exception handler will perform the
I/O.
Testing
=======
Added a counter for the number of COM1 port I/O #VEs handled:
no earlyprintk - ~63000
earlyprintk=ttyS0 - ~61000
earlyprintk=tdx - ~35000
The new tdx option nearly halves the number of #VEs handled.
Additionally, ran the usual suite of CI testing, which covers KVM self
tests, KVM unit tests, and Avocado KVM tests without any regressions.
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
Changes in v2:
- Rebase to v7.3-rc4
- Move the TDX hypercall helpers into coco/tdx/tdx.c (Kiryl)
- Add a new earlyprintk=tdx option that implements the direct TDVMCALL
path (Dave Hansen)
- Link to v1: https://patch.msgid.link/20260910-b4-tdx_earlyprintk_tdcalls-v1-0-4b2b1bf9001b@intel.com
---
Vishal Verma (2):
x86/tdx: Move port I/O definitions to a shared header
x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs
Documentation/admin-guide/kernel-parameters.txt | 9 +++++
arch/x86/include/asm/shared/tdx.h | 6 ++++
arch/x86/include/asm/tdx.h | 3 ++
arch/x86/boot/compressed/tdx.c | 4 +--
arch/x86/coco/tdx/tdx.c | 47 +++++++++++++++++++++----
arch/x86/kernel/early_printk.c | 37 +++++++++++++++++++
6 files changed, 98 insertions(+), 8 deletions(-)
---
base-commit: 93f51579e7df248780214094418f205253383cc5
change-id: 20260903-b4-tdx_earlyprintk_tdcalls-40d1b21a8ba2
Best regards,
--
Vishal Verma <vishal.l.verma@intel.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] x86/tdx: Move port I/O definitions to a shared header
2026-09-21 19:52 [PATCH v2 0/2] x86/tdx: Use TDVMCALLs directly for earlyprintk Vishal Verma
@ 2026-09-21 19:52 ` Vishal Verma
2026-09-21 19:52 ` [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs Vishal Verma
1 sibling, 0 replies; 7+ messages in thread
From: Vishal Verma @ 2026-09-21 19:52 UTC (permalink / raw)
To: x86, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Jonathan Corbet, Shuah Khan, Randy Dunlap
Cc: linux-kernel, linux-coco, kvm, linux-doc, Vishal Verma
In preparation for adding a 'tdx' option for early_printk which uses
direct TDVMCALLs for I/O, factor out the PORT_READ and PORT_WRITE
definitions from arch/x86/coco/tdx/tdx.c into
arch/x86/include/asm/shared/tdx.h, and namespace them with 'TDVMCALL_'.
The decompressor also used 0/1 literals in its tdx_io_{in,out} helpers -
switch those to use the new definitions.
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/include/asm/shared/tdx.h | 6 ++++++
arch/x86/boot/compressed/tdx.c | 4 ++--
arch/x86/coco/tdx/tdx.c | 8 ++------
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index f20e91d7ac35..ecaf965f059b 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -84,6 +84,12 @@
#define TDVMCALL_STATUS_ALIGN_ERROR 0x8000000000000002ULL
#define TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED 0x8000000000000003ULL
+/*
+ * TDG.VP.VMCALL<Instruction.IO> direction (passed in R13)
+ */
+#define TDVMCALL_PORT_READ 0
+#define TDVMCALL_PORT_WRITE 1
+
/*
* Bitmasks of exposed registers (with VMM).
*/
diff --git a/arch/x86/boot/compressed/tdx.c b/arch/x86/boot/compressed/tdx.c
index 8451d6a1030c..ed278bac3c93 100644
--- a/arch/x86/boot/compressed/tdx.c
+++ b/arch/x86/boot/compressed/tdx.c
@@ -22,7 +22,7 @@ static inline unsigned int tdx_io_in(int size, u16 port)
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
.r12 = size,
- .r13 = 0,
+ .r13 = TDVMCALL_PORT_READ,
.r14 = port,
};
@@ -38,7 +38,7 @@ static inline void tdx_io_out(int size, u16 port, u32 value)
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
.r12 = size,
- .r13 = 1,
+ .r13 = TDVMCALL_PORT_WRITE,
.r14 = port,
.r15 = value,
};
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index f904a636d449..7d1a93ee2534 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -24,10 +24,6 @@
#define EPT_READ 0
#define EPT_WRITE 1
-/* Port I/O direction */
-#define PORT_READ 0
-#define PORT_WRITE 1
-
/* See Exit Qualification for I/O Instructions in VMX documentation */
#define VE_IS_IO_IN(e) ((e) & BIT(3))
#define VE_GET_IO_SIZE(e) (((e) & GENMASK(2, 0)) + 1)
@@ -691,7 +687,7 @@ static bool handle_in(struct pt_regs *regs, int size, int port)
.r10 = TDX_HYPERCALL_STANDARD,
.r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
.r12 = size,
- .r13 = PORT_READ,
+ .r13 = TDVMCALL_PORT_READ,
.r14 = port,
};
bool success;
@@ -720,7 +716,7 @@ static bool handle_out(struct pt_regs *regs, int size, int port)
* "TDG.VP.VMCALL<Instruction.IO>".
*/
return !_tdx_hypercall(hcall_func(EXIT_REASON_IO_INSTRUCTION), size,
- PORT_WRITE, port, regs->ax & mask);
+ TDVMCALL_PORT_WRITE, port, regs->ax & mask);
}
/*
--
2.55.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs
2026-09-21 19:52 [PATCH v2 0/2] x86/tdx: Use TDVMCALLs directly for earlyprintk Vishal Verma
2026-09-21 19:52 ` [PATCH v2 1/2] x86/tdx: Move port I/O definitions to a shared header Vishal Verma
@ 2026-09-21 19:52 ` Vishal Verma
2026-09-21 19:58 ` Dave Hansen
1 sibling, 1 reply; 7+ messages in thread
From: Vishal Verma @ 2026-09-21 19:52 UTC (permalink / raw)
To: x86, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Jonathan Corbet, Shuah Khan, Randy Dunlap
Cc: linux-kernel, linux-coco, kvm, linux-doc, Vishal Verma
A TDX guest cannot execute port I/O instructions directly, but
earlyprintk's serial console still issues plain inb()/outb() and lets
each one fault into the #VE handler to be emulated as a TDVMCALL.
While that works, it is a roundabout way to get a character out.
early_serial_putc() polls the LSR, and then writes a byte, but since the
TDX guest can't directly do port I/O, a #VE exception is raised. The #VE
handler must call TDG.VP.VEINFO.GET to find out what faulted, and then
it can issue the TDVMCALL that does the actual work.
This makes #VE a functional mechanism for doing I/O, which is not
desirable, is unnecessarily complicated and fragile, and results in
twice the number of calls into the TDX module.
Instead, add an earlyprintk=tdx option, which can issue the TDVMCALLs
directly. Add a pair of tdx_serial_in() and tdx_serial_out() accessors
and set them up in this case.
Note that the output does not appear any earlier - "earlyprintk=" is an
early_param(), so the console is still registered from
parse_early_param(). This only changes how the bytes leave the guest
once it is up.
LLMs were used under supervision to create this patch, to help
understand the scope and mechanisms, create testing instrumentation
(throwaway) to count #VEs in the serial vs tdx earlyprintk setups,
and to drive lab machines to do this testing.
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
Documentation/admin-guide/kernel-parameters.txt | 9 ++++++
arch/x86/include/asm/tdx.h | 3 ++
arch/x86/coco/tdx/tdx.c | 39 +++++++++++++++++++++++++
arch/x86/kernel/early_printk.c | 37 +++++++++++++++++++++++
4 files changed, 88 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 33cd30996e47..263a806afd2a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1543,6 +1543,7 @@ Kernel parameters
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=serial[,0x...[,baudrate]]
earlyprintk=ttySn[,baudrate]
+ earlyprintk=tdx[,ttySn[,baudrate]]
earlyprintk=dbgp[debugController#]
earlyprintk=mmio32,membase[,{nocfg|baudrate}]
earlyprintk=pciserial[,force],bus:device.function[,{nocfg|baudrate}]
@@ -1556,6 +1557,14 @@ Kernel parameters
Use "nocfg" to skip UART configuration, assume
BIOS/firmware has configured UART correctly.
+ On x86, "tdx" is equivalent to "serial", except that
+ in a TDX guest the serial port is driven with
+ TDVMCALLs rather than port I/O instructions, avoiding
+ the #VE exception that would otherwise be taken to
+ emulate every access. Outside a TDX guest it falls
+ back to port I/O and behaves exactly like "serial".
+ If CONFIG_INTEL_TDX_GUEST is not set, it is ignored.
+
Append ",keep" to not disable it when the real console
takes over.
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 89e97d5761d8..325dd7c5929f 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -83,6 +83,9 @@ int tdx_mcall_extend_rtmr(u8 index, u8 *data);
u64 tdx_hcall_get_quote(u8 *buf, size_t size);
+u8 tdx_inb(u16 port);
+void tdx_outb(u8 value, u16 port);
+
void __init tdx_dump_attributes(u64 td_attr);
void __init tdx_dump_td_ctls(u64 td_ctls);
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 7d1a93ee2534..4377fcca2c99 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -194,6 +194,45 @@ u64 tdx_hcall_get_quote(u8 *buf, size_t size)
}
EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
+/**
+ * tdx_inb() - Read a byte from an I/O port without a #VE
+ * @port: I/O port to read from
+ *
+ * Ask the VMM to perform the read with TDG.VP.VMCALL<Instruction.IO>, rather
+ * than executing an IN instruction and having the resulting #VE emulate it.
+ *
+ * Return: the byte read, or 0xff if the hypercall failed.
+ */
+u8 tdx_inb(u16 port)
+{
+ struct tdx_module_args args = {
+ .r10 = TDX_HYPERCALL_STANDARD,
+ .r11 = hcall_func(EXIT_REASON_IO_INSTRUCTION),
+ .r12 = 1,
+ .r13 = TDVMCALL_PORT_READ,
+ .r14 = port,
+ };
+
+ if (__tdx_hypercall(&args))
+ return 0xff;
+
+ return args.r11;
+}
+
+/**
+ * tdx_outb() - Write a byte to an I/O port without a #VE
+ * @value: byte to write
+ * @port: I/O port to write to
+ *
+ * Ask the VMM to perform the write with TDG.VP.VMCALL<Instruction.IO>, rather
+ * than executing an OUT instruction and having the resulting #VE emulate it.
+ */
+void tdx_outb(u8 value, u16 port)
+{
+ _tdx_hypercall(hcall_func(EXIT_REASON_IO_INSTRUCTION), 1,
+ TDVMCALL_PORT_WRITE, port, value);
+}
+
static void __noreturn tdx_panic(const char *msg)
{
struct tdx_module_args args = {
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index cba75306e5b6..2721e48783cd 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -21,6 +21,7 @@
#include <linux/usb/xhci-dbgp.h>
#include <asm/pci_x86.h>
#include <linux/static_call.h>
+#include <asm/tdx.h>
/* Simple VGA output */
#define VGABASE (__ISA_IO_base + 0xb8000)
@@ -111,6 +112,32 @@ ANNOTATE_NOENDBR_SYM(io_serial_out);
DEFINE_STATIC_CALL(serial_in, io_serial_in);
DEFINE_STATIC_CALL(serial_out, io_serial_out);
+#ifdef CONFIG_INTEL_TDX_GUEST
+/*
+ * A TDX guest cannot execute port I/O instructions, so ask the VMM to do it.
+ */
+static __noendbr unsigned int tdx_serial_in(unsigned long addr, int offset)
+{
+ return tdx_inb(addr + offset);
+}
+ANNOTATE_NOENDBR_SYM(tdx_serial_in);
+
+static __noendbr void tdx_serial_out(unsigned long addr, int offset, int value)
+{
+ tdx_outb(value, addr + offset);
+}
+ANNOTATE_NOENDBR_SYM(tdx_serial_out);
+
+static __init void early_serial_tdx_init(void)
+{
+ if (!cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+ return;
+
+ static_call_update(serial_in, tdx_serial_in);
+ static_call_update(serial_out, tdx_serial_out);
+}
+#endif /* CONFIG_INTEL_TDX_GUEST */
+
static int early_serial_putc(unsigned char ch)
{
unsigned timeout = 0xffff;
@@ -414,6 +441,16 @@ static int __init setup_early_printk(char *buf)
early_serial_init(buf + 4);
early_console_register(&early_serial_console, keep);
}
+#ifdef CONFIG_INTEL_TDX_GUEST
+ if (!strncmp(buf, "tdx", 3)) {
+ buf += 3;
+ early_serial_tdx_init();
+ early_serial_init(buf);
+ early_console_register(&early_serial_console, keep);
+ if (!strncmp(buf, ",ttyS", 5))
+ buf += 5;
+ }
+#endif
#ifdef CONFIG_PCI
if (!strncmp(buf, "pciserial", 9)) {
buf += 9; /* Keep from match the above "pciserial" */
--
2.55.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs
2026-09-21 19:52 ` [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs Vishal Verma
@ 2026-09-21 19:58 ` Dave Hansen
2026-09-21 20:11 ` Verma, Vishal L
0 siblings, 1 reply; 7+ messages in thread
From: Dave Hansen @ 2026-09-21 19:58 UTC (permalink / raw)
To: Vishal Verma, x86, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Jonathan Corbet, Shuah Khan, Randy Dunlap
Cc: linux-kernel, linux-coco, kvm, linux-doc
On 9/21/26 12:52, Vishal Verma wrote:
> + earlyprintk=tdx[,ttySn[,baudrate]]
Isn't keeping support for ttySn and baudrate kinda silly? It costs a few
lines of code at least.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs
2026-09-21 19:58 ` Dave Hansen
@ 2026-09-21 20:11 ` Verma, Vishal L
2026-09-22 18:18 ` Verma, Vishal L
0 siblings, 1 reply; 7+ messages in thread
From: Verma, Vishal L @ 2026-09-21 20:11 UTC (permalink / raw)
To: rdunlap, corbet, Hansen, Dave, dave.hansen, kas, x86, Edgecombe,
Rick P, skhan
Cc: kvm, linux-coco, linux-doc, linux-kernel
On Mon, 2026-09-21 at 12:58 -0700, Dave Hansen wrote:
> On 9/21/26 12:52, Vishal Verma wrote:
> > + earlyprintk=tdx[,ttySn[,baudrate]]
>
> Isn't keeping support for ttySn and baudrate kinda silly? It costs a few
> lines of code at least.
I kept it because ultimately we call early_serial_init() to set the
'serial port' up - mainly select which address we want to use. The baud
rate parsing tags along because that's just how the helper is set up.
I think ttySN parsing can still be useful? The guest could be set up
with multiple serial devices and someone could choose to redirect
earlyprintk output to say ttyS1, and that would work.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs
2026-09-21 20:11 ` Verma, Vishal L
@ 2026-09-22 18:18 ` Verma, Vishal L
2026-09-22 18:24 ` Dave Hansen
0 siblings, 1 reply; 7+ messages in thread
From: Verma, Vishal L @ 2026-09-22 18:18 UTC (permalink / raw)
To: rdunlap, corbet, Hansen, Dave, x86, kas, dave.hansen, Edgecombe,
Rick P, skhan
Cc: kvm, linux-coco, linux-doc, linux-kernel
On Mon, 2026-09-21 at 20:11 +0000, Verma, Vishal L wrote:
> On Mon, 2026-09-21 at 12:58 -0700, Dave Hansen wrote:
> > On 9/21/26 12:52, Vishal Verma wrote:
> > > + earlyprintk=tdx[,ttySn[,baudrate]]
> >
> > Isn't keeping support for ttySn and baudrate kinda silly? It costs a few
> > lines of code at least.
>
> I kept it because ultimately we call early_serial_init() to set the
> 'serial port' up - mainly select which address we want to use. The baud
> rate parsing tags along because that's just how the helper is set up.
>
> I think ttySN parsing can still be useful? The guest could be set up
> with multiple serial devices and someone could choose to redirect
> earlyprintk output to say ttyS1, and that would work.
Hi Dave,
As a thought exercise, I changed this to just use ttyS0 which is the
defined default, and that changes the setup hunks to look like below
(not thoroughly tested or anything yet). Would you prefer this instead?
---
@@ -196,6 +215,24 @@ static __init void early_serial_init(char *s)
early_serial_hw_init(divisor);
}
+#ifdef CONFIG_INTEL_TDX_GUEST
+/*
+ * "earlyprintk=tdx" takes no options. A TDX guest has no firmware tables to
+ * discover a UART from and the VMM presents COM1, so there is nothing for a
+ * port or a baud rate argument to usefully select. Leave early_serial_base at
+ * its default and use the same rate "earlyprintk=serial" would pick.
+ */
+static __init void early_serial_tdx_init(void)
+{
+ if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
+ static_call_update(serial_in, tdx_serial_in);
+ static_call_update(serial_out, tdx_serial_out);
+ }
+
+ early_serial_hw_init(BASE_BAUD / DEFAULT_BAUD);
+}
+#endif /* CONFIG_INTEL_TDX_GUEST */
+
static __noendbr void mem32_serial_out(unsigned long addr, int offset, int value)
{
u32 __iomem *vaddr = (u32 __iomem *)addr;
@@ -414,6 +451,13 @@ static int __init setup_early_printk(char *buf)
early_serial_init(buf + 4);
early_console_register(&early_serial_console, keep);
}
+#ifdef CONFIG_INTEL_TDX_GUEST
+ if (!strncmp(buf, "tdx", 3)) {
+ early_serial_tdx_init();
+ early_console_register(&early_serial_console, keep);
+ break;
+ }
+#endif
#ifdef CONFIG_PCI
if (!strncmp(buf, "pciserial", 9)) {
buf += 9; /* Keep from match the above "pciserial" */
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs
2026-09-22 18:18 ` Verma, Vishal L
@ 2026-09-22 18:24 ` Dave Hansen
0 siblings, 0 replies; 7+ messages in thread
From: Dave Hansen @ 2026-09-22 18:24 UTC (permalink / raw)
To: Verma, Vishal L, rdunlap, corbet, x86, kas, dave.hansen,
Edgecombe, Rick P, skhan
Cc: kvm, linux-coco, linux-doc, linux-kernel
On 9/22/26 11:18, Verma, Vishal L wrote:
> As a thought exercise, I changed this to just use ttyS0 which is the
> defined default, and that changes the setup hunks to look like below
> (not thoroughly tested or anything yet). Would you prefer this instead?
That looks fine to me.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-22 18:24 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 19:52 [PATCH v2 0/2] x86/tdx: Use TDVMCALLs directly for earlyprintk Vishal Verma
2026-09-21 19:52 ` [PATCH v2 1/2] x86/tdx: Move port I/O definitions to a shared header Vishal Verma
2026-09-21 19:52 ` [PATCH v2 2/2] x86/early_printk: Add earlyprintk=tdx to drive the UART with TDVMCALLs Vishal Verma
2026-09-21 19:58 ` Dave Hansen
2026-09-21 20:11 ` Verma, Vishal L
2026-09-22 18:18 ` Verma, Vishal L
2026-09-22 18:24 ` Dave Hansen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®