* [PATCH v5 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
@ 2025-11-18 10:37 ` Fuad Tabba
2025-11-18 10:37 ` [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
` (8 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:37 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
For protected VMs in pKVM, the hypervisor should trap accesses to trace
buffer system registers if Trace Buffer isn't supported by the VM.
However, the current code only traps if Trace Buffer External Mode isn't
supported.
Fix this by checking for FEAT_TRBE (Trace Buffer) rather than
FEAT_TRBE_EXT.
Fixes: 9d5261269098 ("KVM: arm64: Trap external trace for protected VMs")
Reported-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 43bde061b65d..8d06a246dfd1 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -117,7 +117,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
val |= MDCR_EL2_TTRF;
- if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP))
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
val |= MDCR_EL2_E2TB_MASK;
/* Trap Debug Communications Channel registers */
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
2025-11-18 10:37 ` [PATCH v5 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs Fuad Tabba
@ 2025-11-18 10:37 ` Fuad Tabba
2025-11-18 11:11 ` Suzuki K Poulose
2025-11-26 10:23 ` Marc Zyngier
2025-11-18 10:38 ` [PATCH v5 3/9] KVM: arm64: Fix MTE flag initialization " Fuad Tabba
` (7 subsequent siblings)
9 siblings, 2 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:37 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
register accesses. These accesses are trapped to EL2 when the bits are
clear.
The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
had the polarity inverted. When a guest did not support the Trace Buffer
feature, the code was setting E2TB. This incorrectly disabled the trap,
potentially allowing a protected guest to access registers for a feature
it was not given.
Fix this by inverting the operation.
Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 8d06a246dfd1..f6f8996c4f97 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
val |= MDCR_EL2_TTRF;
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
- val |= MDCR_EL2_E2TB_MASK;
+ val &= ~MDCR_EL2_E2TB_MASK;
/* Trap Debug Communications Channel registers */
if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-18 10:37 ` [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
@ 2025-11-18 11:11 ` Suzuki K Poulose
2025-11-26 10:23 ` Marc Zyngier
1 sibling, 0 replies; 27+ messages in thread
From: Suzuki K Poulose @ 2025-11-18 11:11 UTC (permalink / raw)
To: Fuad Tabba, kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, yuzenghui, catalin.marinas,
vladimir.murzin
On 18/11/2025 10:37, Fuad Tabba wrote:
> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> register accesses. These accesses are trapped to EL2 when the bits are
> clear.
>
> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> had the polarity inverted. When a guest did not support the Trace Buffer
> feature, the code was setting E2TB. This incorrectly disabled the trap,
> potentially allowing a protected guest to access registers for a feature
> it was not given.
>
> Fix this by inverting the operation.
>
> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index 8d06a246dfd1..f6f8996c4f97 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> val |= MDCR_EL2_TTRF;
>
> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> - val |= MDCR_EL2_E2TB_MASK;
> + val &= ~MDCR_EL2_E2TB_MASK;
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-18 10:37 ` [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
2025-11-18 11:11 ` Suzuki K Poulose
@ 2025-11-26 10:23 ` Marc Zyngier
2025-11-26 10:29 ` James Clark
2025-11-26 10:37 ` Fuad Tabba
1 sibling, 2 replies; 27+ messages in thread
From: Marc Zyngier @ 2025-11-26 10:23 UTC (permalink / raw)
To: Fuad Tabba
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On Tue, 18 Nov 2025 10:37:59 +0000,
Fuad Tabba <tabba@google.com> wrote:
>
> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> register accesses. These accesses are trapped to EL2 when the bits are
> clear.
>
> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> had the polarity inverted. When a guest did not support the Trace Buffer
> feature, the code was setting E2TB. This incorrectly disabled the trap,
> potentially allowing a protected guest to access registers for a feature
> it was not given.
>
> Fix this by inverting the operation.
>
> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index 8d06a246dfd1..f6f8996c4f97 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> val |= MDCR_EL2_TTRF;
>
> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> - val |= MDCR_EL2_E2TB_MASK;
> + val &= ~MDCR_EL2_E2TB_MASK;
This does not only change the trapping logic (bit 24). It also change
the ownership of the buffer (bit 25). I wonder whether you should do
something for that, maybe by clearing TRBLIMITR_EL1.E, because
otherwise, you keep tracing, but using an EL2 VA. What could possibly
go wrong?
Overall, I'm very uneasy about TRBE in the context of pKVM.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 10:23 ` Marc Zyngier
@ 2025-11-26 10:29 ` James Clark
2025-11-26 10:36 ` Fuad Tabba
2025-11-26 10:37 ` Fuad Tabba
1 sibling, 1 reply; 27+ messages in thread
From: James Clark @ 2025-11-26 10:29 UTC (permalink / raw)
To: Marc Zyngier, Fuad Tabba
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On 26/11/2025 10:23 am, Marc Zyngier wrote:
> On Tue, 18 Nov 2025 10:37:59 +0000,
> Fuad Tabba <tabba@google.com> wrote:
>>
>> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
>> register accesses. These accesses are trapped to EL2 when the bits are
>> clear.
>>
>> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
>> had the polarity inverted. When a guest did not support the Trace Buffer
>> feature, the code was setting E2TB. This incorrectly disabled the trap,
>> potentially allowing a protected guest to access registers for a feature
>> it was not given.
>>
>> Fix this by inverting the operation.
>>
>> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
>> Signed-off-by: Fuad Tabba <tabba@google.com>
>> ---
>> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>> index 8d06a246dfd1..f6f8996c4f97 100644
>> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
>> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
>> val |= MDCR_EL2_TTRF;
>>
>> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
>> - val |= MDCR_EL2_E2TB_MASK;
>> + val &= ~MDCR_EL2_E2TB_MASK;
>
> This does not only change the trapping logic (bit 24). It also change
> the ownership of the buffer (bit 25). I wonder whether you should do
> something for that, maybe by clearing TRBLIMITR_EL1.E, because
> otherwise, you keep tracing, but using an EL2 VA. What could possibly
> go wrong?
>
> Overall, I'm very uneasy about TRBE in the context of pKVM.
>
> Thanks,
>
> M.
>
Don't we already clear TRBLIMITR_EL1.E in __trace_needs_drain() for pKVM
when switching to the guest?
James
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 10:29 ` James Clark
@ 2025-11-26 10:36 ` Fuad Tabba
2025-11-26 10:39 ` James Clark
0 siblings, 1 reply; 27+ messages in thread
From: Fuad Tabba @ 2025-11-26 10:36 UTC (permalink / raw)
To: James Clark
Cc: Marc Zyngier, kvmarm, linux-arm-kernel, oliver.upton, will,
joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
vladimir.murzin
Hi James,
On Wed, 26 Nov 2025 at 10:29, James Clark <james.clark@linaro.org> wrote:
>
>
>
> On 26/11/2025 10:23 am, Marc Zyngier wrote:
> > On Tue, 18 Nov 2025 10:37:59 +0000,
> > Fuad Tabba <tabba@google.com> wrote:
> >>
> >> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> >> register accesses. These accesses are trapped to EL2 when the bits are
> >> clear.
> >>
> >> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> >> had the polarity inverted. When a guest did not support the Trace Buffer
> >> feature, the code was setting E2TB. This incorrectly disabled the trap,
> >> potentially allowing a protected guest to access registers for a feature
> >> it was not given.
> >>
> >> Fix this by inverting the operation.
> >>
> >> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> >> Signed-off-by: Fuad Tabba <tabba@google.com>
> >> ---
> >> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> >> 1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >> index 8d06a246dfd1..f6f8996c4f97 100644
> >> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> >> val |= MDCR_EL2_TTRF;
> >>
> >> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> >> - val |= MDCR_EL2_E2TB_MASK;
> >> + val &= ~MDCR_EL2_E2TB_MASK;
> >
> > This does not only change the trapping logic (bit 24). It also change
> > the ownership of the buffer (bit 25). I wonder whether you should do
> > something for that, maybe by clearing TRBLIMITR_EL1.E, because
> > otherwise, you keep tracing, but using an EL2 VA. What could possibly
> > go wrong?
> >
> > Overall, I'm very uneasy about TRBE in the context of pKVM.
> >
> > Thanks,
> >
> > M.
> >
>
> Don't we already clear TRBLIMITR_EL1.E in __trace_needs_drain() for pKVM
> when switching to the guest?
I don't think so:
https://elixir.bootlin.com/linux/v6.18-rc7/source/arch/arm64/kvm/hyp/nvhe/debug-sr.c#L60
Cheers,
/fuad
> James
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 10:36 ` Fuad Tabba
@ 2025-11-26 10:39 ` James Clark
0 siblings, 0 replies; 27+ messages in thread
From: James Clark @ 2025-11-26 10:39 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, kvmarm, linux-arm-kernel, oliver.upton, will,
joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
vladimir.murzin
On 26/11/2025 10:36 am, Fuad Tabba wrote:
> Hi James,
>
> On Wed, 26 Nov 2025 at 10:29, James Clark <james.clark@linaro.org> wrote:
>>
>>
>>
>> On 26/11/2025 10:23 am, Marc Zyngier wrote:
>>> On Tue, 18 Nov 2025 10:37:59 +0000,
>>> Fuad Tabba <tabba@google.com> wrote:
>>>>
>>>> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
>>>> register accesses. These accesses are trapped to EL2 when the bits are
>>>> clear.
>>>>
>>>> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
>>>> had the polarity inverted. When a guest did not support the Trace Buffer
>>>> feature, the code was setting E2TB. This incorrectly disabled the trap,
>>>> potentially allowing a protected guest to access registers for a feature
>>>> it was not given.
>>>>
>>>> Fix this by inverting the operation.
>>>>
>>>> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
>>>> Signed-off-by: Fuad Tabba <tabba@google.com>
>>>> ---
>>>> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>> index 8d06a246dfd1..f6f8996c4f97 100644
>>>> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
>>>> val |= MDCR_EL2_TTRF;
>>>>
>>>> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
>>>> - val |= MDCR_EL2_E2TB_MASK;
>>>> + val &= ~MDCR_EL2_E2TB_MASK;
>>>
>>> This does not only change the trapping logic (bit 24). It also change
>>> the ownership of the buffer (bit 25). I wonder whether you should do
>>> something for that, maybe by clearing TRBLIMITR_EL1.E, because
>>> otherwise, you keep tracing, but using an EL2 VA. What could possibly
>>> go wrong?
>>>
>>> Overall, I'm very uneasy about TRBE in the context of pKVM.
>>>
>>> Thanks,
>>>
>>> M.
>>>
>>
>> Don't we already clear TRBLIMITR_EL1.E in __trace_needs_drain() for pKVM
>> when switching to the guest?
>
> I don't think so:
> https://elixir.bootlin.com/linux/v6.18-rc7/source/arch/arm64/kvm/hyp/nvhe/debug-sr.c#L60
>
> Cheers,
> /fuad
>> James
>>
Oh yeah I glanced over the TRBLIMITR_EL1_E and thought that was clearing
it, but it's just checking if it's enabled or not.
We actually disable trace by setting the filters to 0 in
__trace_do_switch() and leave TRBLIMITR_EL1.E enabled.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 10:23 ` Marc Zyngier
2025-11-26 10:29 ` James Clark
@ 2025-11-26 10:37 ` Fuad Tabba
2025-11-26 11:47 ` Marc Zyngier
1 sibling, 1 reply; 27+ messages in thread
From: Fuad Tabba @ 2025-11-26 10:37 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
Hi Marc,
On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
>
> On Tue, 18 Nov 2025 10:37:59 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> > register accesses. These accesses are trapped to EL2 when the bits are
> > clear.
> >
> > The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> > had the polarity inverted. When a guest did not support the Trace Buffer
> > feature, the code was setting E2TB. This incorrectly disabled the trap,
> > potentially allowing a protected guest to access registers for a feature
> > it was not given.
> >
> > Fix this by inverting the operation.
> >
> > Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> > arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > index 8d06a246dfd1..f6f8996c4f97 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> > val |= MDCR_EL2_TTRF;
> >
> > if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> > - val |= MDCR_EL2_E2TB_MASK;
> > + val &= ~MDCR_EL2_E2TB_MASK;
>
> This does not only change the trapping logic (bit 24). It also change
> the ownership of the buffer (bit 25). I wonder whether you should do
> something for that, maybe by clearing TRBLIMITR_EL1.E, because
> otherwise, you keep tracing, but using an EL2 VA. What could possibly
> go wrong?
>
> Overall, I'm very uneasy about TRBE in the context of pKVM.
So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
protected mode?
Cheers,
/fuad
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 10:37 ` Fuad Tabba
@ 2025-11-26 11:47 ` Marc Zyngier
2025-11-26 11:48 ` Fuad Tabba
0 siblings, 1 reply; 27+ messages in thread
From: Marc Zyngier @ 2025-11-26 11:47 UTC (permalink / raw)
To: Fuad Tabba
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On Wed, 26 Nov 2025 10:37:57 +0000,
Fuad Tabba <tabba@google.com> wrote:
>
> Hi Marc,
>
> On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
> >
> > On Tue, 18 Nov 2025 10:37:59 +0000,
> > Fuad Tabba <tabba@google.com> wrote:
> > >
> > > The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> > > register accesses. These accesses are trapped to EL2 when the bits are
> > > clear.
> > >
> > > The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> > > had the polarity inverted. When a guest did not support the Trace Buffer
> > > feature, the code was setting E2TB. This incorrectly disabled the trap,
> > > potentially allowing a protected guest to access registers for a feature
> > > it was not given.
> > >
> > > Fix this by inverting the operation.
> > >
> > > Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> > > Signed-off-by: Fuad Tabba <tabba@google.com>
> > > ---
> > > arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > index 8d06a246dfd1..f6f8996c4f97 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> > > val |= MDCR_EL2_TTRF;
> > >
> > > if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> > > - val |= MDCR_EL2_E2TB_MASK;
> > > + val &= ~MDCR_EL2_E2TB_MASK;
> >
> > This does not only change the trapping logic (bit 24). It also change
> > the ownership of the buffer (bit 25). I wonder whether you should do
> > something for that, maybe by clearing TRBLIMITR_EL1.E, because
> > otherwise, you keep tracing, but using an EL2 VA. What could possibly
> > go wrong?
> >
> > Overall, I'm very uneasy about TRBE in the context of pKVM.
>
> So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
> protected mode?
I think you need something of the sort, yes. Overall, SPE and TRBE
should be aligned on what they are allowed to do, as they are two
sides of the same ugly coin.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 11:47 ` Marc Zyngier
@ 2025-11-26 11:48 ` Fuad Tabba
2025-11-27 15:26 ` James Clark
0 siblings, 1 reply; 27+ messages in thread
From: Fuad Tabba @ 2025-11-26 11:48 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On Wed, 26 Nov 2025 at 11:47, Marc Zyngier <maz@kernel.org> wrote:
>
> On Wed, 26 Nov 2025 10:37:57 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > Hi Marc,
> >
> > On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
> > >
> > > On Tue, 18 Nov 2025 10:37:59 +0000,
> > > Fuad Tabba <tabba@google.com> wrote:
> > > >
> > > > The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> > > > register accesses. These accesses are trapped to EL2 when the bits are
> > > > clear.
> > > >
> > > > The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> > > > had the polarity inverted. When a guest did not support the Trace Buffer
> > > > feature, the code was setting E2TB. This incorrectly disabled the trap,
> > > > potentially allowing a protected guest to access registers for a feature
> > > > it was not given.
> > > >
> > > > Fix this by inverting the operation.
> > > >
> > > > Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> > > > Signed-off-by: Fuad Tabba <tabba@google.com>
> > > > ---
> > > > arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > > index 8d06a246dfd1..f6f8996c4f97 100644
> > > > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> > > > @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> > > > val |= MDCR_EL2_TTRF;
> > > >
> > > > if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> > > > - val |= MDCR_EL2_E2TB_MASK;
> > > > + val &= ~MDCR_EL2_E2TB_MASK;
> > >
> > > This does not only change the trapping logic (bit 24). It also change
> > > the ownership of the buffer (bit 25). I wonder whether you should do
> > > something for that, maybe by clearing TRBLIMITR_EL1.E, because
> > > otherwise, you keep tracing, but using an EL2 VA. What could possibly
> > > go wrong?
> > >
> > > Overall, I'm very uneasy about TRBE in the context of pKVM.
> >
> > So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
> > protected mode?
>
> I think you need something of the sort, yes. Overall, SPE and TRBE
> should be aligned on what they are allowed to do, as they are two
> sides of the same ugly coin.
I'll fix this (or add a patch to do this, depending on how it looks)
when I respin.
Cheers,
/fuad
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-26 11:48 ` Fuad Tabba
@ 2025-11-27 15:26 ` James Clark
2025-11-27 15:38 ` Fuad Tabba
0 siblings, 1 reply; 27+ messages in thread
From: James Clark @ 2025-11-27 15:26 UTC (permalink / raw)
To: Fuad Tabba, Marc Zyngier
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On 26/11/2025 11:48 am, Fuad Tabba wrote:
> On Wed, 26 Nov 2025 at 11:47, Marc Zyngier <maz@kernel.org> wrote:
>>
>> On Wed, 26 Nov 2025 10:37:57 +0000,
>> Fuad Tabba <tabba@google.com> wrote:
>>>
>>> Hi Marc,
>>>
>>> On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
>>>>
>>>> On Tue, 18 Nov 2025 10:37:59 +0000,
>>>> Fuad Tabba <tabba@google.com> wrote:
>>>>>
>>>>> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
>>>>> register accesses. These accesses are trapped to EL2 when the bits are
>>>>> clear.
>>>>>
>>>>> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
>>>>> had the polarity inverted. When a guest did not support the Trace Buffer
>>>>> feature, the code was setting E2TB. This incorrectly disabled the trap,
>>>>> potentially allowing a protected guest to access registers for a feature
>>>>> it was not given.
>>>>>
>>>>> Fix this by inverting the operation.
>>>>>
>>>>> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
>>>>> Signed-off-by: Fuad Tabba <tabba@google.com>
>>>>> ---
>>>>> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
>>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>>> index 8d06a246dfd1..f6f8996c4f97 100644
>>>>> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>>> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>>> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
>>>>> val |= MDCR_EL2_TTRF;
>>>>>
>>>>> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
>>>>> - val |= MDCR_EL2_E2TB_MASK;
>>>>> + val &= ~MDCR_EL2_E2TB_MASK;
>>>>
>>>> This does not only change the trapping logic (bit 24). It also change
>>>> the ownership of the buffer (bit 25). I wonder whether you should do
>>>> something for that, maybe by clearing TRBLIMITR_EL1.E, because
>>>> otherwise, you keep tracing, but using an EL2 VA. What could possibly
>>>> go wrong?
>>>>
>>>> Overall, I'm very uneasy about TRBE in the context of pKVM.
>>>
>>> So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
>>> protected mode?
>>
>> I think you need something of the sort, yes. Overall, SPE and TRBE
>> should be aligned on what they are allowed to do, as they are two
>> sides of the same ugly coin.
>
> I'll fix this (or add a patch to do this, depending on how it looks)
> when I respin.
>
> Cheers,
> /fuad
>
To understand this, is it just belt-and-braces because you don't trust
the current filter clearing in TRFCR_EL1? And to reduce the potential
for mistakes leading to trace leakages? I suppose even the hardware
itself could have some errata where it tries to access the buffer, even
if we've completely filtered out trace and flushed before going into the
guest.
Thanks
James
>> M.
>>
>> --
>> Without deviation from the norm, progress is not possible.
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-27 15:26 ` James Clark
@ 2025-11-27 15:38 ` Fuad Tabba
2025-11-27 16:06 ` James Clark
0 siblings, 1 reply; 27+ messages in thread
From: Fuad Tabba @ 2025-11-27 15:38 UTC (permalink / raw)
To: James Clark
Cc: Marc Zyngier, kvmarm, linux-arm-kernel, oliver.upton, will,
joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
vladimir.murzin
On Thu, 27 Nov 2025 at 15:26, James Clark <james.clark@linaro.org> wrote:
>
>
>
> On 26/11/2025 11:48 am, Fuad Tabba wrote:
> > On Wed, 26 Nov 2025 at 11:47, Marc Zyngier <maz@kernel.org> wrote:
> >>
> >> On Wed, 26 Nov 2025 10:37:57 +0000,
> >> Fuad Tabba <tabba@google.com> wrote:
> >>>
> >>> Hi Marc,
> >>>
> >>> On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
> >>>>
> >>>> On Tue, 18 Nov 2025 10:37:59 +0000,
> >>>> Fuad Tabba <tabba@google.com> wrote:
> >>>>>
> >>>>> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> >>>>> register accesses. These accesses are trapped to EL2 when the bits are
> >>>>> clear.
> >>>>>
> >>>>> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> >>>>> had the polarity inverted. When a guest did not support the Trace Buffer
> >>>>> feature, the code was setting E2TB. This incorrectly disabled the trap,
> >>>>> potentially allowing a protected guest to access registers for a feature
> >>>>> it was not given.
> >>>>>
> >>>>> Fix this by inverting the operation.
> >>>>>
> >>>>> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> >>>>> Signed-off-by: Fuad Tabba <tabba@google.com>
> >>>>> ---
> >>>>> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> >>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >>>>> index 8d06a246dfd1..f6f8996c4f97 100644
> >>>>> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >>>>> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >>>>> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> >>>>> val |= MDCR_EL2_TTRF;
> >>>>>
> >>>>> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> >>>>> - val |= MDCR_EL2_E2TB_MASK;
> >>>>> + val &= ~MDCR_EL2_E2TB_MASK;
> >>>>
> >>>> This does not only change the trapping logic (bit 24). It also change
> >>>> the ownership of the buffer (bit 25). I wonder whether you should do
> >>>> something for that, maybe by clearing TRBLIMITR_EL1.E, because
> >>>> otherwise, you keep tracing, but using an EL2 VA. What could possibly
> >>>> go wrong?
> >>>>
> >>>> Overall, I'm very uneasy about TRBE in the context of pKVM.
> >>>
> >>> So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
> >>> protected mode?
> >>
> >> I think you need something of the sort, yes. Overall, SPE and TRBE
> >> should be aligned on what they are allowed to do, as they are two
> >> sides of the same ugly coin.
> >
> > I'll fix this (or add a patch to do this, depending on how it looks)
> > when I respin.
> >
> > Cheers,
> > /fuad
> >
>
> To understand this, is it just belt-and-braces because you don't trust
> the current filter clearing in TRFCR_EL1? And to reduce the potential
> for mistakes leading to trace leakages? I suppose even the hardware
> itself could have some errata where it tries to access the buffer, even
> if we've completely filtered out trace and flushed before going into the
> guest.
Yes, we don't trust the host. The pKVM threat model is to protect
against a malicious host.
Getting into hardware errata... that's a can of worms. I haven't
considered that.
Cheers,
/fuad
> Thanks
> James
>
> >> M.
> >>
> >> --
> >> Without deviation from the norm, progress is not possible.
> >
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-27 15:38 ` Fuad Tabba
@ 2025-11-27 16:06 ` James Clark
2025-11-27 16:23 ` Fuad Tabba
0 siblings, 1 reply; 27+ messages in thread
From: James Clark @ 2025-11-27 16:06 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, kvmarm, linux-arm-kernel, oliver.upton, will,
joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
vladimir.murzin
On 27/11/2025 3:38 pm, Fuad Tabba wrote:
> On Thu, 27 Nov 2025 at 15:26, James Clark <james.clark@linaro.org> wrote:
>>
>>
>>
>> On 26/11/2025 11:48 am, Fuad Tabba wrote:
>>> On Wed, 26 Nov 2025 at 11:47, Marc Zyngier <maz@kernel.org> wrote:
>>>>
>>>> On Wed, 26 Nov 2025 10:37:57 +0000,
>>>> Fuad Tabba <tabba@google.com> wrote:
>>>>>
>>>>> Hi Marc,
>>>>>
>>>>> On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
>>>>>>
>>>>>> On Tue, 18 Nov 2025 10:37:59 +0000,
>>>>>> Fuad Tabba <tabba@google.com> wrote:
>>>>>>>
>>>>>>> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
>>>>>>> register accesses. These accesses are trapped to EL2 when the bits are
>>>>>>> clear.
>>>>>>>
>>>>>>> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
>>>>>>> had the polarity inverted. When a guest did not support the Trace Buffer
>>>>>>> feature, the code was setting E2TB. This incorrectly disabled the trap,
>>>>>>> potentially allowing a protected guest to access registers for a feature
>>>>>>> it was not given.
>>>>>>>
>>>>>>> Fix this by inverting the operation.
>>>>>>>
>>>>>>> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
>>>>>>> Signed-off-by: Fuad Tabba <tabba@google.com>
>>>>>>> ---
>>>>>>> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
>>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>>>>> index 8d06a246dfd1..f6f8996c4f97 100644
>>>>>>> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>>>>> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
>>>>>>> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
>>>>>>> val |= MDCR_EL2_TTRF;
>>>>>>>
>>>>>>> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
>>>>>>> - val |= MDCR_EL2_E2TB_MASK;
>>>>>>> + val &= ~MDCR_EL2_E2TB_MASK;
>>>>>>
>>>>>> This does not only change the trapping logic (bit 24). It also change
>>>>>> the ownership of the buffer (bit 25). I wonder whether you should do
>>>>>> something for that, maybe by clearing TRBLIMITR_EL1.E, because
>>>>>> otherwise, you keep tracing, but using an EL2 VA. What could possibly
>>>>>> go wrong?
>>>>>>
>>>>>> Overall, I'm very uneasy about TRBE in the context of pKVM.
>>>>>
>>>>> So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
>>>>> protected mode?
>>>>
>>>> I think you need something of the sort, yes. Overall, SPE and TRBE
>>>> should be aligned on what they are allowed to do, as they are two
>>>> sides of the same ugly coin.
>>>
>>> I'll fix this (or add a patch to do this, depending on how it looks)
>>> when I respin.
>>>
>>> Cheers,
>>> /fuad
>>>
>>
>> To understand this, is it just belt-and-braces because you don't trust
>> the current filter clearing in TRFCR_EL1? And to reduce the potential
>> for mistakes leading to trace leakages? I suppose even the hardware
>> itself could have some errata where it tries to access the buffer, even
>> if we've completely filtered out trace and flushed before going into the
>> guest.
>
> Yes, we don't trust the host. The pKVM threat model is to protect
> against a malicious host.
>
> Getting into hardware errata... that's a can of worms. I haven't
> considered that.
>
> Cheers,
> /fuad
>
>
But the hypervisor already clears the filters, equivalent to clearing
TRBLIMITR_EL1.E. Which is why I was wondering if there was something
extra on top of the model where the host isn't trusted. I would assume
that without anything more specific that just clearing the filters is
enough. If we trust the hardware then it is anyway.
>> Thanks
>> James
>>
>>>> M.
>>>>
>>>> --
>>>> Without deviation from the norm, progress is not possible.
>>>
>>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
2025-11-27 16:06 ` James Clark
@ 2025-11-27 16:23 ` Fuad Tabba
0 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-27 16:23 UTC (permalink / raw)
To: James Clark
Cc: Marc Zyngier, kvmarm, linux-arm-kernel, oliver.upton, will,
joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
vladimir.murzin
On Thu, 27 Nov 2025 at 16:06, James Clark <james.clark@linaro.org> wrote:
>
>
>
> On 27/11/2025 3:38 pm, Fuad Tabba wrote:
> > On Thu, 27 Nov 2025 at 15:26, James Clark <james.clark@linaro.org> wrote:
> >>
> >>
> >>
> >> On 26/11/2025 11:48 am, Fuad Tabba wrote:
> >>> On Wed, 26 Nov 2025 at 11:47, Marc Zyngier <maz@kernel.org> wrote:
> >>>>
> >>>> On Wed, 26 Nov 2025 10:37:57 +0000,
> >>>> Fuad Tabba <tabba@google.com> wrote:
> >>>>>
> >>>>> Hi Marc,
> >>>>>
> >>>>> On Wed, 26 Nov 2025 at 10:23, Marc Zyngier <maz@kernel.org> wrote:
> >>>>>>
> >>>>>> On Tue, 18 Nov 2025 10:37:59 +0000,
> >>>>>> Fuad Tabba <tabba@google.com> wrote:
> >>>>>>>
> >>>>>>> The E2TB bits in MDCR_EL2 control trapping of Trace Buffer system
> >>>>>>> register accesses. These accesses are trapped to EL2 when the bits are
> >>>>>>> clear.
> >>>>>>>
> >>>>>>> The trap initialization logic for protected VMs in pvm_init_traps_mdcr()
> >>>>>>> had the polarity inverted. When a guest did not support the Trace Buffer
> >>>>>>> feature, the code was setting E2TB. This incorrectly disabled the trap,
> >>>>>>> potentially allowing a protected guest to access registers for a feature
> >>>>>>> it was not given.
> >>>>>>>
> >>>>>>> Fix this by inverting the operation.
> >>>>>>>
> >>>>>>> Fixes: f50758260bff ("KVM: arm64: Group setting traps for protected VMs by control register")
> >>>>>>> Signed-off-by: Fuad Tabba <tabba@google.com>
> >>>>>>> ---
> >>>>>>> arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +-
> >>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>>>>
> >>>>>>> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >>>>>>> index 8d06a246dfd1..f6f8996c4f97 100644
> >>>>>>> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >>>>>>> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> >>>>>>> @@ -118,7 +118,7 @@ static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
> >>>>>>> val |= MDCR_EL2_TTRF;
> >>>>>>>
> >>>>>>> if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> >>>>>>> - val |= MDCR_EL2_E2TB_MASK;
> >>>>>>> + val &= ~MDCR_EL2_E2TB_MASK;
> >>>>>>
> >>>>>> This does not only change the trapping logic (bit 24). It also change
> >>>>>> the ownership of the buffer (bit 25). I wonder whether you should do
> >>>>>> something for that, maybe by clearing TRBLIMITR_EL1.E, because
> >>>>>> otherwise, you keep tracing, but using an EL2 VA. What could possibly
> >>>>>> go wrong?
> >>>>>>
> >>>>>> Overall, I'm very uneasy about TRBE in the context of pKVM.
> >>>>>
> >>>>> So should we clear/restore TRBLIMITR_EL1.E on guest entry/exit in
> >>>>> protected mode?
> >>>>
> >>>> I think you need something of the sort, yes. Overall, SPE and TRBE
> >>>> should be aligned on what they are allowed to do, as they are two
> >>>> sides of the same ugly coin.
> >>>
> >>> I'll fix this (or add a patch to do this, depending on how it looks)
> >>> when I respin.
> >>>
> >>> Cheers,
> >>> /fuad
> >>>
> >>
> >> To understand this, is it just belt-and-braces because you don't trust
> >> the current filter clearing in TRFCR_EL1? And to reduce the potential
> >> for mistakes leading to trace leakages? I suppose even the hardware
> >> itself could have some errata where it tries to access the buffer, even
> >> if we've completely filtered out trace and flushed before going into the
> >> guest.
> >
> > Yes, we don't trust the host. The pKVM threat model is to protect
> > against a malicious host.
> >
> > Getting into hardware errata... that's a can of worms. I haven't
> > considered that.
> >
> > Cheers,
> > /fuad
> >
> >
>
> But the hypervisor already clears the filters, equivalent to clearing
> TRBLIMITR_EL1.E. Which is why I was wondering if there was something
> extra on top of the model where the host isn't trusted. I would assume
> that without anything more specific that just clearing the filters is
> enough. If we trust the hardware then it is anyway.
We trust the hardware, yes. Marc, what do you think?
/fuad
> >> Thanks
> >> James
> >>
> >>>> M.
> >>>>
> >>>> --
> >>>> Without deviation from the norm, progress is not possible.
> >>>
> >>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 3/9] KVM: arm64: Fix MTE flag initialization for protected VMs
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
2025-11-18 10:37 ` [PATCH v5 1/9] KVM: arm64: Fix Trace Buffer trapping for protected VMs Fuad Tabba
2025-11-18 10:37 ` [PATCH v5 2/9] KVM: arm64: Fix Trace Buffer trap polarity " Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-18 10:38 ` [PATCH v5 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset Fuad Tabba
` (6 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
The function pkvm_init_features_from_host() initializes guest
features, propagating them from the host. The logic to propagate
KVM_ARCH_FLAG_MTE_ENABLED (Memory Tagging Extension)
has a couple of issues.
First, the check was in the common path, before the divergence for
protected and non-protected VMs. For non-protected VMs, this was
unnecessary, as 'kvm->arch.flags' is completely overwritten by
host_arch_flags immediately after, which already contains the MTE flag.
For protected VMs, this was setting the flag even if the feature is not
allowed.
Second, the check was reading 'host_kvm->arch.flags' instead of using
the local 'host_arch_flags', which is read once from the host flags.
Fix these by moving the MTE flag check inside the protected-VM-only
path, checking if the feature is allowed, and changing it to use the
correct host_arch_flags local variable. This ensures non-protected VMs
get the flag via the bulk copy, and protected VMs get it via an explicit
check.
Fixes: b7f345fbc32a ("KVM: arm64: Fix FEAT_MTE in pKVM")
Reviewed-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/pkvm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index f6f8996c4f97..16d7bf493c18 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -337,9 +337,6 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
/* CTR_EL0 is always under host control, even for protected VMs. */
hyp_vm->kvm.arch.ctr_el0 = host_kvm->arch.ctr_el0;
- if (test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &host_kvm->arch.flags))
- set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags);
-
/* No restrictions for non-protected VMs. */
if (!kvm_vm_is_protected(kvm)) {
hyp_vm->kvm.arch.flags = host_arch_flags;
@@ -354,6 +351,9 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
return;
}
+ if (kvm_pvm_ext_allowed(KVM_CAP_ARM_MTE))
+ kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_MTE_ENABLED);
+
bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v5 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (2 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 3/9] KVM: arm64: Fix MTE flag initialization " Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-18 10:38 ` [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM Fuad Tabba
` (5 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
This 12-bit FAR fault IPA offset mask is hard-coded as 'GENMASK(11, 0)'
in several places to reconstruct the full fault IPA.
Introduce FAR_TO_FIPA_OFFSET() to calculate this value in a shared
header and replace all open-coded instances to improve readability.
No functional change intended.
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_arm.h | 2 ++
arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 2 +-
arch/arm64/kvm/inject_fault.c | 2 +-
arch/arm64/kvm/mmu.c | 4 ++--
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 1da290aeedce..73abe697bc2d 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -343,6 +343,8 @@
#define PAR_TO_HPFAR(par) \
(((par) & GENMASK_ULL(52 - 1, 12)) >> 8)
+#define FAR_TO_FIPA_OFFSET(far) ((far) & GENMASK_ULL(11, 0))
+
#define ECN(x) { ESR_ELx_EC_##x, #x }
#define kvm_arm_exception_class \
diff --git a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
index 78579b31a420..43d7dfa2c517 100644
--- a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
+++ b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
@@ -44,7 +44,7 @@ int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
/* Build the full address */
fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
- fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+ fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
/* If not for GICV, move on */
if (fault_ipa < vgic->vgic_cpu_base ||
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index dfcd66c65517..c9bbce017dee 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -258,7 +258,7 @@ void kvm_inject_size_fault(struct kvm_vcpu *vcpu)
unsigned long addr, esr;
addr = kvm_vcpu_get_fault_ipa(vcpu);
- addr |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+ addr |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
__kvm_inject_sea(vcpu, kvm_vcpu_trap_is_iabt(vcpu), addr);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 7cc964af8d30..5b159cf0d203 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1959,7 +1959,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
/* Falls between the IPA range and the PARange? */
if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) {
- fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+ fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
return kvm_inject_sea(vcpu, is_iabt, fault_ipa);
}
@@ -2059,7 +2059,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
* faulting VA. This is always 12 bits, irrespective
* of the page size.
*/
- ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0);
+ ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
ret = io_mem_abort(vcpu, ipa);
goto out_unlock;
}
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (3 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 4/9] KVM: arm64: Introduce helper to calculate fault IPA offset Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-26 10:52 ` Marc Zyngier
2025-11-18 10:38 ` [PATCH v5 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest " Fuad Tabba
` (4 subsequent siblings)
9 siblings, 1 reply; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
Certian features and capabilities are restricted in protected mode. Most
of these features are restricted only for protected VMs, but some
are restricted for ALL VMs in protected mode.
Extend the pKVM capability check to pass the VM (kvm), and use that when
determining supported features. Moreover, extend the check to disallow
MTE for all VM types in protected mode.
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_pkvm.h | 10 ++++++----
arch/arm64/kvm/arm.c | 4 ++--
arch/arm64/kvm/hyp/nvhe/pkvm.c | 10 +++++-----
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 08be89c95466..7195be508d99 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -23,10 +23,12 @@ void pkvm_destroy_hyp_vm(struct kvm *kvm);
int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
/*
- * This functions as an allow-list of protected VM capabilities.
- * Features not explicitly allowed by this function are denied.
+ * Check whether the specific capability is allowed in pKVM.
+ *
+ * Certain features are allowed only for non-protected VMs in pKVM, which is why
+ * this takes the VM (kvm) as a parameter.
*/
-static inline bool kvm_pvm_ext_allowed(long ext)
+static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
{
switch (ext) {
case KVM_CAP_IRQCHIP:
@@ -43,7 +45,7 @@ static inline bool kvm_pvm_ext_allowed(long ext)
case KVM_CAP_ARM_PTRAUTH_GENERIC:
return true;
default:
- return false;
+ return !kvm || !kvm_vm_is_protected(kvm);
}
}
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 870953b4a8a7..10d853f2722e 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -87,7 +87,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
if (cap->flags)
return -EINVAL;
- if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap))
+ if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, cap->cap))
return -EINVAL;
switch (cap->cap) {
@@ -299,7 +299,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
{
int r;
- if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext))
+ if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, ext))
return 0;
switch (ext) {
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 16d7bf493c18..581dec4b8271 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -351,23 +351,23 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
return;
}
- if (kvm_pvm_ext_allowed(KVM_CAP_ARM_MTE))
+ if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_MTE))
kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_MTE_ENABLED);
bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
- if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3))
+ if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PMU_V3))
set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
- if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS))
+ if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_ADDRESS))
set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
- if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC))
+ if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_GENERIC))
set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
- if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE)) {
+ if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_SVE)) {
set_bit(KVM_ARM_VCPU_SVE, allowed_features);
kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE);
}
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
2025-11-18 10:38 ` [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM Fuad Tabba
@ 2025-11-26 10:52 ` Marc Zyngier
2025-11-26 11:00 ` Fuad Tabba
0 siblings, 1 reply; 27+ messages in thread
From: Marc Zyngier @ 2025-11-26 10:52 UTC (permalink / raw)
To: Fuad Tabba
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On Tue, 18 Nov 2025 10:38:02 +0000,
Fuad Tabba <tabba@google.com> wrote:
>
> Certian features and capabilities are restricted in protected mode. Most
> of these features are restricted only for protected VMs, but some
> are restricted for ALL VMs in protected mode.
>
> Extend the pKVM capability check to pass the VM (kvm), and use that when
> determining supported features. Moreover, extend the check to disallow
> MTE for all VM types in protected mode.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
> arch/arm64/include/asm/kvm_pkvm.h | 10 ++++++----
> arch/arm64/kvm/arm.c | 4 ++--
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 10 +++++-----
> 3 files changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> index 08be89c95466..7195be508d99 100644
> --- a/arch/arm64/include/asm/kvm_pkvm.h
> +++ b/arch/arm64/include/asm/kvm_pkvm.h
> @@ -23,10 +23,12 @@ void pkvm_destroy_hyp_vm(struct kvm *kvm);
> int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
>
> /*
> - * This functions as an allow-list of protected VM capabilities.
> - * Features not explicitly allowed by this function are denied.
> + * Check whether the specific capability is allowed in pKVM.
> + *
> + * Certain features are allowed only for non-protected VMs in pKVM, which is why
> + * this takes the VM (kvm) as a parameter.
> */
> -static inline bool kvm_pvm_ext_allowed(long ext)
> +static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> {
> switch (ext) {
> case KVM_CAP_IRQCHIP:
> @@ -43,7 +45,7 @@ static inline bool kvm_pvm_ext_allowed(long ext)
> case KVM_CAP_ARM_PTRAUTH_GENERIC:
> return true;
> default:
> - return false;
> + return !kvm || !kvm_vm_is_protected(kvm);
I find this expression a bit unreadable. IMO it would be better if
written as:
return !(kvm && kvm_vm_is_protected(kvm));
which makes it "clear" that you claim to support everything when
either kvm == NULL or described an unprotected VM.
But it then begs the question:
- in what circumstances is kvm == NULL? Is there any case outside of
kvm_vm_check_extension()?
- do you really support everything?
> }
> }
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 870953b4a8a7..10d853f2722e 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -87,7 +87,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
> if (cap->flags)
> return -EINVAL;
>
> - if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap))
> + if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, cap->cap))
> return -EINVAL;
>
> switch (cap->cap) {
> @@ -299,7 +299,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> {
> int r;
>
> - if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext))
> + if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, ext))
> return 0;
But that's a change in semantics here. Calling this function outside
of the context of a VM (kvm == NULL) will now report that *ALL*
extensions are valid, instead of limiting it to the allow-list.
With that, userspace can no longer detect what is available and what
isn't before creating a VM with the correct VM type.
I don't think this is the right way to do this, unless you really want
to break the existing UAPI (rhetorical question).
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
2025-11-26 10:52 ` Marc Zyngier
@ 2025-11-26 11:00 ` Fuad Tabba
2025-11-26 15:36 ` Marc Zyngier
0 siblings, 1 reply; 27+ messages in thread
From: Fuad Tabba @ 2025-11-26 11:00 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
Hi Marc,
On Wed, 26 Nov 2025 at 10:53, Marc Zyngier <maz@kernel.org> wrote:
>
> On Tue, 18 Nov 2025 10:38:02 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > Certian features and capabilities are restricted in protected mode. Most
> > of these features are restricted only for protected VMs, but some
> > are restricted for ALL VMs in protected mode.
> >
> > Extend the pKVM capability check to pass the VM (kvm), and use that when
> > determining supported features. Moreover, extend the check to disallow
> > MTE for all VM types in protected mode.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> > arch/arm64/include/asm/kvm_pkvm.h | 10 ++++++----
> > arch/arm64/kvm/arm.c | 4 ++--
> > arch/arm64/kvm/hyp/nvhe/pkvm.c | 10 +++++-----
> > 3 files changed, 13 insertions(+), 11 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> > index 08be89c95466..7195be508d99 100644
> > --- a/arch/arm64/include/asm/kvm_pkvm.h
> > +++ b/arch/arm64/include/asm/kvm_pkvm.h
> > @@ -23,10 +23,12 @@ void pkvm_destroy_hyp_vm(struct kvm *kvm);
> > int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
> >
> > /*
> > - * This functions as an allow-list of protected VM capabilities.
> > - * Features not explicitly allowed by this function are denied.
> > + * Check whether the specific capability is allowed in pKVM.
> > + *
> > + * Certain features are allowed only for non-protected VMs in pKVM, which is why
> > + * this takes the VM (kvm) as a parameter.
> > */
> > -static inline bool kvm_pvm_ext_allowed(long ext)
> > +static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
> > {
> > switch (ext) {
> > case KVM_CAP_IRQCHIP:
> > @@ -43,7 +45,7 @@ static inline bool kvm_pvm_ext_allowed(long ext)
> > case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > return true;
> > default:
> > - return false;
> > + return !kvm || !kvm_vm_is_protected(kvm);
>
> I find this expression a bit unreadable. IMO it would be better if
> written as:
>
> return !(kvm && kvm_vm_is_protected(kvm));
Will change.
> which makes it "clear" that you claim to support everything when
> either kvm == NULL or described an unprotected VM.
>
> But it then begs the question:
>
> - in what circumstances is kvm == NULL? Is there any case outside of
> kvm_vm_check_extension()?
kvm_vm_ioctl_check_extension() could be called without a VM. In which
case, we don't know if the check is for non-protected or protected.
This patch doesn't change the behavior of this part.
> - do you really support everything?
For non-protected, yes ... with the MTE caveat, which later patches fix.
> > }
> > }
> >
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 870953b4a8a7..10d853f2722e 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -87,7 +87,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
> > if (cap->flags)
> > return -EINVAL;
> >
> > - if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap))
> > + if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, cap->cap))
> > return -EINVAL;
> >
> > switch (cap->cap) {
> > @@ -299,7 +299,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> > {
> > int r;
> >
> > - if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext))
> > + if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, ext))
> > return 0;
>
> But that's a change in semantics here. Calling this function outside
> of the context of a VM (kvm == NULL) will now report that *ALL*
> extensions are valid, instead of limiting it to the allow-list.
>
> With that, userspace can no longer detect what is available and what
> isn't before creating a VM with the correct VM type.
This patch doesn't change this semantic, since this patch moves the
NULL check into kvm_pkvm_ext_allowed().
> I don't think this is the right way to do this, unless you really want
> to break the existing UAPI (rhetorical question).
I agree, but I don't think this patch changes this behavior. Later on
in this series we expand the check to apply to non-protected VMs to
also restrict features that are not allowed in protected mode in
general -- something that until this series we didn't have.
Cheers,
/fuad
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
2025-11-26 11:00 ` Fuad Tabba
@ 2025-11-26 15:36 ` Marc Zyngier
2025-11-26 17:05 ` Fuad Tabba
0 siblings, 1 reply; 27+ messages in thread
From: Marc Zyngier @ 2025-11-26 15:36 UTC (permalink / raw)
To: Fuad Tabba
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On Wed, 26 Nov 2025 11:00:47 +0000,
Fuad Tabba <tabba@google.com> wrote:
>
> Hi Marc,
>
> I agree, but I don't think this patch changes this behavior. Later on
> in this series we expand the check to apply to non-protected VMs to
> also restrict features that are not allowed in protected mode in
> general -- something that until this series we didn't have.
Ah, you are correct. Apologies for being so thick.
Still, I think we need to do something here -- the whole extension
check without context is just broken.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM
2025-11-26 15:36 ` Marc Zyngier
@ 2025-11-26 17:05 ` Fuad Tabba
0 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-26 17:05 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, oliver.upton, will, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, vladimir.murzin
On Wed, 26 Nov 2025 at 15:36, Marc Zyngier <maz@kernel.org> wrote:
>
> On Wed, 26 Nov 2025 11:00:47 +0000,
> Fuad Tabba <tabba@google.com> wrote:
> >
> > Hi Marc,
> >
> > I agree, but I don't think this patch changes this behavior. Later on
> > in this series we expand the check to apply to non-protected VMs to
> > also restrict features that are not allowed in protected mode in
> > general -- something that until this series we didn't have.
>
> Ah, you are correct. Apologies for being so thick.
>
> Still, I think we need to do something here -- the whole extension
> check without context is just broken.
I agree, but should we handle that in another series, since I don't
think that there's a straightfoward solution for this?
Cheers,
/fiad
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest in pKVM
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (4 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 5/9] KVM: arm64: Include VM type when checking VM capabilities in pKVM Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-18 10:38 ` [PATCH v5 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps Fuad Tabba
` (3 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
Supporting MTE in pKVM introduces significant complexity to the
hypervisor at EL2, even for non-protected VMs, since it would require
EL2 to handle tag management.
For now, do not allow KVM_CAP_ARM_MTE for all VM types in protected
mode.
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_pkvm.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 7195be508d99..5b564576160d 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -44,6 +44,8 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
case KVM_CAP_ARM_PTRAUTH_ADDRESS:
case KVM_CAP_ARM_PTRAUTH_GENERIC:
return true;
+ case KVM_CAP_ARM_MTE:
+ return false;
default:
return !kvm || !kvm_vm_is_protected(kvm);
}
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v5 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (5 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 6/9] KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest " Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-18 10:38 ` [PATCH v5 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM Fuad Tabba
` (2 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
Track KVM IOCTLs (VM IOCTLs for now), and the associated KVM capability
that enables that IOCTL. Add a function that performs the lookup.
This will be used by CoCo VM Hypervisors (e.g., pKVM) to determine
whether a particular KVM IOCTL is allowed for its VMs.
Suggested-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_host.h | 42 +++++++++++++++++++++++++++++++
include/uapi/linux/kvm.h | 1 +
2 files changed, 43 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 64302c438355..3ec2d4edd3b4 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1652,4 +1652,46 @@ static __always_inline enum fgt_group_id __fgt_reg_to_group_id(enum vcpu_sysreg
p; \
})
+/*
+ * Tracks KVM IOCTLs and their associated KVM capabilities.
+ */
+struct kvm_ioctl_cap_map {
+ unsigned int ioctl;
+ long ext;
+};
+
+/*
+ * Sorted by ioctl to allow for potential binary search,
+ * though linear scan is sufficient for this size.
+ */
+static const struct kvm_ioctl_cap_map vm_ioctl_caps[] = {
+ { KVM_CREATE_IRQCHIP, KVM_CAP_IRQCHIP },
+ { KVM_ARM_SET_DEVICE_ADDR, KVM_CAP_ARM_SET_DEVICE_ADDR },
+ { KVM_ARM_MTE_COPY_TAGS, KVM_CAP_ARM_MTE },
+ { KVM_SET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
+ { KVM_GET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
+ { KVM_HAS_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL },
+ { KVM_ARM_SET_COUNTER_OFFSET, KVM_CAP_COUNTER_OFFSET },
+ { KVM_ARM_GET_REG_WRITABLE_MASKS, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES },
+ { KVM_ARM_PREFERRED_TARGET, KVM_CAP_CORE },
+};
+
+/*
+ * Set *ext to the capability.
+ * Return 0 if found, or -EINVAL if no IOCTL matches.
+ */
+static inline long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vm_ioctl_caps); i++) {
+ if (vm_ioctl_caps[i].ioctl == ioctl) {
+ *ext = vm_ioctl_caps[i].ext;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 52f6000ab020..1f6e51234157 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -704,6 +704,7 @@ struct kvm_enable_cap {
/*
* Extension capability list.
*/
+#define KVM_CAP_CORE -1 /* represents core KVM capabilities */
#define KVM_CAP_IRQCHIP 0
#define KVM_CAP_HLT 1
#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v5 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (6 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 7/9] KVM: arm64: Track KVM IOCTLs and their associated KVM caps Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-18 10:38 ` [PATCH v5 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs Fuad Tabba
2025-11-18 10:39 ` [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
Certain VM IOCTLs are tied to specific VM features. Since pKVM does not
support all features, restrict which IOCTLs are allowed depending on
whether the associated feature is supported.
Use the existing VM capability check as the source of truth to whether
an IOCTL is allowed for a particular VM by mapping the IOCTLs with their
associated capabilities.
Suggested-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_pkvm.h | 21 +++++++++++++++++++++
arch/arm64/kvm/arm.c | 3 +++
2 files changed, 24 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index 5b564576160d..dcba7f99b88c 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -9,6 +9,7 @@
#include <linux/arm_ffa.h>
#include <linux/memblock.h>
#include <linux/scatterlist.h>
+#include <asm/kvm_host.h>
#include <asm/kvm_pgtable.h>
/* Maximum number of VMs that can co-exist under pKVM. */
@@ -31,6 +32,7 @@ int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu);
static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
{
switch (ext) {
+ case KVM_CAP_CORE:
case KVM_CAP_IRQCHIP:
case KVM_CAP_ARM_PSCI:
case KVM_CAP_ARM_PSCI_0_2:
@@ -51,6 +53,25 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext)
}
}
+/*
+ * Check whether the KVM VM IOCTL is allowed in pKVM.
+ *
+ * Certain features are allowed only for non-protected VMs in pKVM, which is why
+ * this takes the VM (kvm) as a parameter.
+ */
+static inline bool kvm_pkvm_ioctl_allowed(struct kvm *kvm, unsigned int ioctl)
+{
+ long ext;
+ int r;
+
+ r = kvm_get_cap_for_kvm_ioctl(ioctl, &ext);
+
+ if (WARN_ON_ONCE(r < 0))
+ return false;
+
+ return kvm_pkvm_ext_allowed(kvm, ext);
+}
+
extern struct memblock_region kvm_nvhe_sym(hyp_memory)[];
extern unsigned int kvm_nvhe_sym(hyp_memblock_nr);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 10d853f2722e..020cadd811a3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1879,6 +1879,9 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
void __user *argp = (void __user *)arg;
struct kvm_device_attr attr;
+ if (is_protected_kvm_enabled() && !kvm_pkvm_ioctl_allowed(kvm, ioctl))
+ return -EINVAL;
+
switch (ioctl) {
case KVM_CREATE_IRQCHIP: {
int ret;
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH v5 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (7 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 8/9] KVM: arm64: Check whether a VM IOCTL is allowed in pKVM Fuad Tabba
@ 2025-11-18 10:38 ` Fuad Tabba
2025-11-18 10:39 ` [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:38 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin, tabba
For protected VMs, the guest's timer offset state should not be
controlled by the host and must always run with a virtual counter offset
of 0. The existing timer logic allowed the host to set and manage the
timer counter offsets for protected VMs in certain cases.
Disable all host-side management of timer offsets for protected VMs by
adding checks in the relevant code paths.
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/arch_timer.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 3f675875abea..f5407301c8f9 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -1056,10 +1056,14 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
ctxt->timer_id = timerid;
- if (timerid == TIMER_VTIMER)
- ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
- else
- ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
+ if (!kvm_vm_is_protected(vcpu->kvm)) {
+ if (timerid == TIMER_VTIMER)
+ ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
+ else
+ ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset;
+ } else {
+ ctxt->offset.vm_offset = NULL;
+ }
hrtimer_setup(&ctxt->hrtimer, kvm_hrtimer_expire, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
@@ -1083,7 +1087,8 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
timer_context_init(vcpu, i);
/* Synchronize offsets across timers of a VM if not already provided */
- if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
+ if (!vcpu_is_protected(vcpu) &&
+ !test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read());
timer_set_offset(vcpu_ptimer(vcpu), 0);
}
@@ -1687,6 +1692,9 @@ int kvm_vm_ioctl_set_counter_offset(struct kvm *kvm,
if (offset->reserved)
return -EINVAL;
+ if (kvm_vm_is_protected(kvm))
+ return -EINVAL;
+
mutex_lock(&kvm->lock);
if (!kvm_trylock_all_vcpus(kvm)) {
--
2.52.0.rc1.455.g30608eb744-goog
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling
2025-11-18 10:37 [PATCH v5 0/9] KVM: arm64: Fixes for guest CPU feature trapping and enabling Fuad Tabba
` (8 preceding siblings ...)
2025-11-18 10:38 ` [PATCH v5 9/9] KVM: arm64: Prevent host from managing timer offsets for protected VMs Fuad Tabba
@ 2025-11-18 10:39 ` Fuad Tabba
9 siblings, 0 replies; 27+ messages in thread
From: Fuad Tabba @ 2025-11-18 10:39 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel
Cc: maz, oliver.upton, will, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, vladimir.murzin
On Tue, 18 Nov 2025 at 10:38, Fuad Tabba <tabba@google.com> wrote:
>
> Hi,
>
> This series contains several fixes for guest feature trapping and
> enabling, as well as a bit of tidying up.
>
> Changes from v3 [1]:
This should be
Changes from v4 [1]:
[1] https://lore.kernel.org/all/20251112092051.1376245-1-tabba@google.com/
Cheers,
/fuad
> - Add a map of KVM capabilities to IOCTLs (Oliver)
> - Based on Linux 6.18-rc6
>
> Cheers,
> /fuad
>
> [1] https://lore.kernel.org/all/20251110134525.3768197-1-tabba@google.com/
>
> Fuad Tabba (9):
> KVM: arm64: Fix Trace Buffer trapping for protected VMs
> KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
> KVM: arm64: Fix MTE flag initialization for protected VMs
> KVM: arm64: Introduce helper to calculate fault IPA offset
> KVM: arm64: Include VM type when checking VM capabilities in pKVM
> KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest in pKVM
> KVM: arm64: Track KVM IOCTLs and their associated KVM caps
> KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
> KVM: arm64: Prevent host from managing timer offsets for protected VMs
>
> arch/arm64/include/asm/kvm_arm.h | 2 ++
> arch/arm64/include/asm/kvm_host.h | 42 ++++++++++++++++++++++++
> arch/arm64/include/asm/kvm_pkvm.h | 33 ++++++++++++++++---
> arch/arm64/kvm/arch_timer.c | 18 +++++++---
> arch/arm64/kvm/arm.c | 7 ++--
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 18 +++++-----
> arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 2 +-
> arch/arm64/kvm/inject_fault.c | 2 +-
> arch/arm64/kvm/mmu.c | 4 +--
> include/uapi/linux/kvm.h | 1 +
> 10 files changed, 105 insertions(+), 24 deletions(-)
>
>
> base-commit: 6a23ae0a96a600d1d12557add110e0bb6e32730c
> --
> 2.52.0.rc1.455.g30608eb744-goog
>
^ permalink raw reply [flat|nested] 27+ messages in thread