2024-04-29 15:59:03

by Alejandro Jimenez

[permalink] [raw]
Subject: [PATCH 4/4] KVM: x86: Add vCPU stat for APICv interrupt injections causing #VMEXIT

Even when APICv/AVIC is active, certain guest accesses to its local APIC(s)
cannot be fully accelerated, and cause a #VMEXIT to allow the VMM to
emulate the behavior and side effects. Expose a counter stat for these
specific #VMEXIT types.

Suggested-by: Paolo Bonzini <[email protected]>
Signed-off-by: Alejandro Jimenez <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm/avic.c | 7 +++++++
arch/x86/kvm/vmx/vmx.c | 2 ++
arch/x86/kvm/x86.c | 1 +
4 files changed, 11 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index e7e3213cefae..388979dfe9f3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1576,6 +1576,7 @@ struct kvm_vcpu_stat {
u64 guest_mode;
u64 notify_window_exits;
u64 apicv_active;
+ u64 apicv_unaccelerated_inj;
};

struct x86_instruction_info;
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 4b74ea91f4e6..274041d3cf66 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -517,6 +517,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
kvm_apic_write_nodecode(vcpu, APIC_ICR);
else
kvm_apic_send_ipi(apic, icrl, icrh);
+
+ ++vcpu->stat.apicv_unaccelerated_inj;
break;
case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING:
/*
@@ -525,6 +527,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
* vcpus. So, we just need to kick the appropriate vcpu.
*/
avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh, index);
+
+ ++vcpu->stat.apicv_unaccelerated_inj;
break;
case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
WARN_ONCE(1, "Invalid backing page\n");
@@ -704,6 +708,9 @@ int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu)

