diff mbox series

KVM: arm64: nv: Forward hvc traps if originated from nested VM

Message ID 20250410070743.1072583-1-gankulkarni@os.amperecomputing.com (mailing list archive)
State New
Headers show
Series KVM: arm64: nv: Forward hvc traps if originated from nested VM | expand

Commit Message

Ganapatrao Kulkarni April 10, 2025, 7:07 a.m. UTC
It was discovered while trying selftest(smccc_filter) that the
hvc trap is getting forwarded to guest hypervisor even if it is
originated from itself.

HVC traps from guest hypervisor should be handled by the host
hypervisor and traps originating from nested VM should be
forwarded. Adding check to forward only if the hvc is trapped
from the nested VM.

Signed-off-by: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>
---
 arch/arm64/kvm/handle_exit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Marc Zyngier April 10, 2025, 7:19 a.m. UTC | #1
On Thu, 10 Apr 2025 08:07:43 +0100,
Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
> 
> It was discovered while trying selftest(smccc_filter) that the
> hvc trap is getting forwarded to guest hypervisor even if it is
> originated from itself.
> 
> HVC traps from guest hypervisor should be handled by the host
> hypervisor and traps originating from nested VM should be
> forwarded. Adding check to forward only if the hvc is trapped
> from the nested VM.

I disagree. HVC from EL2 must be routed to the same EL2. HVC from EL1
must be routed to the EL2 controlling EL1.

In no circumstances should HVC from a NV guest be directly handled by
the host hypervisor. That's what SMC is for.

Please read the pseudocode for HVC.

	M.
Ganapatrao Kulkarni April 10, 2025, 10:20 a.m. UTC | #2
On 10-04-2025 12:49 pm, Marc Zyngier wrote:
> On Thu, 10 Apr 2025 08:07:43 +0100,
> Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
>>
>> It was discovered while trying selftest(smccc_filter) that the
>> hvc trap is getting forwarded to guest hypervisor even if it is
>> originated from itself.
>>
>> HVC traps from guest hypervisor should be handled by the host
>> hypervisor and traps originating from nested VM should be
>> forwarded. Adding check to forward only if the hvc is trapped
>> from the nested VM.
> 
> I disagree. HVC from EL2 must be routed to the same EL2. HVC from EL1
> must be routed to the EL2 controlling EL1.

Thanks, Understood, In NV case, hvc has to be forwarded to L1 
irrespective of it origin (L1 or L2). Need to add hvc handler in the 
smccc_filter.c for the vm (when run as L1), so that it is handled and 
returns with required args set.
Marc Zyngier April 10, 2025, 10:52 a.m. UTC | #3
On Thu, 10 Apr 2025 11:20:24 +0100,
Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
> 
> 
> 
> On 10-04-2025 12:49 pm, Marc Zyngier wrote:
> > On Thu, 10 Apr 2025 08:07:43 +0100,
> > Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
> >> 
> >> It was discovered while trying selftest(smccc_filter) that the
> >> hvc trap is getting forwarded to guest hypervisor even if it is
> >> originated from itself.
> >> 
> >> HVC traps from guest hypervisor should be handled by the host
> >> hypervisor and traps originating from nested VM should be
> >> forwarded. Adding check to forward only if the hvc is trapped
> >> from the nested VM.
> > 
> > I disagree. HVC from EL2 must be routed to the same EL2. HVC from EL1
> > must be routed to the EL2 controlling EL1.
> 
> Thanks, Understood, In NV case, hvc has to be forwarded to L1
> irrespective of it origin (L1 or L2). Need to add hvc handler in the
> smccc_filter.c for the vm (when run as L1), so that it is handled and
> returns with required args set.

Why? This test checks under which conditions an HVC/SMC gets routed to
userspace. What does it even mean to test HVC if it doesn't make it
outside of the guest itself?

	M.
