Re: [PATCH v2 2/5] KVM: SVM: Always intercept RDMSR for TMCCT (current APIC timer count)

From: Sean Christopherson

Date: Fri May 08 2026 - 12:56:37 EST


On Fri, May 08, 2026, Naveen N Rao wrote:
> On Thu, May 07, 2026 at 11:26:15AM -0700, Sean Christopherson wrote:
> > The only reg that's at all hot is Timer Initial Count Register, and (a) it's a
> > moot point with TSC Deadline mode, and (b) the cost to program hrtimers is so high
> > than shaving ~10 cycles is completely meaningless.
>
> Thanks for the checking this - this was something I wanted to check. And
> I agree with your assessment. None of those registers look to be
> commonly written to, and ~10 cycles is almost in the noise. If we ever
> come across a performance issue, it should be fairly simple to pass
> additional registers through (with good reason, of course).
>
> On a side note, how did you measure this? My naive attempt showed a lot
> of variation between runs.

I hacked the x86/vmexit.c test in KUT, and then ran it with and without x2APIC:

./x86/run x86/vmexit.flat -smp 2 -cpu qemu64,+x2apic -append apic_wr_lvt0
./x86/run x86/vmexit.flat -smp 2 -cpu qemu64,-x2apic -append apic_wr_lvt0

That test super useful for micro-benchmarking single instructions and/or short
sequences. Even without pinning vCPUs, it does a decent job of generating stable
results.

diff --git a/x86/vmexit.c b/x86/vmexit.c
index 5296ed38..1749cbd8 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -22,6 +22,7 @@ struct test {

static int nr_cpus;
static u64 cr4_shadow;
+static u32 lvt0;

static void cpuid_test(void)
{
@@ -447,6 +448,11 @@ static void tscdeadline(void)
while (x == 0) barrier();
}

+static void apic_wr_lvt0(void)
+{
+ apic_write(APIC_LVT0, lvt0);
+}
+
static void wr_tsx_ctrl_msr(void)
{
wrmsr(MSR_IA32_TSX_CTRL, 0);
@@ -501,6 +507,7 @@ static struct test tests[] = {
{ mov_from_cr8, "mov_from_cr8", .parallel = 1, },
{ mov_to_cr8, "mov_to_cr8" , .parallel = 1, },
#endif
+ { apic_wr_lvt0, "apic_wr_lvt0", .parallel = 1, },
{ inl_pmtimer, "inl_from_pmtimer", .parallel = 1, },
{ inl_nop_qemu, "inl_from_qemu", .parallel = 1 },
{ inl_nop_kernel, "inl_from_kernel", .parallel = 1 },
@@ -618,6 +625,7 @@ int main(int ac, char **av)

setup_vm();
cr4_shadow = read_cr4();
+ lvt0 = apic_read(APIC_LVT0);
handle_irq(IPI_TEST_VECTOR, self_ipi_isr);
nr_cpus = cpu_count();