trace_kvm_avic_unaccelerated_access(vcpu->vcpu_id, offset,
trap, write, vector);
+
+ ++vcpu->stat.apicv_unaccelerated_inj;
+
if (trap) {
/* Handling Trap */
WARN_ONCE(!write, "svm: Handling trap read.\n");
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index f10b5f8f364b..a7487f12ded1 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -5657,6 +5657,8 @@ static int handle_apic_write(struct kvm_vcpu *vcpu)
{
unsigned long exit_qualification = vmx_get_exit_qual(vcpu);

+ ++vcpu->stat.apicv_unaccelerated_inj;
+
/*
* APIC-write VM-Exit is trap-like, KVM doesn't need to advance RIP and
* hardware has done any necessary aliasing, offset adjustments, etc...
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 03cb933920cb..c8730b0fac87 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -307,6 +307,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
STATS_DESC_IBOOLEAN(VCPU, guest_mode),
STATS_DESC_COUNTER(VCPU, notify_window_exits),
STATS_DESC_IBOOLEAN(VCPU, apicv_active),
+ STATS_DESC_COUNTER(VCPU, apicv_unaccelerated_inj),
};

const struct kvm_stats_header kvm_vcpu_stats_header = {
--
2.39.3



2024-05-31 09:33:24

by Vasant Hegde

[permalink] [raw]
Subject: Re: [PATCH 4/4] KVM: x86: Add vCPU stat for APICv interrupt injections causing #VMEXIT

Hi Alejandro,


On 4/29/2024 9:27 PM, Alejandro Jimenez wrote:
> Even when APICv/AVIC is active, certain guest accesses to its local APIC(s)
> cannot be fully accelerated, and cause a #VMEXIT to allow the VMM to
> emulate the behavior and side effects. Expose a counter stat for these
> specific #VMEXIT types.
>
> Suggested-by: Paolo Bonzini <[email protected]>
> Signed-off-by: Alejandro Jimenez <[email protected]>

Reviewed-by: Vasant Hegde <[email protected]> # AMD

-Vasant

> ---
> arch/x86/include/asm/kvm_host.h | 1 +
> arch/x86/kvm/svm/avic.c | 7 +++++++
> arch/x86/kvm/vmx/vmx.c | 2 ++
> arch/x86/kvm/x86.c | 1 +
> 4 files changed, 11 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index e7e3213cefae..388979dfe9f3 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1576,6 +1576,7 @@ struct kvm_vcpu_stat {
> u64 guest_mode;
> u64 notify_window_exits;
> u64 apicv_active;
> + u64 apicv_unaccelerated_inj;
> };
>
> struct x86_instruction_info;
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 4b74ea91f4e6..274041d3cf66 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -517,6 +517,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
> kvm_apic_write_nodecode(vcpu, APIC_ICR);
> else
> kvm_apic_send_ipi(apic, icrl, icrh);
> +
> + ++vcpu->stat.apicv_unaccelerated_inj;
> break;
> case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING:
> /*
> @@ -525,6 +527,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
> * vcpus. So, we just need to kick the appropriate vcpu.
> */
> avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh, index);
> +
> + ++vcpu->stat.apicv_unaccelerated_inj;
> break;
> case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
> WARN_ONCE(1, "Invalid backing page\n");
> @@ -704,6 +708,9 @@ int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu)
>
> trace_kvm_avic_unaccelerated_access(vcpu->vcpu_id, offset,
> trap, write, vector);
> +
> + ++vcpu->stat.apicv_unaccelerated_inj;
> +
> if (trap) {
> /* Handling Trap */
> WARN_ONCE(!write, "svm: Handling trap read.\n");
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index f10b5f8f364b..a7487f12ded1 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -5657,6 +5657,8 @@ static int handle_apic_write(struct kvm_vcpu *vcpu)
> {
> unsigned long exit_qualification = vmx_get_exit_qual(vcpu);
>
> + ++vcpu->stat.apicv_unaccelerated_inj;
> +
> /*
> * APIC-write VM-Exit is trap-like, KVM doesn't need to advance RIP and
> * hardware has done any necessary aliasing, offset adjustments, etc...
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 03cb933920cb..c8730b0fac87 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -307,6 +307,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
> STATS_DESC_IBOOLEAN(VCPU, guest_mode),
> STATS_DESC_COUNTER(VCPU, notify_window_exits),
> STATS_DESC_IBOOLEAN(VCPU, apicv_active),
> + STATS_DESC_COUNTER(VCPU, apicv_unaccelerated_inj),
> };
>
> const struct kvm_stats_header kvm_vcpu_stats_header = {

2024-06-04 00:14:28

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH 4/4] KVM: x86: Add vCPU stat for APICv interrupt injections causing #VMEXIT

On Mon, Apr 29, 2024, Alejandro Jimenez wrote:
> Even when APICv/AVIC is active, certain guest accesses to its local APIC(s)
> cannot be fully accelerated, and cause a #VMEXIT to allow the VMM to
> emulate the behavior and side effects. Expose a counter stat for these
> specific #VMEXIT types.
>
> Suggested-by: Paolo Bonzini <[email protected]>
> Signed-off-by: Alejandro Jimenez <[email protected]>
> ---
> arch/x86/include/asm/kvm_host.h | 1 +
> arch/x86/kvm/svm/avic.c | 7 +++++++
> arch/x86/kvm/vmx/vmx.c | 2 ++
> arch/x86/kvm/x86.c | 1 +
> 4 files changed, 11 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index e7e3213cefae..388979dfe9f3 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1576,6 +1576,7 @@ struct kvm_vcpu_stat {
> u64 guest_mode;
> u64 notify_window_exits;
> u64 apicv_active;
> + u64 apicv_unaccelerated_inj;

The stat name doesn't match the changelog or the code. The AVIC updates in
avic_incomplete_ipi_interception() are unaccelerated _injection_, they're
unaccelarated _delivery_. And in those cases, the fact that delivery wasn't
accelerated is relatively uninteresting in most cases.

And avic_unaccelerated_access_interception() and handle_apic_write() don't
necessarily have anything to do with injection.

On the flip side, the slow paths for {svm,vmx}_deliver_interrupt() are very
explicitly unnaccelerated injection.

It's not entirely clear from the changelog what the end goal of this stat is.
A singular stat for all APICv/AVIC access VM-Exits seems uninteresting, as such
a stat essentially just captures that the guest is active. Maaaybe someone could
glean info from comparing two VMs, but even that is dubious. E.g. if a guest is
doing something function and generating a lot of avic_incomplete_ipi_interception()
exits, those will likely be in the noise due to the total volume of other AVIC
exits.

> };
>
> struct x86_instruction_info;
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 4b74ea91f4e6..274041d3cf66 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -517,6 +517,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
> kvm_apic_write_nodecode(vcpu, APIC_ICR);
> else
> kvm_apic_send_ipi(apic, icrl, icrh);
> +
> + ++vcpu->stat.apicv_unaccelerated_inj;
> break;
> case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING:
> /*
> @@ -525,6 +527,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
> * vcpus. So, we just need to kick the appropriate vcpu.
> */
> avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh, index);
> +
> + ++vcpu->stat.apicv_unaccelerated_inj;
> break;
> case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
> WARN_ONCE(1, "Invalid backing page\n");
> @@ -704,6 +708,9 @@ int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu)
>
> trace_kvm_avic_unaccelerated_access(vcpu->vcpu_id, offset,
> trap, write, vector);
> +
> + ++vcpu->stat.apicv_unaccelerated_inj;
> +
> if (trap) {
> /* Handling Trap */
> WARN_ONCE(!write, "svm: Handling trap read.\n");
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index f10b5f8f364b..a7487f12ded1 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -5657,6 +5657,8 @@ static int handle_apic_write(struct kvm_vcpu *vcpu)
> {
> unsigned long exit_qualification = vmx_get_exit_qual(vcpu);
>
> + ++vcpu->stat.apicv_unaccelerated_inj;
> +
> /*
> * APIC-write VM-Exit is trap-like, KVM doesn't need to advance RIP and
> * hardware has done any necessary aliasing, offset adjustments, etc...
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 03cb933920cb..c8730b0fac87 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -307,6 +307,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
> STATS_DESC_IBOOLEAN(VCPU, guest_mode),
> STATS_DESC_COUNTER(VCPU, notify_window_exits),
> STATS_DESC_IBOOLEAN(VCPU, apicv_active),
> + STATS_DESC_COUNTER(VCPU, apicv_unaccelerated_inj),
> };
>
> const struct kvm_stats_header kvm_vcpu_stats_header = {
> --
> 2.39.3
>

2024-06-06 21:10:01

by Alejandro Jimenez

[permalink] [raw]
Subject: Re: [PATCH 4/4] KVM: x86: Add vCPU stat for APICv interrupt injections causing #VMEXIT



On 6/3/24 20:14, Sean Christopherson wrote:
> On Mon, Apr 29, 2024, Alejandro Jimenez wrote:
>> Even when APICv/AVIC is active, certain guest accesses to its local APIC(s)
>> cannot be fully accelerated, and cause a #VMEXIT to allow the VMM to
>> emulate the behavior and side effects. Expose a counter stat for these
>> specific #VMEXIT types.
>>
>> Suggested-by: Paolo Bonzini <[email protected]>
>> Signed-off-by: Alejandro Jimenez <[email protected]>
>> ---
>> arch/x86/include/asm/kvm_host.h | 1 +
>> arch/x86/kvm/svm/avic.c | 7 +++++++
>> arch/x86/kvm/vmx/vmx.c | 2 ++
>> arch/x86/kvm/x86.c | 1 +
>> 4 files changed, 11 insertions(+)
>>
>> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
>> index e7e3213cefae..388979dfe9f3 100644
>> --- a/arch/x86/include/asm/kvm_host.h
>> +++ b/arch/x86/include/asm/kvm_host.h
>> @@ -1576,6 +1576,7 @@ struct kvm_vcpu_stat {
>> u64 guest_mode;
>> u64 notify_window_exits;
>> u64 apicv_active;
>> + u64 apicv_unaccelerated_inj;
>
> The stat name doesn't match the changelog or the code. The AVIC updates in
> avic_incomplete_ipi_interception() are unaccelerated _injection_, they're
> unaccelarated _delivery_. And in those cases, the fact that delivery wasn't
> accelerated is relatively uninteresting in most cases.
>

Yeah, this was my flawed attempt to interpret/implement Paolo's comment in the RFC thread:

"... for example I'd add an interrupt_injections stat for unaccelerated injections causing a vmexit or otherwise hitting lapic.c"

so I incorrectly bundled together APIC accesses that result in #VMEXIT and end up requiring additional emulation (while managing to miss the handle_apic_access() case).


> And avic_unaccelerated_access_interception() and handle_apic_write() don't
> necessarily have anything to do with injection.

apicv_unaccelerated_acccess is perhaps a better name (assuming stat is updated in handle_apic_access() as well)?

>
> On the flip side, the slow paths for {svm,vmx}_deliver_interrupt() are very
> explicitly unnaccelerated injection.

Now that you highlight this, I think it might be closer to Paolo's idea. i.e. a stat for the slow path on these can be contrasted/compared with the kvm_apicv_accept_irq tracepoint that is hit on the fast path.
My initial reaction would be to update a stat for the fast path, as a confirmation that apicv is active which is how/why I typically use the kvm_apicv_accept_irq tracepoint, but that becomes redundant by having the apicv_active stat on PATCH 1.

So, if you don't think it is useful to have a general apicv_unaccelerated_acccess counter, I can drop this patch.

Thank you,

Alejandro

>
> It's not entirely clear from the changelog what the end goal of this stat is.
> A singular stat for all APICv/AVIC access VM-Exits seems uninteresting, as such
> a stat essentially just captures that the guest is active. Maaaybe someone could
> glean info from comparing two VMs, but even that is dubious. E.g. if a guest is
> doing something function and generating a lot of avic_incomplete_ipi_interception()
> exits, those will likely be in the noise due to the total volume of other AVIC
> exits.
>
>> };
>>
>> struct x86_instruction_info;
>> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
>> index 4b74ea91f4e6..274041d3cf66 100644
>> --- a/arch/x86/kvm/svm/avic.c
>> +++ b/arch/x86/kvm/svm/avic.c
>> @@ -517,6 +517,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
>> kvm_apic_write_nodecode(vcpu, APIC_ICR);
>> else
>> kvm_apic_send_ipi(apic, icrl, icrh);
>> +
>> + ++vcpu->stat.apicv_unaccelerated_inj;
>> break;
>> case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING:
>> /*
>> @@ -525,6 +527,8 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
>> * vcpus. So, we just need to kick the appropriate vcpu.
>> */
>> avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh, index);
>> +
>> + ++vcpu->stat.apicv_unaccelerated_inj;
>> break;
>> case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
>> WARN_ONCE(1, "Invalid backing page\n");
>> @@ -704,6 +708,9 @@ int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu)
>>
>> trace_kvm_avic_unaccelerated_access(vcpu->vcpu_id, offset,
>> trap, write, vector);
>> +
>> + ++vcpu->stat.apicv_unaccelerated_inj;
>> +
>> if (trap) {
>> /* Handling Trap */
>> WARN_ONCE(!write, "svm: Handling trap read.\n");
>> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
>> index f10b5f8f364b..a7487f12ded1 100644
>> --- a/arch/x86/kvm/vmx/vmx.c
>> +++ b/arch/x86/kvm/vmx/vmx.c
>> @@ -5657,6 +5657,8 @@ static int handle_apic_write(struct kvm_vcpu *vcpu)
>> {
>> unsigned long exit_qualification = vmx_get_exit_qual(vcpu);
>>
>> + ++vcpu->stat.apicv_unaccelerated_inj;
>> +
>> /*
>> * APIC-write VM-Exit is trap-like, KVM doesn't need to advance RIP and
>> * hardware has done any necessary aliasing, offset adjustments, etc...
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 03cb933920cb..c8730b0fac87 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -307,6 +307,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
>> STATS_DESC_IBOOLEAN(VCPU, guest_mode),
>> STATS_DESC_COUNTER(VCPU, notify_window_exits),
>> STATS_DESC_IBOOLEAN(VCPU, apicv_active),
>> + STATS_DESC_COUNTER(VCPU, apicv_unaccelerated_inj),
>> };
>>
>> const struct kvm_stats_header kvm_vcpu_stats_header = {
>> --
>> 2.39.3
>>

2024-06-07 15:11:42

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH 4/4] KVM: x86: Add vCPU stat for APICv interrupt injections causing #VMEXIT

On Thu, Jun 06, 2024, Alejandro Jimenez wrote:
> On 6/3/24 20:14, Sean Christopherson wrote:
> > On Mon, Apr 29, 2024, Alejandro Jimenez wrote:
> > > Even when APICv/AVIC is active, certain guest accesses to its local APIC(s)
> > > cannot be fully accelerated, and cause a #VMEXIT to allow the VMM to
> > > emulate the behavior and side effects. Expose a counter stat for these
> > > specific #VMEXIT types.
> > >
> > > Suggested-by: Paolo Bonzini <[email protected]>
> > > Signed-off-by: Alejandro Jimenez <[email protected]>
> > > ---
> > > arch/x86/include/asm/kvm_host.h | 1 +
> > > arch/x86/kvm/svm/avic.c | 7 +++++++
> > > arch/x86/kvm/vmx/vmx.c | 2 ++
> > > arch/x86/kvm/x86.c | 1 +
> > > 4 files changed, 11 insertions(+)
> > >
> > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> > > index e7e3213cefae..388979dfe9f3 100644
> > > --- a/arch/x86/include/asm/kvm_host.h
> > > +++ b/arch/x86/include/asm/kvm_host.h
> > > @@ -1576,6 +1576,7 @@ struct kvm_vcpu_stat {
> > > u64 guest_mode;
> > > u64 notify_window_exits;
> > > u64 apicv_active;
> > > + u64 apicv_unaccelerated_inj;
> >
> > The stat name doesn't match the changelog or the code. The AVIC updates in
> > avic_incomplete_ipi_interception() are unaccelerated _injection_, they're
> > unaccelarated _delivery_. And in those cases, the fact that delivery wasn't
> > accelerated is relatively uninteresting in most cases.
> >
>
> Yeah, this was my flawed attempt to interpret/implement Paolo's comment in
> the RFC thread:
>
> "... for example I'd add an interrupt_injections stat for unaccelerated
> injections causing a vmexit or otherwise hitting lapic.c"

KVM essentially already has this stat, irq_injections. Sort of. The problem is
that the stat isn't bumped when APICv is enabled because the IRQ isn't *directly*
injected. KVM does "inject" the IRQ into the IRR (and RVI on Intel), but KVM
doesn't go through .inject_irq().

For APICv, KVM could bump the stat when manually moving the IRQ from the IRR to
RVI, but that'd be more than a bit misleading with respect to AVIC. With AVIC,
the CPU itself processes the IRR on VMRUN, i.e. there's no software intervention
needed to get the CPU to inject the IRQ. But practically speaking, there's no
meaningful difference between the two flows; in both cases an IRQ arrived while
the target vCPU wasn't actively running the guest. And that means KVM would need
to parse the IRR on AMD just to bump a stat.

It'd also be misleading to some extent in general, because when the target vCPU
is in its inner run loop, but not actually post-VM-Enter, KVM doesn't kick the
vCPU because either KVM or the CPU will automatically process the pending IRQ.
I.e. KVM would bump the stat cases where the injection isn't fully accelerated,
but that's somewhat disingenuous because KVM didn't need to slow down the vCPU
in order to deliver the interrupt.

And KVM already has an irq_exits stat, which can be used to get a rough feel for
how often KVM is kicking a vCPU (though timer ticks likely dominate the stat).

> > And avic_unaccelerated_access_interception() and handle_apic_write() don't
> > necessarily have anything to do with injection.
>
> apicv_unaccelerated_acccess is perhaps a better name (assuming stat is
> updated in handle_apic_access() as well)?

This is again not super interesting. If we were to add this stat, I would lobby
hard for turning "exits" into an array that accounts each individual VM-Exit,
though with some massaging to reconcile differences between VMX and SVM.

Unaccelerated APIC exits aren't completely uninteresting, but they suffer similar
issues to the "exits" stat: a few flavors of APIC exits would dominate the stats,
and _those_ exits aren't very interesting.

> > On the flip side, the slow paths for {svm,vmx}_deliver_interrupt() are very
> > explicitly unnaccelerated injection.
>
> Now that you highlight this, I think it might be closer to Paolo's idea. i.e.
> a stat for the slow path on these can be contrasted/compared with the
> kvm_apicv_accept_irq tracepoint that is hit on the fast path. My initial
> reaction would be to update a stat for the fast path, as a confirmation that
> apicv is active which is how/why I typically use the kvm_apicv_accept_irq
> tracepoint, but that becomes redundant by having the apicv_active stat on
> PATCH 1.
>
> So, if you don't think it is useful to have a general
> apicv_unaccelerated_acccess counter, I can drop this patch.

The one thing I can think of that might be somewhat interesting is when
kvm_apic_send_ipi() is invoked to deliver an IPI. If KVM manually sends the IPI,
and IPI virtualization is enabled (on-by-default in AVIC, and an add-on feature
for APICv), then it means IPI virtualization isn't doing it's job for whatever
reason. But even then, I'm doubt it's worth a stat, because it likely just means
the guest is doing something weird, not that there's a problem in KVM.