[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] x86/hvm: Add Kconfig option to disable nested virtualization


  • To: Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Mon, 16 Feb 2026 10:08:39 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=KBFkYU5zO4LtipAAYY0sZcm+knroMLSl+ac7aDpY/3U=; b=ZQ1xZMQy84Zu3mvPshJuGe6GYg0NKPRW/7Wl1rYe0GqlEVZwCLqZm55e9TJm0NOwYCu4cRCr11tQZJyvCjNHYGqH2JYbei+F6K9galnKwzkQ44SfWpuIStaUe+Ya0WkvmIXItwA1kcTVHGHfGXXsThbhmZhAKqoaR5U/pxVtPsdUr50zmsfSBDxrUSKHYAWLWozI9UiPBjM9GEZqolfX/TY6SDt2sKLD3FEhNFuEJE7XjAyJ9j+FIxeP+hmW65+7T/JdCkleZ6JEAJNAzScJX9QjPlwg2ZWoPJcn8HLkp9PWjXk4IW1T6wzZmXrt/gvnDmEr4h4B1aptnaA0EhoP3Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DBB2rVK8YIjdTtJotLGZiKK/4Q9aDvrhRtZdPsLAzILkfa6ASbrGBNIr8oKnBpBRsplKjEG0SP0b+AxtZRxgWSHhHzD1jgpafUXiEDIZsGJc/rwa5PlEDjGKgOzV62nZYuJLG/YjYvOeuGCnvCfeh1JqeOvHxv3dRGh13xQsZYGqoXXRJGxNV96y0SecmnrEsGC+s3Ped3HssI5ObCrp8dJmKbRek8gPqr6jOg0ms45B4HysLlPrM0lG2IT0jOOB6FR9dFI1ps+DXQJ/eUlEynSdCcewFZ1tzzmaBqCA/8WafacOEMYlKy/nz3yOZA+yN+M09LkQGzNd5XgorUE+Xw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Stefano Stabellini <stefano.stabellini@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx, jbeulich@xxxxxxxx, andrew.cooper3@xxxxxxxxxx, jason.andryuk@xxxxxxx, alejandro.garciavallejo@xxxxxxx
  • Delivery-date: Mon, 16 Feb 2026 09:08:54 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Fri, Feb 13, 2026 at 01:56:34PM -0800, Stefano Stabellini wrote:
> I address all other comments
> 
> 
> On Mon, 9 Feb 2026, Roger Pau Monné wrote:
> > > +static inline int nvmx_msr_read_intercept(unsigned int msr, u64
> > > *msr_content)
> > > +{
> > > +    ASSERT_UNREACHABLE();
> > > +    return 0;
> > > +}
> > >
> > I think this function is reachable even when nested virt is not
> > enabled:
> > 
> > vmx_msr_read_intercept() -> case MSR_IA32_VMX_BASIC...MSR_IA32_VMX_VMFUNC 
> > -> nvmx_msr_read_intercept()
> > 
> > I'm also confused about why the function returns 0 instead of an error
> > when !nestedhvm_enabled().  We should probably make it return -ENODEV
> > when nested virt is not available or enabled.

Oh, I see.  The return type of that function is weird.  It should be
adjusted to bool (not that you need to do it here).

> I agree on the way of thinking but if we return zero it will goto gp_fault.
> So I'll just remove ASSERT_UNREACHABLE.

Ack.

> 
> > > +static inline int nvmx_handle_vmx_insn(struct cpu_user_regs *regs,
> > > +                                       unsigned int exit_reason)
> > > +{
> > > +    ASSERT_UNREACHABLE();
> > > +    return 0;
> > > +}
> > 
> > Same here, I think this is likely reachable from vmx_vmexit_handler(),
> > and shouldn't assert?
> > 
> > It should also do something like:
> > 
> >     hvm_inject_hw_exception(X86_EXC_UD, X86_EVENT_NO_EC);
> >     return X86EMUL_EXCEPTION;
> > 
> > So it mimics what the function itself does when !nestedhvm_enabled().
> 
> hvm_inject_hw_exception cannot be easily called here because it is not
> available at this point in the header. But actually this function should
> be unreachable because when !CONFIG_NESTED_VIRT, CR4.VMXE is not
> a valid guest CR4 bit, so nested VMX instructions should cause #UD?

I'm not sure about nvmx_handle_vmx_insn() being unreachable when
CR4.VMXE is not set, the Intel SDM states:

"26.1.2 Instructions That Cause VM Exits Unconditionally

The following instructions cause VM exits when they are executed in
VMX non-root operation: CPUID, GETSEC,1 INVD, and XSETBV. This is also
true of instructions introduced with VMX, which include: INVEPT,
INVVPID, VMCALL,2 VMCLEAR, VMLAUNCH, VMPTRLD, VMPTRST, VMRESUME,
VMXOFF, and VMXON."

My reading is that regardless of the value of CR4.VMXE the execution
of VMX instructions will cause a VMEXIT, and it's the hypervisor task
to figure out what to do.

> 
> I changed it to:
> 
> ASSERT_UNREACHABLE();
> return X86EMUL_EXCEPTION;

If the above is correct, the ASSERT_UNREACHABLE() is reachable.

Returning X86EMUL_EXCEPTION without actually having injected the
exception will result in a loop I think, as vmx_vmexit_handler() will
resume guest execution without having advanced the instruction
pointer, and without having injected an exception, and hence another
VMEXIT will trigger.

IMO the best way to solve this is to make vmx_vmexit_handler() inject
#UD when nvmx_handle_vmx_insn() returns X86EMUL_EXCEPTION. You will
need to then also adjust the non-stub version of
nvmx_handle_vmx_insn(), so it doesn't inject #UD itself.

Thanks, Roger.



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.