Ganapatrao Kulkarni April 10, 2025, 1:22 p.m. UTC | #4
On 10-04-2025 04:22 pm, Marc Zyngier wrote:
> On Thu, 10 Apr 2025 11:20:24 +0100,
> Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
>>
>>
>>
>> On 10-04-2025 12:49 pm, Marc Zyngier wrote:
>>> On Thu, 10 Apr 2025 08:07:43 +0100,
>>> Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
>>>>
>>>> It was discovered while trying selftest(smccc_filter) that the
>>>> hvc trap is getting forwarded to guest hypervisor even if it is
>>>> originated from itself.
>>>>
>>>> HVC traps from guest hypervisor should be handled by the host
>>>> hypervisor and traps originating from nested VM should be
>>>> forwarded. Adding check to forward only if the hvc is trapped
>>>> from the nested VM.
>>>
>>> I disagree. HVC from EL2 must be routed to the same EL2. HVC from EL1
>>> must be routed to the EL2 controlling EL1.
>>
>> Thanks, Understood, In NV case, hvc has to be forwarded to L1
>> irrespective of it origin (L1 or L2). Need to add hvc handler in the
>> smccc_filter.c for the vm (when run as L1), so that it is handled and
>> returns with required args set.
> 
> Why? This test checks under which conditions an HVC/SMC gets routed to
> userspace. What does it even mean to test HVC if it doesn't make it
> outside of the guest itself?

smccc_filter.c has 2 tests (test_filter_denied and 
test_filter_fwd_to_user), which runs the vm(guest_code).

I was trying to modify test_filter_denied to run in vEL2, which led to 
this patch/discussion. I agree, it does not makes sense to run this test 
for vEL2.

test_filter_fwd_to_user is not feasible to run in vEL2.
Thanks for the feedback.

BTW, I could add hvc handler and run test_filter_denied in vEL2.
Oliver Upton April 10, 2025, 5:31 p.m. UTC | #5
On Thu, Apr 10, 2025 at 06:52:45PM +0530, Ganapatrao Kulkarni wrote:
> 
> 
> On 10-04-2025 04:22 pm, Marc Zyngier wrote:
> > On Thu, 10 Apr 2025 11:20:24 +0100,
> > Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
> > > 
> > > 
> > > 
> > > On 10-04-2025 12:49 pm, Marc Zyngier wrote:
> > > > On Thu, 10 Apr 2025 08:07:43 +0100,
> > > > Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> wrote:
> > > > > 
> > > > > It was discovered while trying selftest(smccc_filter) that the
> > > > > hvc trap is getting forwarded to guest hypervisor even if it is
> > > > > originated from itself.
> > > > > 
> > > > > HVC traps from guest hypervisor should be handled by the host
> > > > > hypervisor and traps originating from nested VM should be
> > > > > forwarded. Adding check to forward only if the hvc is trapped
> > > > > from the nested VM.
> > > > 
> > > > I disagree. HVC from EL2 must be routed to the same EL2. HVC from EL1
> > > > must be routed to the EL2 controlling EL1.
> > > 
> > > Thanks, Understood, In NV case, hvc has to be forwarded to L1
> > > irrespective of it origin (L1 or L2). Need to add hvc handler in the
> > > smccc_filter.c for the vm (when run as L1), so that it is handled and
> > > returns with required args set.
> > 
> > Why? This test checks under which conditions an HVC/SMC gets routed to
> > userspace. What does it even mean to test HVC if it doesn't make it
> > outside of the guest itself?
> 
> smccc_filter.c has 2 tests (test_filter_denied and test_filter_fwd_to_user),
> which runs the vm(guest_code).
> 
> I was trying to modify test_filter_denied to run in vEL2, which led to this
> patch/discussion. I agree, it does not makes sense to run this test for
> vEL2.
> 
> test_filter_fwd_to_user is not feasible to run in vEL2.
> Thanks for the feedback.
> 
> BTW, I could add hvc handler and run test_filter_denied in vEL2.

I would much prefer that the entire test be adapted to consider the EL of
the guest, only testing the behavior of SMCs for EL2.

Thanks,
Oliver
diff mbox series

Patch

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 80218f62773b..894f92693ed9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -40,8 +40,8 @@  static int handle_hvc(struct kvm_vcpu *vcpu)
 			    kvm_vcpu_hvc_get_imm(vcpu));
 	vcpu->stat.hvc_exit_stat++;
 
-	/* Forward hvc instructions to the virtual EL2 if the guest has EL2. */
-	if (vcpu_has_nv(vcpu)) {
+	/* Forward hvc instructions to the virtual EL2, if it is from nested VM. */
+	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
 		if (vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_HCD)
 			kvm_inject_undefined(vcpu);
 		else