Linux-HyperV List
 help / color / mirror / Atom feed
* [RFC Patch v2 1/4] x86/Hyper-V: Not use hv apic driver when Secure AVIC is available
From: Tianyu Lan @ 2025-06-13 11:08 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
	hpa, kvijayab, Neeraj.Upadhyay
  Cc: Tianyu Lan, linux-hyperv, linux-kernel
In-Reply-To: <20250613110829.122371-1-ltykernel@gmail.com>

From: Tianyu Lan <tiala@microsoft.com>

When Secure AVIC is available, AMD x2apic Secure
AVIC driver should be selected and return directly
in the hv_apic_init().

Signed-off-by: Tianyu Lan <tiala@microsoft.com>
---
 arch/x86/hyperv/hv_apic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index bfde0a3498b9..1c48396e5389 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -293,6 +293,9 @@ static void hv_send_ipi_self(int vector)
 
 void __init hv_apic_init(void)
 {
+       if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+               return;
+
 	if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
 		pr_info("Hyper-V: Using IPI hypercalls\n");
 		/*
-- 
2.25.1


^ permalink raw reply related

* [RFC Patch v2 0/4] x86/Hyper-V: Add AMD Secure AVIC for Hyper-V platform
From: Tianyu Lan @ 2025-06-13 11:08 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
	hpa, kvijayab, Neeraj.Upadhyay
  Cc: Tianyu Lan, linux-hyperv, linux-kernel

From: Tianyu Lan <tiala@microsoft.com>

Secure AVIC is a new hardware feature in the AMD64
architecture to allow SEV-SNP guests to prevent the
hypervisor from generating unexpected interrupts to
a vCPU or otherwise violate architectural assumptions
around APIC behavior.

Each vCPU has a guest-allocated APIC backing page of
size 4K, which maintains APIC state for that vCPU.
APIC backing page's ALLOWED_IRR field indicates the
interrupt vectors which the guest allows the hypervisor
to send.

This patchset is to enable the feature for Hyper-V
platform. Patch "Expose x2apic_savic_update_vector()"
is to expose new fucntion and device driver and arch
code may update AVIC backing page ALLOWED_IRR field to
allow Hyper-V inject associated vector.

This patchset is based on the AMD patchset "AMD: Add
Secure AVIC Guest Support"
https://lkml.org/lkml/2025/6/10/1579

Change since v1:
       - Remove the check of Secure AVIC when set APIC backing page
       - Use apic_update_vector() instead of exposing new interface
       from Secure AVIC driver to update APIC backing page and allow
       associated interrupt to be injected by hypervisor.

Tianyu Lan (4):
  x86/Hyper-V: Not use hv apic driver when Secure AVIC is available
  drivers/hv: Allow vmbus message synic interrupt injected from Hyper-V
  x86/Hyper-V: Not use auto-eoi when Secure AVIC is available
  x86/Hyper-V: Allow Hyper-V to inject Hyper-V vectors

 arch/x86/hyperv/hv_apic.c      | 3 +++
 arch/x86/hyperv/hv_init.c      | 4 ++++
 arch/x86/kernel/cpu/mshyperv.c | 2 ++
 drivers/hv/hv.c                | 2 ++
 4 files changed, 11 insertions(+)

-- 
2.25.1

^ permalink raw reply

* [PATCH v4 0/1] tools/hv: Fix incorrect file path conversion in fcopy
From: yasuenag @ 2025-06-13 10:46 UTC (permalink / raw)
  To: namjain
  Cc: eahariha, kys, haiyangz, wei.liu, decui, linux-hyperv, ssengar,
	Yasumasa Suenaga

From: Yasumasa Suenaga <yasuenag@gmail.com>

Hi,

Thanks a lot for your comment! I updated my patch:

  - Update loop condition to exit in wcstoutf8() if NUL char is found
  - Add new syslog message when the path length exceeds MAX_PATH
  - Revise both subject and commit message

Can you review again? Comments are welcome.


Thanks,

Yasumasa


Yasumasa Suenaga (1):
  tools/hv: Fix incorrect file path conversion in fcopy on Linux

 tools/hv/hv_fcopy_uio_daemon.c | 37 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

-- 
2.49.0


^ permalink raw reply

* [PATCH v4 1/1] tools/hv: Fix incorrect file path conversion in fcopy on Linux
From: yasuenag @ 2025-06-13 10:46 UTC (permalink / raw)
  To: namjain
  Cc: eahariha, kys, haiyangz, wei.liu, decui, linux-hyperv, ssengar,
	Yasumasa Suenaga
In-Reply-To: <20250613104648.1212-1-yasuenag@gmail.com>

From: Yasumasa Suenaga <yasuenag@gmail.com>

The hv_fcopy_uio_daemon fails to correctly handle file copy requests
from Windows hosts (e.g. via Copy-VMFile) due to wchar_t size
differences between Windows and Linux. On Linux, wchar_t is 32 bit,
whereas Windows uses 16 bit wide characters.

Currently, the code casts __u16 arrays directly to wchar_t* and
uses wcstombs(), which leads to corrupted file paths or even crashes.

This patch changes:
- Treats file name and path as __u16 arrays, not wchar_t*.
- Allocates fixed-size buffers (W_MAX_PATH) for converted strings
  instead of using malloc.
- Adds a check for target path length to prevent snprintf() buffer
  overflow.

This change ensures file transfers from host to Linux guest succeed
with correctly decoded file names and paths.

Signed-off-by: Yasumasa Suenaga <yasuenag@gmail.com>
---
 tools/hv/hv_fcopy_uio_daemon.c | 37 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/tools/hv/hv_fcopy_uio_daemon.c b/tools/hv/hv_fcopy_uio_daemon.c
index 0198321d1..4b09ed6b6 100644
--- a/tools/hv/hv_fcopy_uio_daemon.c
+++ b/tools/hv/hv_fcopy_uio_daemon.c
@@ -62,8 +62,11 @@ static int hv_fcopy_create_file(char *file_name, char *path_name, __u32 flags)
 
 	filesize = 0;
 	p = path_name;
-	snprintf(target_fname, sizeof(target_fname), "%s/%s",
-		 path_name, file_name);
+	if (snprintf(target_fname, sizeof(target_fname), "%s/%s",
+		     path_name, file_name) >= sizeof(target_fname)) {
+		syslog(LOG_ERR, "target file name is too long: %s/%s", path_name, file_name);
+		goto done;
+	}
 
 	/*
 	 * Check to see if the path is already in place; if not,
@@ -270,7 +273,7 @@ static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
 {
 	size_t len = 0;
 
-	while (len < dest_size) {
+	while (len < dest_size && *src) {
 		if (src[len] < 0x80)
 			dest[len++] = (char)(*src++);
 		else
@@ -282,27 +285,15 @@ static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
 
 static int hv_fcopy_start(struct hv_start_fcopy *smsg_in)
 {
-	setlocale(LC_ALL, "en_US.utf8");
-	size_t file_size, path_size;
-	char *file_name, *path_name;
-	char *in_file_name = (char *)smsg_in->file_name;
-	char *in_path_name = (char *)smsg_in->path_name;
-
-	file_size = wcstombs(NULL, (const wchar_t *restrict)in_file_name, 0) + 1;
-	path_size = wcstombs(NULL, (const wchar_t *restrict)in_path_name, 0) + 1;
-
-	file_name = (char *)malloc(file_size * sizeof(char));
-	path_name = (char *)malloc(path_size * sizeof(char));
-
-	if (!file_name || !path_name) {
-		free(file_name);
-		free(path_name);
-		syslog(LOG_ERR, "Can't allocate memory for file name and/or path name");
-		return HV_E_FAIL;
-	}
+	/*
+	 * file_name and path_name should have same length with appropriate
+	 * member of hv_start_fcopy.
+	 */
+	char file_name[W_MAX_PATH], path_name[W_MAX_PATH];
 
-	wcstoutf8(file_name, (__u16 *)in_file_name, file_size);
-	wcstoutf8(path_name, (__u16 *)in_path_name, path_size);
+	setlocale(LC_ALL, "en_US.utf8");
+	wcstoutf8(file_name, smsg_in->file_name, W_MAX_PATH - 1);
+	wcstoutf8(path_name, smsg_in->path_name, W_MAX_PATH - 1);
 
 	return hv_fcopy_create_file(file_name, path_name, smsg_in->copy_flags);
 }
-- 
2.49.0


^ permalink raw reply related

* Re: [PATCH net-next 4/4] net: mana: Handle unsupported HWC commands
From: Erni Sri Satya Vennela @ 2025-06-13 10:12 UTC (permalink / raw)
  To: Dipayaan Roy
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, kotaranov, longli, horms, shirazsaleem, leon,
	shradhagupta, schakrabarti, rosenp, sdf, linux-hyperv, netdev,
	linux-kernel, linux-rdma
In-Reply-To: <20250611113539.GB4690@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>

On Wed, Jun 11, 2025 at 04:35:39AM -0700, Dipayaan Roy wrote:
> On Wed, Jun 11, 2025 at 01:46:16AM -0700, Erni Sri Satya Vennela wrote:
> > If any of the HWC commands are not recognized by the
> > underlying hardware, the hardware returns the response
> > header status of -1. Log the information using
> > netdev_info_once to avoid multiple error logs in dmesg.
> > 
> > Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> > ---
> >  drivers/net/ethernet/microsoft/mana/hw_channel.c |  4 ++++
> >  drivers/net/ethernet/microsoft/mana/mana_en.c    | 11 +++++++++++
> >  2 files changed, 15 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> > index a8c4d8db75a5..70c3b57b1e75 100644
> > --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> > +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> > @@ -890,6 +890,10 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
> >  	}
> >  
> >  	if (ctx->status_code && ctx->status_code != GDMA_STATUS_MORE_ENTRIES) {
> > +		if (ctx->status_code == -1) {
> Minor comment: instead of == -1 could use some macro like GDMA_STATUS_CMD_UNSUPPORTED, rest LGTM.
Thankyou Dipayaan.
I'll define this macro and us it for the next version.
> 
> Reviewed-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>

^ permalink raw reply

* Re: [PATCH net-next 1/4] net: mana: Fix potential deadlocks in mana napi ops
From: Erni Sri Satya Vennela @ 2025-06-13 10:10 UTC (permalink / raw)
  To: Long Li
  Cc: Saurabh Singh Sengar, KY Srinivasan, Haiyang Zhang,
	wei.liu@kernel.org, Dexuan Cui, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, Konstantin Taranov, horms@kernel.org,
	Shiraz Saleem, leon@kernel.org, shradhagupta@linux.microsoft.com,
	schakrabarti@linux.microsoft.com, rosenp@gmail.com,
	sdf@fomichev.me, linux-hyperv@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-rdma@vger.kernel.org
In-Reply-To: <LV2PR21MB33009692C01762F9BCF06D98CE75A@LV2PR21MB3300.namprd21.prod.outlook.com>

On Wed, Jun 11, 2025 at 05:36:51PM +0000, Long Li wrote:
> > Subject: Re: [PATCH net-next 1/4] net: mana: Fix potential deadlocks in mana
> > napi ops
> > 
> > On Wed, Jun 11, 2025 at 04:03:52AM -0700, Saurabh Singh Sengar wrote:
> > > On Wed, Jun 11, 2025 at 01:46:13AM -0700, Erni Sri Satya Vennela wrote:
> > > > When net_shaper_ops are enabled for MANA, netdev_ops_lock becomes
> > > > active.
> > > >
> > > > The netvsc sets up MANA VF via following call chain:
> > > >
> > > > netvsc_vf_setup()
> > > >         dev_change_flags()
> > > > 		...
> > > >          __dev_open() OR __dev_close()
> > > >
> > > > dev_change_flags() holds the netdev mutex via netdev_lock_ops.
> > > >
> > > > During this process, mana_create_txq() and mana_create_rxq() invoke
> > > > netif_napi_add_tx(), netif_napi_add_weight(), and napi_enable(), all
> > > > of which attempt to acquire the same lock, leading to a potential
> > > > deadlock.
> > >
> > > commit message could be better oriented.
> > >
> > > >
> > > > Similarly, mana_destroy_txq() and mana_destroy_rxq() call
> > > > netif_napi_disable() and netif_napi_del(), which also contend for
> > > > the same lock.
> > > >
> > > > Switch to the _locked variants of these APIs to avoid deadlocks when
> > > > the netdev_ops_lock is held.
> > > >
> > > > Fixes: d4c22ec680c8 ("net: hold netdev instance lock during
> > > > ndo_open/ndo_stop")
> > > > Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> > > > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> > > > ---
> > > >  drivers/net/ethernet/microsoft/mana/mana_en.c | 39
> > > > ++++++++++++++-----
> > > >  1 file changed, 30 insertions(+), 9 deletions(-)
> > > >
> > > > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > > b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > > index ccd2885c939e..3c879d8a39e3 100644
> > > > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > > @@ -1911,8 +1911,13 @@ static void mana_destroy_txq(struct
> > mana_port_context *apc)
> > > >  		napi = &apc->tx_qp[i].tx_cq.napi;
> > > >  		if (apc->tx_qp[i].txq.napi_initialized) {
> > > >  			napi_synchronize(napi);
> > > > -			napi_disable(napi);
> > > > -			netif_napi_del(napi);
> > > > +			if (netdev_need_ops_lock(napi->dev)) {
> > > > +				napi_disable_locked(napi);
> > > > +				netif_napi_del_locked(napi);
> > > > +			} else {
> > > > +				napi_disable(napi);
> > > > +				netif_napi_del(napi);
> > > > +			}
> > >
> > > Instead of using if-else, we can used netdev_lock_ops(), followed by *_locked
> > api-s.
> > > Same for rest of the patch.
> > >
> > 
> > I later realized that what we actually need is:
> > 
> >   if (!netdev_need_ops_lock(napi->dev))
> > 	netdev_lock(dev);
> > 
> > not
> > 
> >   if (netdev_need_ops_lock(napi->dev))
> >         netdev_lock(dev);
> > 
> > Hence, netdev_lock_ops() is not appropriate. Instead, netdev_lock_ops_to_full()
> > seems to be a better choice.
> 
> Yes, netdev_lock_ops_to_full() seems better

Thankyou, Saurabh and Long, for the suggestion. I'll make sure to
incorporate this API in my next version.

> Long

^ permalink raw reply

* Re: [PATCH v4] hv/hv_kvp_daemon: Enable debug logs for hv_kvp_daemon
From: Shradha Gupta @ 2025-06-13  9:53 UTC (permalink / raw)
  To: Olaf Hering
  Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Naman Jain,
	linux-hyperv, Shradha Gupta
In-Reply-To: <20250612175318.3a794cf2.olaf@aepfle.de>

On Thu, Jun 12, 2025 at 05:54:01PM +0200, Olaf Hering wrote:
> Tue, 15 Apr 2025 04:19:38 -0700 Shradha Gupta <shradhagupta@linux.microsoft.com>:
> 
> >  static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
> > +	if (debug)
> > +		syslog(LOG_DEBUG, "%s: got a KVP: pool=%d key=%s val=%s",
> > +		       __func__, pool, key, value);
> >  
> >  	if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
> > -		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
> > +		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
> > +		syslog(LOG_ERR, "%s: Too long key or value: key=%s, val=%s",
> > +		       __func__, key, value);
> > +
> > +		if (debug)
> > +			syslog(LOG_DEBUG, "%s: Too long key or value: pool=%d, key=%s, val=%s",
> > +			       __func__, pool, key, value);
> >  		return 1;
> > +	}
> 
> I think this is logging three times in case of an error.
> Maybe move the debug case after the size check, and change the LOG_ERR case to show all details just once?
> 
> 
> Olaf

Thanks Olaf. That makes sense. Let me send out another patch to address
this.


^ permalink raw reply

* Re: [PATCH net-next,v7] net: mana: Add handler for hardware servicing events
From: Jakub Kicinski @ 2025-06-13  1:21 UTC (permalink / raw)
  To: Haiyang Zhang
  Cc: linux-hyperv, netdev, haiyangz, decui, stephen, kys, paulros,
	olaf, vkuznets, davem, wei.liu, edumazet, pabeni, leon, longli,
	ssengar, linux-rdma, daniel, john.fastabend, bpf, ast, hawk, tglx,
	shradhagupta, andrew+netdev, kotaranov, horms, linux-kernel
In-Reply-To: <1749580942-17671-1-git-send-email-haiyangz@linux.microsoft.com>

On Tue, 10 Jun 2025 11:42:22 -0700 Haiyang Zhang wrote:
> v6:
> Not acquiring module refcnt as suggested by Paolo Abeni.

TBH I'm not 100% sure this is correct.
If the service worker operations end up unbinding the driver from
the device holding the device ref may not prevent the module from
being unloaded.

Could you try to trigger that condition? Make that msleep() in the work
even longer and try to remove the module while the work is sleeping
there?

^ permalink raw reply

* Re: [PATCH v4] hv/hv_kvp_daemon: Enable debug logs for hv_kvp_daemon
From: Olaf Hering @ 2025-06-12 15:54 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Naman Jain,
	linux-hyperv, Shradha Gupta
In-Reply-To: <1744715978-8185-1-git-send-email-shradhagupta@linux.microsoft.com>

[-- Attachment #1: Type: text/plain, Size: 900 bytes --]

Tue, 15 Apr 2025 04:19:38 -0700 Shradha Gupta <shradhagupta@linux.microsoft.com>:

>  static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
> +	if (debug)
> +		syslog(LOG_DEBUG, "%s: got a KVP: pool=%d key=%s val=%s",
> +		       __func__, pool, key, value);
>  
>  	if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
> -		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
> +		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
> +		syslog(LOG_ERR, "%s: Too long key or value: key=%s, val=%s",
> +		       __func__, key, value);
> +
> +		if (debug)
> +			syslog(LOG_DEBUG, "%s: Too long key or value: pool=%d, key=%s, val=%s",
> +			       __func__, pool, key, value);
>  		return 1;
> +	}

I think this is logging three times in case of an error.
Maybe move the debug case after the size check, and change the LOG_ERR case to show all details just once?


Olaf

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] x86: Fix build warnings about export.h
From: Naman Jain @ 2025-06-12  9:57 UTC (permalink / raw)
  To: Zhenghan Cheng, herbert, davem, peterz, acme, namhyung, kys,
	haiyangz, wei.liu, decui, rafael, jgross, Jason, mhiramat,
	ebiggers, masahiroy
  Cc: linux-kernel, mark.rutland, alexander.shishkin, jolsa, irogers,
	adrian.hunter, kan.liang, lenb, ajay.kaher, alexey.makhalov,
	bcm-kernel-feedback-list, ppaalanen, boris.ostrovsky, nathan,
	nicolas, ilpo.jarvinen, usamaarif642, ubizjat, dyoung,
	myrrhperiwinkle, guoweikang.kernel, graf, chao.gao,
	chang.seok.bae, sohil.mehta, vigbalas, aruna.ramakrishna,
	zhangkunbo, fvdl, gatlin.newhouse, snovitoll, bjohannesmeyer,
	glider, david, lorenzo.stoakes, Liam.Howlett, shivankg, peterx,
	dan.j.williams, dave.jiang, kevin.brodsky, willy, linux,
	Neeraj.Upadhyay, wangyuli, linux-crypto, linux-perf-users,
	linux-hyperv, linux-acpi, linux-pci, linux-efi, linux-kbuild,
	Huacai Chen, Zhenghan Cheng
In-Reply-To: <20250612093021.7187-1-chengzhenghan@uniontech.com>



On 6/12/2025 3:00 PM, Zhenghan Cheng wrote:
> After commit a934a57a42f64a4 ("scripts/misc-check:
> check missing #include <linux/export.h> when W=1")
> and commit 7d95680d64ac8e836c ("scripts/misc-check:
> check unnecessary #include <linux/export.h> when W=1"),
> we get some build warnings with W=1,such as:
> 
> arch/x86/coco/sev/core.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
> arch/x86/crypto/aria_aesni_avx2_glue.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
> arch/x86/kernel/unwind_orc.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
> arch/x86/kvm/hyperv.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
> arch/x86/events/intel/core.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
> arch/x86/events/zhaoxin/core.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
> arch/x86/kernel/crash.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
> arch/x86/kernel/devicetree.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
> 
> so fix these build warnings for x86.
> 
> Signed-off-by: "Zhenghan Cheng" <chengzhenghan@uniontech.com>
> Suggested-by: "Huacai Chen" <chenhuacai@loongson.cn>
> 


Thanks for sharing.

FYI, I sent a patch to fix these warnings in Hyper-V related drivers
here:
https://lore.kernel.org/all/20250611100459.92900-1-namjain@linux.microsoft.com/

Some of the files are common to the ones in your patch.

Regards,
Naman



^ permalink raw reply

* [PATCH] x86: Fix build warnings about export.h
From: Zhenghan Cheng @ 2025-06-12  9:30 UTC (permalink / raw)
  To: herbert, davem, peterz, acme, namhyung, kys, haiyangz, wei.liu,
	decui, rafael, jgross, Jason, mhiramat, ebiggers, masahiroy
  Cc: linux-kernel, mark.rutland, alexander.shishkin, jolsa, irogers,
	adrian.hunter, kan.liang, lenb, ajay.kaher, alexey.makhalov,
	bcm-kernel-feedback-list, ppaalanen, boris.ostrovsky, nathan,
	nicolas, ilpo.jarvinen, usamaarif642, ubizjat, dyoung,
	myrrhperiwinkle, guoweikang.kernel, graf, chao.gao,
	chang.seok.bae, sohil.mehta, vigbalas, aruna.ramakrishna,
	zhangkunbo, fvdl, gatlin.newhouse, snovitoll, bjohannesmeyer,
	glider, david, lorenzo.stoakes, Liam.Howlett, shivankg, peterx,
	dan.j.williams, dave.jiang, kevin.brodsky, willy, linux,
	Neeraj.Upadhyay, chengzhenghan, wangyuli, linux-crypto,
	linux-perf-users, linux-hyperv, linux-acpi, linux-pci, linux-efi,
	linux-kbuild, Huacai Chen, Zhenghan Cheng

After commit a934a57a42f64a4 ("scripts/misc-check:
check missing #include <linux/export.h> when W=1")
and commit 7d95680d64ac8e836c ("scripts/misc-check:
check unnecessary #include <linux/export.h> when W=1"),
we get some build warnings with W=1,such as:

arch/x86/coco/sev/core.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
arch/x86/crypto/aria_aesni_avx2_glue.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
arch/x86/kernel/unwind_orc.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
arch/x86/kvm/hyperv.c: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
arch/x86/events/intel/core.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
arch/x86/events/zhaoxin/core.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
arch/x86/kernel/crash.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present
arch/x86/kernel/devicetree.c: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present

so fix these build warnings for x86.

Signed-off-by: "Zhenghan Cheng" <chengzhenghan@uniontech.com>
Suggested-by: "Huacai Chen" <chenhuacai@loongson.cn>

diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index b6db4e0b936b..773b24859037 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/psp-sev.h>
 #include <linux/dmi.h>
+#include <linux/export.h>
 #include <uapi/linux/sev-guest.h>
 #include <crypto/gcm.h>

diff --git a/arch/x86/crypto/aria_aesni_avx2_glue.c b/arch/x86/crypto/aria_aesni_avx2_glue.c
index b4bddcd58457..007b250f774c 100644
--- a/arch/x86/crypto/aria_aesni_avx2_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx2_glue.c
@@ -9,6 +9,7 @@
 #include <crypto/aria.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/types.h>

diff --git a/arch/x86/crypto/aria_aesni_avx_glue.c b/arch/x86/crypto/aria_aesni_avx_glue.c
index ab9b38d05332..4c88ef4eba82 100644
--- a/arch/x86/crypto/aria_aesni_avx_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx_glue.c
@@ -9,6 +9,7 @@
 #include <crypto/aria.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/types.h>

diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c
index a7d162388142..5c321f255eb7 100644
--- a/arch/x86/crypto/camellia_aesni_avx_glue.c
+++ b/arch/x86/crypto/camellia_aesni_avx_glue.c
@@ -8,6 +8,7 @@
 #include <crypto/algapi.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/types.h>

diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c
index 3bd37d664121..cbede120e5f2 100644
--- a/arch/x86/crypto/camellia_glue.c
+++ b/arch/x86/crypto/camellia_glue.c
@@ -10,6 +10,7 @@

 #include <linux/unaligned.h>
 #include <linux/crypto.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c
index dcfc0de333de..86d4c4d85487 100644
--- a/arch/x86/crypto/curve25519-x86_64.c
+++ b/arch/x86/crypto/curve25519-x86_64.c
@@ -8,6 +8,7 @@
 #include <crypto/internal/kpp.h>

 #include <linux/types.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c
index e640abc1cb8a..9c8b3a335d5c 100644
--- a/arch/x86/crypto/serpent_avx_glue.c
+++ b/arch/x86/crypto/serpent_avx_glue.c
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <crypto/algapi.h>
 #include <crypto/serpent.h>

diff --git a/arch/x86/crypto/sm4_aesni_avx_glue.c b/arch/x86/crypto/sm4_aesni_avx_glue.c
index 72867fc49ce8..88caf418a06f 100644
--- a/arch/x86/crypto/sm4_aesni_avx_glue.c
+++ b/arch/x86/crypto/sm4_aesni_avx_glue.c
@@ -11,6 +11,7 @@
 #include <asm/fpu/api.h>
 #include <linux/module.h>
 #include <linux/crypto.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/sm4.h>
diff --git a/arch/x86/crypto/twofish_glue.c b/arch/x86/crypto/twofish_glue.c
index 4c67184dc573..8e9906d36902 100644
--- a/arch/x86/crypto/twofish_glue.c
+++ b/arch/x86/crypto/twofish_glue.c
@@ -40,6 +40,7 @@

 #include <crypto/algapi.h>
 #include <crypto/twofish.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 1a1ecfa7f72a..8ad77725bf60 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -9,6 +9,7 @@
 #include <crypto/algapi.h>
 #include <crypto/twofish.h>
 #include <linux/crypto.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 741b229f0718..04cf3d1019d9 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -12,7 +12,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/export.h>
 #include <linux/nmi.h>
 #include <linux/kvm_host.h>

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 7aa59966e7c3..10619c767602 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/perf_event.h>
+#include <linux/export.h>
 #include <linux/types.h>

 #include <asm/cpu_device_id.h>
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index e8cf29d2b10c..9c772c89b623 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -17,6 +17,8 @@
 #include <linux/limits.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/export.h>
+

 #include <asm/cpuid/api.h>
 #include <asm/perf_event.h>
diff --git a/arch/x86/events/zhaoxin/core.c b/arch/x86/events/zhaoxin/core.c
index 4bdfcf091200..67fa000cf372 100644
--- a/arch/x86/events/zhaoxin/core.c
+++ b/arch/x86/events/zhaoxin/core.c
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/export.h>
 #include <linux/nmi.h>

 #include <asm/cpufeature.h>
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 3d1d3547095a..3bd18521cd46 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -29,6 +29,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/cpuhotplug.h>
 #include <linux/syscore_ops.h>
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index 31f0d29cbc5e..f7627bc8fe49 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -10,6 +10,7 @@

 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <linux/export.h>
 #include <asm/mshyperv.h>

 static int hv_map_interrupt(union hv_device_id device_id, bool level,
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index e93a2f488ff7..d9c0b3064222 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -7,6 +7,7 @@
  */

 #include <linux/bitfield.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/cpu.h>
diff --git a/arch/x86/hyperv/nested.c b/arch/x86/hyperv/nested.c
index 1083dc8646f9..1413bfe40ea9 100644
--- a/arch/x86/hyperv/nested.c
+++ b/arch/x86/hyperv/nested.c
@@ -9,7 +9,7 @@
  */
 #define pr_fmt(fmt)  "Hyper-V: " fmt

-
+#include <linux/export.h>
 #include <linux/types.h>
 #include <hyperv/hvhdk.h>
 #include <asm/mshyperv.h>
diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
index 7047124490f6..e943947ccb3d 100644
--- a/arch/x86/kernel/acpi/cppc.c
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -5,6 +5,7 @@
  */

 #include <linux/bitfield.h>
+#include <linux/export.h>

 #include <acpi/cppc_acpi.h>
 #include <asm/msr.h>
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index ecfe7b497cad..882d99b1f4fb 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -6,6 +6,7 @@
 #include <linux/vmalloc.h>
 #include <linux/memory.h>
 #include <linux/execmem.h>
+#include <linux/export.h>

 #include <asm/text-patching.h>
 #include <asm/insn.h>
diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index a40176b62eb5..55118dd87116 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -9,6 +9,7 @@
  */

 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <asm/amd/node.h>

 /*
diff --git a/arch/x86/kernel/apic/apic_common.c b/arch/x86/kernel/apic/apic_common.c
index 9ef3be866832..f7e1cbb70029 100644
--- a/arch/x86/kernel/apic/apic_common.c
+++ b/arch/x86/kernel/apic/apic_common.c
@@ -3,6 +3,7 @@
  *
  * SPDX-License-Identifier: GPL-2.0
  */
+#include <linux/export.h>
 #include <linux/irq.h>
 #include <asm/apic.h>

diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 66bc5d3e79db..3f133e24a38e 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -14,6 +14,7 @@
 #include <linux/dmar.h>
 #include <linux/hpet.h>
 #include <linux/msi.h>
+#include <linux/export.h>
 #include <asm/irqdomain.h>
 #include <asm/hpet.h>
 #include <asm/hw_irq.h>
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 93069b13d3af..f35c9184ac30 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/compiler.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/irqdomain.h>
 #include <asm/hw_irq.h>
 #include <asm/traps.h>
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 2c5b51aad91a..8f181da43b20 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -10,6 +10,7 @@
  */

 #include <linux/interrupt.h>
+#include <linux/export.h>

 #include <asm/acrn.h>
 #include <asm/apic.h>
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index a315b0627dfb..e441400106f8 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -8,6 +8,7 @@
  */
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/ktime.h>
 #include <linux/math64.h>
 #include <linux/percpu.h>
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 7f94e6a5497d..fd136016ff8f 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -16,6 +16,7 @@
 #include <linux/sched/smt.h>
 #include <linux/pgtable.h>
 #include <linux/bpf.h>
+#include <linux/export.h>

 #include <asm/spec-ctrl.h>
 #include <asm/cmdline.h>
diff --git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/kernel/cpu/bus_lock.c
index 981f8b1f0792..68105db4dc66 100644
--- a/arch/x86/kernel/cpu/bus_lock.c
+++ b/arch/x86/kernel/cpu/bus_lock.c
@@ -6,6 +6,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/cpuhotplug.h>
+#include <linux/export.h>
 #include <asm/cpu_device_id.h>
 #include <asm/cmdline.h>
 #include <asm/traps.h>
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 9d852c3b2cb5..9b335a939576 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -8,6 +8,7 @@
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/kobject.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c
index 8d023239ce18..4657fdb4810e 100644
--- a/arch/x86/kernel/cpu/mce/dev-mcelog.c
+++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c
@@ -10,6 +10,7 @@
  */

 #include <linux/miscdevice.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/poll.h>
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 371ca6eac00e..50b17579ca97 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -14,6 +14,7 @@
 #include <linux/earlycpio.h>
 #include <linux/firmware.h>
 #include <linux/uaccess.h>
+#include <linux/export.h>
 #include <linux/initrd.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index 2de01b379aa3..cb9eade755ee 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*  Copyright(c) 2016-20 Intel Corporation. */

+#include <linux/export.h>
 #include <linux/file.h>
 #include <linux/freezer.h>
 #include <linux/highmem.h>
diff --git a/arch/x86/kernel/cpu/sgx/virt.c b/arch/x86/kernel/cpu/sgx/virt.c
index 7aaa3652e31d..15ce2a05c260 100644
--- a/arch/x86/kernel/cpu/sgx/virt.c
+++ b/arch/x86/kernel/cpu/sgx/virt.c
@@ -5,6 +5,7 @@
  * Copyright(c) 2021 Intel Corporation.
  */

+#include <linux/export.h>
 #include <linux/miscdevice.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
index e35ccdc84910..30df9f9c4b0d 100644
--- a/arch/x86/kernel/cpu/topology.c
+++ b/arch/x86/kernel/cpu/topology.c
@@ -23,6 +23,7 @@
  */
 #define pr_fmt(fmt) "CPU topo: " fmt
 #include <linux/cpu.h>
+#include <linux/export.h>

 #include <xen/xen.h>

diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c
index b5a5e1411469..fa841c8b70df 100644
--- a/arch/x86/kernel/cpu/topology_common.c
+++ b/arch/x86/kernel/cpu/topology_common.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/cpu.h>
+#include <linux/export.h>

 #include <xen/xen.h>

diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index bcb534688dfe..3dbabdfe9649 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
-#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/memblock.h>
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index dd8748c45529..2b72ca27eaac 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -3,7 +3,6 @@
  * Architecture specific OF callbacks.
  */
 #include <linux/acpi.h>
-#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 722fd712e1cf..16f5a7984a46 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -9,7 +9,6 @@
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kdebug.h>
-#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
 #include <linux/sysfs.h>
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 6c5defd6569a..4975c5546ba9 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -9,7 +9,6 @@
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kdebug.h>
-#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
 #include <linux/sysfs.h>
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index c3acbd26408b..9edbb4ebac31 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -12,6 +12,7 @@
 #include <linux/crash_dump.h>
 #include <linux/memblock.h>
 #include <linux/suspend.h>
+#include <linux/export.h>
 #include <linux/acpi.h>
 #include <linux/firmware-map.h>
 #include <linux/sort.h>
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 6b6f32f40cbe..097721a95a8d 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/pci_ids.h>
 #include <linux/bcma/bcma.h>
 #include <linux/bcma/bcma_regs.h>
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index ea138583dd92..2e4e37bf9d8f 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -17,6 +17,7 @@

 #include <uapi/asm/kvm.h>

+#include <linux/export.h>
 #include <linux/hardirq.h>
 #include <linux/pkeys.h>
 #include <linux/vmalloc.h>
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 9aa9ac8399ae..6e1dcafc457d 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -7,6 +7,7 @@
 #include <linux/bitops.h>
 #include <linux/compat.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 #include <linux/mman.h>
 #include <linux/nospec.h>
 #include <linux/pkeys.h>
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 533fcf5636fc..b58c6128554f 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -19,6 +19,7 @@
 #include <linux/memblock.h>
 #include <linux/cc_platform.h>
 #include <linux/pgtable.h>
+#include <linux/export.h>

 #include <asm/asm.h>
 #include <asm/page_64.h>
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 2bade73f49e3..212f5e9959e1 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/linkage.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 921c1c783bc1..37a94e2a2d46 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -29,6 +29,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/cc_platform.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <asm/timer.h>
 #include <asm/cpu.h>
 #include <asm/traps.h>
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c
index 9e1ea99ad9df..7f131a15ac9e 100644
--- a/arch/x86/kernel/paravirt-spinlocks.c
+++ b/arch/x86/kernel/paravirt-spinlocks.c
@@ -4,7 +4,6 @@
  * compiled in a FTRACE-compatible way.
  */
 #include <linux/spinlock.h>
-#include <linux/export.h>
 #include <linux/jump_label.h>

 #include <asm/paravirt.h>
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 095f04bdabdc..dfc8ebc8b0f8 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -22,7 +22,6 @@
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/rcupdate.h>
-#include <linux/export.h>
 #include <linux/context_tracking.h>
 #include <linux/nospec.h>

diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index b3f81379c2fc..96d944e26dbe 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -11,6 +11,7 @@
 #include <linux/gfp.h>
 #include <linux/memblock.h>
 #include <linux/nmi.h>
+#include <linux/export.h>

 #include <asm/fixmap.h>
 #include <asm/pvclock.h>
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index a92f18db9610..221014f3d306 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -5,6 +5,7 @@
 #include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <linux/export.h>

 #include <asm/hpet.h>
 #include <asm/setup.h>
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index fb27be697128..ea43a022f9a8 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -11,6 +11,7 @@
 #include <linux/crash_dump.h>
 #include <linux/dma-map-ops.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/hugetlb.h>
 #include <linux/ima.h>
 #include <linux/init_ohci1394_dma.h>
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index ee117fcf46ed..ddce014f29b2 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -7,7 +7,6 @@
 #include <linux/sched/debug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
-#include <linux/export.h>
 #include <linux/uaccess.h>
 #include <asm/stacktrace.h>
 #include <asm/unwind.h>
diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c
index 378c388d1b31..3ab922966ab4 100644
--- a/arch/x86/kernel/static_call.c
+++ b/arch/x86/kernel/static_call.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/static_call.h>
+#include <linux/export.h>
 #include <linux/memory.h>
 #include <linux/bug.h>
 #include <asm/text-patching.h>
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 46b8f1f16676..b6a1bb741ebd 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -8,7 +8,6 @@

 #include <linux/init_task.h>
 #include <linux/spinlock.h>
-#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/init.h>
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c5c897a86418..5a038f66271b 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -22,7 +22,6 @@
 #include <linux/kdebug.h>
 #include <linux/kgdb.h>
 #include <linux/kernel.h>
-#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/uprobes.h>
 #include <linux/string.h>
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c
index d8ba93778ae3..f3b893c0e5e7 100644
--- a/arch/x86/kernel/unwind_frame.c
+++ b/arch/x86/kernel/unwind_frame.c
@@ -3,6 +3,7 @@
 #include <linux/sched/task.h>
 #include <linux/sched/task_stack.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <asm/sections.h>
 #include <asm/ptrace.h>
 #include <asm/bitops.h>
diff --git a/arch/x86/kernel/unwind_guess.c b/arch/x86/kernel/unwind_guess.c
index 884d68a6e714..86813ae9d57c 100644
--- a/arch/x86/kernel/unwind_guess.c
+++ b/arch/x86/kernel/unwind_guess.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/sched.h>
 #include <linux/ftrace.h>
+#include <linux/export.h>
 #include <asm/ptrace.h>
 #include <asm/bitops.h>
 #include <asm/stacktrace.h>
diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index 977ee75e047c..ec0cd3c54616 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/objtool.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/sort.h>
 #include <asm/ptrace.h>
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 24f0318c50d7..09f9de4555dd 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -33,6 +33,7 @@
 #include <linux/sched/cputime.h>
 #include <linux/spinlock.h>
 #include <linux/eventfd.h>
+#include <linux/export.h>

 #include <asm/apicdef.h>
 #include <asm/mshyperv.h>
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 45dae2d5d2f1..bfa87e74fe18 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -36,7 +36,6 @@
 #include <linux/hrtimer.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/export.h>
 #include <linux/nospec.h>
 #include <asm/processor.h>
 #include <asm/page.h>
diff --git a/arch/x86/kvm/kvm_onhyperv.c b/arch/x86/kvm/kvm_onhyperv.c
index ded0bd688c65..73a97e1dcdbd 100644
--- a/arch/x86/kvm/kvm_onhyperv.c
+++ b/arch/x86/kvm/kvm_onhyperv.c
@@ -4,6 +4,7 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <linux/export.h>
 #include <linux/kvm_host.h>
 #include <asm/mshyperv.h>

diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 1b17b12393a8..2c407d7edd09 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -15,6 +15,7 @@
 #include <linux/lockdep.h>
 #include <linux/kvm_host.h>
 #include <linux/rculist.h>
+#include <linux/export.h>

 #include "mmu.h"
 #include "mmu_internal.h"
diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c
index cfce03d8f123..217a802e86f9 100644
--- a/arch/x86/kvm/mmu/spte.c
+++ b/arch/x86/kvm/mmu/spte.c
@@ -9,6 +9,7 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <linux/export.h>
 #include <linux/kvm_host.h>
 #include "mmu.h"
 #include "mmu_internal.h"
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 7f3d7229b2c1..1df1726f506c 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -8,6 +8,7 @@
 #include "tdp_mmu.h"
 #include "spte.h"

+#include <linux/export.h>
 #include <asm/cmpxchg.h>
 #include <trace/events/kvm.h>

diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 75e9cfc689f8..308a6ae502e3 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -16,6 +16,7 @@
 #include <linux/perf_event.h>
 #include <linux/bsearch.h>
 #include <linux/sort.h>
+#include <linux/export.h>
 #include <asm/perf_event.h>
 #include <asm/cpu_device_id.h>
 #include "x86.h"
diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c
index 9864c057187d..4b13a6346f06 100644
--- a/arch/x86/kvm/smm.c
+++ b/arch/x86/kvm/smm.c
@@ -2,6 +2,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

 #include <linux/kvm_host.h>
+#include <linux/export.h>
 #include "x86.h"
 #include "kvm_cache_regs.h"
 #include "kvm_emulate.h"
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c
index a0b4a350daa7..04a6901a8969 100644
--- a/arch/x86/lib/atomic64_32.c
+++ b/arch/x86/lib/atomic64_32.c
@@ -1,4 +1,3 @@
 #define ATOMIC64_EXPORT EXPORT_SYMBOL

-#include <linux/export.h>
 #include <linux/atomic.h>
diff --git a/arch/x86/lib/crc-t10dif.c b/arch/x86/lib/crc-t10dif.c
index db7ce59c31ac..c8c2108675cd 100644
--- a/arch/x86/lib/crc-t10dif.c
+++ b/arch/x86/lib/crc-t10dif.c
@@ -6,6 +6,7 @@
  */

 #include <linux/crc-t10dif.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include "crc-pclmul-template.h"

diff --git a/arch/x86/lib/crc32.c b/arch/x86/lib/crc32.c
index d09343e2cea9..21e84e3c94eb 100644
--- a/arch/x86/lib/crc32.c
+++ b/arch/x86/lib/crc32.c
@@ -8,6 +8,7 @@
  */

 #include <linux/crc32.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include "crc-pclmul-template.h"

diff --git a/arch/x86/lib/crc64.c b/arch/x86/lib/crc64.c
index 351a09f5813e..6c1a1beb5c97 100644
--- a/arch/x86/lib/crc64.c
+++ b/arch/x86/lib/crc64.c
@@ -6,6 +6,7 @@
  */

 #include <linux/crc64.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include "crc-pclmul-template.h"

diff --git a/arch/x86/lib/crypto/blake2s-glue.c b/arch/x86/lib/crypto/blake2s-glue.c
index adc296cd17c9..e65cebbdc043 100644
--- a/arch/x86/lib/crypto/blake2s-glue.c
+++ b/arch/x86/lib/crypto/blake2s-glue.c
@@ -8,6 +8,7 @@
 #include <asm/processor.h>
 #include <asm/simd.h>
 #include <crypto/internal/blake2s.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
diff --git a/arch/x86/lib/crypto/chacha_glue.c b/arch/x86/lib/crypto/chacha_glue.c
index 10b2c945f541..7e3bf4b091f1 100644
--- a/arch/x86/lib/crypto/chacha_glue.c
+++ b/arch/x86/lib/crypto/chacha_glue.c
@@ -7,6 +7,7 @@

 #include <asm/simd.h>
 #include <crypto/chacha.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/arch/x86/lib/crypto/poly1305_glue.c b/arch/x86/lib/crypto/poly1305_glue.c
index b7e78a583e07..c2bc5b831551 100644
--- a/arch/x86/lib/crypto/poly1305_glue.c
+++ b/arch/x86/lib/crypto/poly1305_glue.c
@@ -6,6 +6,7 @@
 #include <asm/cpu_device_id.h>
 #include <asm/fpu/api.h>
 #include <crypto/internal/poly1305.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/arch/x86/lib/crypto/sha256.c b/arch/x86/lib/crypto/sha256.c
index 80380f8fdcee..46d5d174e821 100644
--- a/arch/x86/lib/crypto/sha256.c
+++ b/arch/x86/lib/crypto/sha256.c
@@ -6,6 +6,7 @@
  */
 #include <asm/fpu/api.h>
 #include <crypto/internal/sha2.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/static_call.h>
diff --git a/arch/x86/lib/iomem.c b/arch/x86/lib/iomem.c
index c20e04764edc..20f90c60e34e 100644
--- a/arch/x86/lib/iomem.c
+++ b/arch/x86/lib/iomem.c
@@ -1,5 +1,6 @@
 #include <linux/string.h>
 #include <linux/module.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/kmsan-checks.h>

diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c
index 575f863f3c75..2ffd4628643b 100644
--- a/arch/x86/mm/cpu_entry_area.c
+++ b/arch/x86/mm/cpu_entry_area.c
@@ -5,6 +5,7 @@
 #include <linux/kallsyms.h>
 #include <linux/kcore.h>
 #include <linux/pgtable.h>
+#include <linux/export.h>

 #include <asm/cpu_entry_area.h>
 #include <asm/fixmap.h>
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index a4700ef6eb64..90df00f4ef88 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -9,6 +9,7 @@
  */

 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/kasan.h>
 #include <linux/mm.h>
 #include <linux/init.h>
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 7456df985d96..00c7088c5835 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -8,6 +8,7 @@
 #include <linux/kmemleak.h>
 #include <linux/sched/task.h>
 #include <linux/execmem.h>
+#include <linux/export.h>

 #include <asm/set_memory.h>
 #include <asm/cpu_device_id.h>
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 607d6a2e66e2..633887c582af 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -31,6 +31,7 @@
 #include <linux/cpumask.h>
 #include <linux/gfp.h>
 #include <linux/execmem.h>
+#include <linux/export.h>

 #include <asm/asm.h>
 #include <asm/bios_ebda.h>
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index ee66fae9ebcc..e3bd8adea411 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -35,6 +35,7 @@
 #include <linux/kcore.h>
 #include <linux/bootmem_info.h>
 #include <linux/execmem.h>
+#include <linux/export.h>

 #include <asm/processor.h>
 #include <asm/bios_ebda.h>
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 12c8180ca1ba..4e2101e637ba 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -17,6 +17,7 @@
 #include <linux/mmiotrace.h>
 #include <linux/cc_platform.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/pgtable.h>
 #include <linux/kmsan.h>

diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index faf3a13fb6ba..cb069276f756 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -18,6 +18,7 @@
 #include <linux/bitops.h>
 #include <linux/dma-mapping.h>
 #include <linux/cc_platform.h>
+#include <linux/export.h>

 #include <asm/tlbflush.h>
 #include <asm/fixmap.h>
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index c3317f0650d8..7555c0ef2cf3 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -21,6 +21,7 @@
 #include <linux/atomic.h>
 #include <linux/percpu.h>
 #include <linux/cpu.h>
+#include <linux/export.h>

 #include "pf_in.h"

diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index c24890c40138..5e3ac16ceea5 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -14,6 +14,7 @@
 #include <linux/topology.h>
 #include <linux/sort.h>
 #include <linux/numa_memblks.h>
+#include <linux/export.h>

 #include <asm/e820/api.h>
 #include <asm/proto.h>
diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
index 2e7923844afe..3eeee5b2384a 100644
--- a/arch/x86/mm/pat/memtype.c
+++ b/arch/x86/mm/pat/memtype.c
@@ -34,6 +34,7 @@
 #include <linux/seq_file.h>
 #include <linux/memblock.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/pfn_t.h>
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 46edc11726b7..89973d5e4327 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -22,6 +22,7 @@
 #include <linux/cc_platform.h>
 #include <linux/set_memory.h>
 #include <linux/memregion.h>
+#include <linux/export.h>

 #include <asm/e820/api.h>
 #include <asm/processor.h>
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index ddf248c3ee7d..92ee7b5cd93b 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/mm.h>
 #include <linux/gfp.h>
+#include <linux/export.h>
 #include <linux/hugetlb.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index c234634e26ba..2acb05736cf1 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -9,6 +9,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>

 #include <asm/cpu_entry_area.h>
 #include <asm/fixmap.h>
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index 244c643bb0b5..1956cb58e281 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -5,6 +5,7 @@

 #include <linux/bits.h>
 #include <linux/bitfield.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 463b784499a8..6288436d8ec3 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -35,7 +35,6 @@
 #include <linux/init.h>
 #include <linux/efi.h>
 #include <linux/efi-bgrt.h>
-#include <linux/export.h>
 #include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index e7e8f77f77f8..627d084c344d 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -27,7 +27,6 @@
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
 #include <linux/efi.h>
-#include <linux/export.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/reboot.h>
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 553f330198f2..4119b2f693bc 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -7,6 +7,7 @@
 #include <linux/time.h>
 #include <linux/types.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/memblock.h>
 #include <linux/acpi.h>
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index a8e75f8c14fd..a877e52cb38e 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -15,7 +15,6 @@
 #include <linux/regulator/machine.h>
 #include <linux/scatterlist.h>
 #include <linux/irq.h>
-#include <linux/export.h>
 #include <linux/notifier.h>

 #include <asm/setup.h>
diff --git a/arch/x86/platform/intel-mid/pwr.c b/arch/x86/platform/intel-mid/pwr.c
index cd7e0c71adde..77c0ff63ee28 100644
--- a/arch/x86/platform/intel-mid/pwr.c
+++ b/arch/x86/platform/intel-mid/pwr.c
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>

diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c
index ee25b032c0b3..f97c11d3c1d2 100644
--- a/arch/x86/platform/intel-quark/imr.c
+++ b/arch/x86/platform/intel-quark/imr.c
@@ -32,6 +32,7 @@
 #include <asm/io.h>

 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/types.h>
diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c
index 40ae94db20d8..49af88f1deda 100644
--- a/arch/x86/platform/intel/iosf_mbi.c
+++ b/arch/x86/platform/intel/iosf_mbi.c
@@ -18,6 +18,7 @@
 #include <linux/capability.h>
 #include <linux/pm_qos.h>
 #include <linux/wait.h>
+#include <linux/export.h>

 #include <asm/iosf_mbi.h>

diff --git a/arch/x86/platform/scx200/scx200_32.c b/arch/x86/platform/scx200/scx200_32.c
index 80662b72035d..97386353b0f5 100644
--- a/arch/x86/platform/scx200/scx200_32.c
+++ b/arch/x86/platform/scx200/scx200_32.c
@@ -7,6 +7,7 @@

 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
diff --git a/arch/x86/video/video-common.c b/arch/x86/video/video-common.c
index 81fc97a2a837..57070d9e1a56 100644
--- a/arch/x86/video/video-common.c
+++ b/arch/x86/video/video-common.c
@@ -7,6 +7,7 @@
  *
  */

+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index 942372e69b4d..7cd06bb3aa9f 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -19,6 +19,7 @@
 #include <linux/iommu.h>
 #include <linux/amd-iommu.h>
 #include <linux/nospec.h>
+#include <linux/export.h>

 #include <asm/sev.h>
 #include <asm/processor.h>
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 2457d13c3f9e..e5bb81dc8497 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -12,6 +12,7 @@
 #include <linux/cache.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/printk.h>
 #include <linux/cpu.h>
 #include <linux/spinlock.h>
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 53282dc7d5ac..4b2b038a1ec8 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -2,6 +2,7 @@

 #include <linux/console.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 #include <linux/instrumentation.h>
 #include <linux/kexec.h>
 #include <linux/memblock.h>
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index fe57ff85d004..4399a1796861 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -2,6 +2,7 @@

 #include <linux/acpi.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 #include <linux/kexec.h>
 #include <linux/memblock.h>
 #include <linux/virtio_anchor.h>
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index c4c479373249..da38470e6131 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0

 #include <linux/pfn.h>
+#include <linux/export.h>
 #include <asm/xen/page.h>
 #include <asm/xen/hypercall.h>
 #include <xen/interface/memory.h>

Signed-off-by: Zhenghan Cheng <your_email@example.com>
---
 arch/x86/coco/sev/core.c                  | 1 +
 arch/x86/crypto/aria_aesni_avx2_glue.c    | 1 +
 arch/x86/crypto/aria_aesni_avx_glue.c     | 1 +
 arch/x86/crypto/camellia_aesni_avx_glue.c | 1 +
 arch/x86/crypto/camellia_glue.c           | 1 +
 arch/x86/crypto/curve25519-x86_64.c       | 1 +
 arch/x86/crypto/serpent_avx_glue.c        | 1 +
 arch/x86/crypto/sm4_aesni_avx_glue.c      | 1 +
 arch/x86/crypto/twofish_glue.c            | 1 +
 arch/x86/crypto/twofish_glue_3way.c       | 1 +
 arch/x86/events/intel/core.c              | 1 -
 arch/x86/events/intel/lbr.c               | 1 +
 arch/x86/events/intel/pt.c                | 2 ++
 arch/x86/events/zhaoxin/core.c            | 1 -
 arch/x86/hyperv/hv_init.c                 | 1 +
 arch/x86/hyperv/irqdomain.c               | 1 +
 arch/x86/hyperv/ivm.c                     | 1 +
 arch/x86/hyperv/nested.c                  | 2 +-
 arch/x86/kernel/acpi/cppc.c               | 1 +
 arch/x86/kernel/alternative.c             | 1 +
 arch/x86/kernel/amd_node.c                | 1 +
 arch/x86/kernel/apic/apic_common.c        | 1 +
 arch/x86/kernel/apic/msi.c                | 1 +
 arch/x86/kernel/apic/vector.c             | 1 +
 arch/x86/kernel/cpu/acrn.c                | 1 +
 arch/x86/kernel/cpu/aperfmperf.c          | 1 +
 arch/x86/kernel/cpu/bugs.c                | 1 +
 arch/x86/kernel/cpu/bus_lock.c            | 1 +
 arch/x86/kernel/cpu/mce/amd.c             | 1 +
 arch/x86/kernel/cpu/mce/dev-mcelog.c      | 1 +
 arch/x86/kernel/cpu/microcode/intel.c     | 1 +
 arch/x86/kernel/cpu/sgx/main.c            | 1 +
 arch/x86/kernel/cpu/sgx/virt.c            | 1 +
 arch/x86/kernel/cpu/topology.c            | 1 +
 arch/x86/kernel/cpu/topology_common.c     | 1 +
 arch/x86/kernel/crash.c                   | 1 -
 arch/x86/kernel/devicetree.c              | 1 -
 arch/x86/kernel/dumpstack_32.c            | 1 -
 arch/x86/kernel/dumpstack_64.c            | 1 -
 arch/x86/kernel/e820.c                    | 1 +
 arch/x86/kernel/early-quirks.c            | 1 +
 arch/x86/kernel/fpu/core.c                | 1 +
 arch/x86/kernel/fpu/xstate.c              | 1 +
 arch/x86/kernel/head64.c                  | 1 +
 arch/x86/kernel/i8259.c                   | 1 +
 arch/x86/kernel/kvm.c                     | 1 +
 arch/x86/kernel/paravirt-spinlocks.c      | 1 -
 arch/x86/kernel/ptrace.c                  | 1 -
 arch/x86/kernel/pvclock.c                 | 1 +
 arch/x86/kernel/quirks.c                  | 1 +
 arch/x86/kernel/setup.c                   | 1 +
 arch/x86/kernel/stacktrace.c              | 1 -
 arch/x86/kernel/static_call.c             | 1 +
 arch/x86/kernel/tboot.c                   | 1 -
 arch/x86/kernel/traps.c                   | 1 -
 arch/x86/kernel/unwind_frame.c            | 1 +
 arch/x86/kernel/unwind_guess.c            | 1 +
 arch/x86/kernel/unwind_orc.c              | 1 +
 arch/x86/kvm/hyperv.c                     | 1 +
 arch/x86/kvm/ioapic.c                     | 1 -
 arch/x86/kvm/kvm_onhyperv.c               | 1 +
 arch/x86/kvm/mmu/page_track.c             | 1 +
 arch/x86/kvm/mmu/spte.c                   | 1 +
 arch/x86/kvm/mmu/tdp_mmu.c                | 1 +
 arch/x86/kvm/pmu.c                        | 1 +
 arch/x86/kvm/smm.c                        | 1 +
 arch/x86/lib/atomic64_32.c                | 1 -
 arch/x86/lib/crc-t10dif.c                 | 1 +
 arch/x86/lib/crc32.c                      | 1 +
 arch/x86/lib/crc64.c                      | 1 +
 arch/x86/lib/crypto/blake2s-glue.c        | 1 +
 arch/x86/lib/crypto/chacha_glue.c         | 1 +
 arch/x86/lib/crypto/poly1305_glue.c       | 1 +
 arch/x86/lib/crypto/sha256.c              | 1 +
 arch/x86/lib/iomem.c                      | 1 +
 arch/x86/mm/cpu_entry_area.c              | 1 +
 arch/x86/mm/dump_pagetables.c             | 1 +
 arch/x86/mm/init.c                        | 1 +
 arch/x86/mm/init_32.c                     | 1 +
 arch/x86/mm/init_64.c                     | 1 +
 arch/x86/mm/ioremap.c                     | 1 +
 arch/x86/mm/mem_encrypt_amd.c             | 1 +
 arch/x86/mm/mmio-mod.c                    | 1 +
 arch/x86/mm/numa.c                        | 1 +
 arch/x86/mm/pat/memtype.c                 | 1 +
 arch/x86/mm/pat/set_memory.c              | 1 +
 arch/x86/mm/pgtable.c                     | 1 +
 arch/x86/mm/pgtable_32.c                  | 1 +
 arch/x86/pci/pcbios.c                     | 1 +
 arch/x86/platform/efi/efi.c               | 1 -
 arch/x86/platform/efi/efi_64.c            | 1 -
 arch/x86/platform/efi/quirks.c            | 1 +
 arch/x86/platform/intel-mid/intel-mid.c   | 1 -
 arch/x86/platform/intel-mid/pwr.c         | 1 -
 arch/x86/platform/intel-quark/imr.c       | 1 +
 arch/x86/platform/intel/iosf_mbi.c        | 1 +
 arch/x86/platform/scx200/scx200_32.c      | 1 +
 arch/x86/video/video-common.c             | 1 +
 arch/x86/virt/svm/sev.c                   | 1 +
 arch/x86/virt/vmx/tdx/tdx.c               | 1 +
 arch/x86/xen/enlighten.c                  | 1 +
 arch/x86/xen/enlighten_hvm.c              | 1 +
 arch/x86/xen/mmu.c                        | 1 +
 103 files changed, 87 insertions(+), 18 deletions(-)

diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index b6db4e0b936b..773b24859037 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/psp-sev.h>
 #include <linux/dmi.h>
+#include <linux/export.h>
 #include <uapi/linux/sev-guest.h>
 #include <crypto/gcm.h>
 
diff --git a/arch/x86/crypto/aria_aesni_avx2_glue.c b/arch/x86/crypto/aria_aesni_avx2_glue.c
index b4bddcd58457..007b250f774c 100644
--- a/arch/x86/crypto/aria_aesni_avx2_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx2_glue.c
@@ -9,6 +9,7 @@
 #include <crypto/aria.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/types.h>
 
diff --git a/arch/x86/crypto/aria_aesni_avx_glue.c b/arch/x86/crypto/aria_aesni_avx_glue.c
index ab9b38d05332..4c88ef4eba82 100644
--- a/arch/x86/crypto/aria_aesni_avx_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx_glue.c
@@ -9,6 +9,7 @@
 #include <crypto/aria.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/types.h>
 
diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c
index a7d162388142..5c321f255eb7 100644
--- a/arch/x86/crypto/camellia_aesni_avx_glue.c
+++ b/arch/x86/crypto/camellia_aesni_avx_glue.c
@@ -8,6 +8,7 @@
 #include <crypto/algapi.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/types.h>
 
diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c
index 3bd37d664121..cbede120e5f2 100644
--- a/arch/x86/crypto/camellia_glue.c
+++ b/arch/x86/crypto/camellia_glue.c
@@ -10,6 +10,7 @@
 
 #include <linux/unaligned.h>
 #include <linux/crypto.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c
index dcfc0de333de..86d4c4d85487 100644
--- a/arch/x86/crypto/curve25519-x86_64.c
+++ b/arch/x86/crypto/curve25519-x86_64.c
@@ -8,6 +8,7 @@
 #include <crypto/internal/kpp.h>
 
 #include <linux/types.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c
index e640abc1cb8a..9c8b3a335d5c 100644
--- a/arch/x86/crypto/serpent_avx_glue.c
+++ b/arch/x86/crypto/serpent_avx_glue.c
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <crypto/algapi.h>
 #include <crypto/serpent.h>
 
diff --git a/arch/x86/crypto/sm4_aesni_avx_glue.c b/arch/x86/crypto/sm4_aesni_avx_glue.c
index 72867fc49ce8..88caf418a06f 100644
--- a/arch/x86/crypto/sm4_aesni_avx_glue.c
+++ b/arch/x86/crypto/sm4_aesni_avx_glue.c
@@ -11,6 +11,7 @@
 #include <asm/fpu/api.h>
 #include <linux/module.h>
 #include <linux/crypto.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/sm4.h>
diff --git a/arch/x86/crypto/twofish_glue.c b/arch/x86/crypto/twofish_glue.c
index 4c67184dc573..8e9906d36902 100644
--- a/arch/x86/crypto/twofish_glue.c
+++ b/arch/x86/crypto/twofish_glue.c
@@ -40,6 +40,7 @@
 
 #include <crypto/algapi.h>
 #include <crypto/twofish.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 1a1ecfa7f72a..8ad77725bf60 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -9,6 +9,7 @@
 #include <crypto/algapi.h>
 #include <crypto/twofish.h>
 #include <linux/crypto.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 741b229f0718..04cf3d1019d9 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -12,7 +12,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/export.h>
 #include <linux/nmi.h>
 #include <linux/kvm_host.h>
 
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 7aa59966e7c3..10619c767602 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/perf_event.h>
+#include <linux/export.h>
 #include <linux/types.h>
 
 #include <asm/cpu_device_id.h>
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index e8cf29d2b10c..9c772c89b623 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -17,6 +17,8 @@
 #include <linux/limits.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/export.h>
+
 
 #include <asm/cpuid/api.h>
 #include <asm/perf_event.h>
diff --git a/arch/x86/events/zhaoxin/core.c b/arch/x86/events/zhaoxin/core.c
index 4bdfcf091200..67fa000cf372 100644
--- a/arch/x86/events/zhaoxin/core.c
+++ b/arch/x86/events/zhaoxin/core.c
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/export.h>
 #include <linux/nmi.h>
 
 #include <asm/cpufeature.h>
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 3d1d3547095a..3bd18521cd46 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -29,6 +29,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/cpuhotplug.h>
 #include <linux/syscore_ops.h>
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index 31f0d29cbc5e..f7627bc8fe49 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -10,6 +10,7 @@
 
 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <linux/export.h>
 #include <asm/mshyperv.h>
 
 static int hv_map_interrupt(union hv_device_id device_id, bool level,
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index e93a2f488ff7..d9c0b3064222 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/cpu.h>
diff --git a/arch/x86/hyperv/nested.c b/arch/x86/hyperv/nested.c
index 1083dc8646f9..1413bfe40ea9 100644
--- a/arch/x86/hyperv/nested.c
+++ b/arch/x86/hyperv/nested.c
@@ -9,7 +9,7 @@
  */
 #define pr_fmt(fmt)  "Hyper-V: " fmt
 
-
+#include <linux/export.h>
 #include <linux/types.h>
 #include <hyperv/hvhdk.h>
 #include <asm/mshyperv.h>
diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
index 7047124490f6..e943947ccb3d 100644
--- a/arch/x86/kernel/acpi/cppc.c
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/export.h>
 
 #include <acpi/cppc_acpi.h>
 #include <asm/msr.h>
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index ecfe7b497cad..882d99b1f4fb 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -6,6 +6,7 @@
 #include <linux/vmalloc.h>
 #include <linux/memory.h>
 #include <linux/execmem.h>
+#include <linux/export.h>
 
 #include <asm/text-patching.h>
 #include <asm/insn.h>
diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index a40176b62eb5..55118dd87116 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <asm/amd/node.h>
 
 /*
diff --git a/arch/x86/kernel/apic/apic_common.c b/arch/x86/kernel/apic/apic_common.c
index 9ef3be866832..f7e1cbb70029 100644
--- a/arch/x86/kernel/apic/apic_common.c
+++ b/arch/x86/kernel/apic/apic_common.c
@@ -3,6 +3,7 @@
  *
  * SPDX-License-Identifier: GPL-2.0
  */
+#include <linux/export.h>
 #include <linux/irq.h>
 #include <asm/apic.h>
 
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 66bc5d3e79db..3f133e24a38e 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -14,6 +14,7 @@
 #include <linux/dmar.h>
 #include <linux/hpet.h>
 #include <linux/msi.h>
+#include <linux/export.h>
 #include <asm/irqdomain.h>
 #include <asm/hpet.h>
 #include <asm/hw_irq.h>
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 93069b13d3af..f35c9184ac30 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/compiler.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/irqdomain.h>
 #include <asm/hw_irq.h>
 #include <asm/traps.h>
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 2c5b51aad91a..8f181da43b20 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/export.h>
 
 #include <asm/acrn.h>
 #include <asm/apic.h>
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index a315b0627dfb..e441400106f8 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -8,6 +8,7 @@
  */
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/ktime.h>
 #include <linux/math64.h>
 #include <linux/percpu.h>
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 7f94e6a5497d..fd136016ff8f 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -16,6 +16,7 @@
 #include <linux/sched/smt.h>
 #include <linux/pgtable.h>
 #include <linux/bpf.h>
+#include <linux/export.h>
 
 #include <asm/spec-ctrl.h>
 #include <asm/cmdline.h>
diff --git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/kernel/cpu/bus_lock.c
index 981f8b1f0792..68105db4dc66 100644
--- a/arch/x86/kernel/cpu/bus_lock.c
+++ b/arch/x86/kernel/cpu/bus_lock.c
@@ -6,6 +6,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/cpuhotplug.h>
+#include <linux/export.h>
 #include <asm/cpu_device_id.h>
 #include <asm/cmdline.h>
 #include <asm/traps.h>
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 9d852c3b2cb5..9b335a939576 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -8,6 +8,7 @@
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/kobject.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c
index 8d023239ce18..4657fdb4810e 100644
--- a/arch/x86/kernel/cpu/mce/dev-mcelog.c
+++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/miscdevice.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/poll.h>
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 371ca6eac00e..50b17579ca97 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -14,6 +14,7 @@
 #include <linux/earlycpio.h>
 #include <linux/firmware.h>
 #include <linux/uaccess.h>
+#include <linux/export.h>
 #include <linux/initrd.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index 2de01b379aa3..cb9eade755ee 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*  Copyright(c) 2016-20 Intel Corporation. */
 
+#include <linux/export.h>
 #include <linux/file.h>
 #include <linux/freezer.h>
 #include <linux/highmem.h>
diff --git a/arch/x86/kernel/cpu/sgx/virt.c b/arch/x86/kernel/cpu/sgx/virt.c
index 7aaa3652e31d..15ce2a05c260 100644
--- a/arch/x86/kernel/cpu/sgx/virt.c
+++ b/arch/x86/kernel/cpu/sgx/virt.c
@@ -5,6 +5,7 @@
  * Copyright(c) 2021 Intel Corporation.
  */
 
+#include <linux/export.h>
 #include <linux/miscdevice.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
index e35ccdc84910..30df9f9c4b0d 100644
--- a/arch/x86/kernel/cpu/topology.c
+++ b/arch/x86/kernel/cpu/topology.c
@@ -23,6 +23,7 @@
  */
 #define pr_fmt(fmt) "CPU topo: " fmt
 #include <linux/cpu.h>
+#include <linux/export.h>
 
 #include <xen/xen.h>
 
diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c
index b5a5e1411469..fa841c8b70df 100644
--- a/arch/x86/kernel/cpu/topology_common.c
+++ b/arch/x86/kernel/cpu/topology_common.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/cpu.h>
+#include <linux/export.h>
 
 #include <xen/xen.h>
 
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index bcb534688dfe..3dbabdfe9649 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
-#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/memblock.h>
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index dd8748c45529..2b72ca27eaac 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -3,7 +3,6 @@
  * Architecture specific OF callbacks.
  */
 #include <linux/acpi.h>
-#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 722fd712e1cf..16f5a7984a46 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -9,7 +9,6 @@
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kdebug.h>
-#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
 #include <linux/sysfs.h>
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 6c5defd6569a..4975c5546ba9 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -9,7 +9,6 @@
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
 #include <linux/kdebug.h>
-#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
 #include <linux/sysfs.h>
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index c3acbd26408b..9edbb4ebac31 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -12,6 +12,7 @@
 #include <linux/crash_dump.h>
 #include <linux/memblock.h>
 #include <linux/suspend.h>
+#include <linux/export.h>
 #include <linux/acpi.h>
 #include <linux/firmware-map.h>
 #include <linux/sort.h>
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 6b6f32f40cbe..097721a95a8d 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/pci_ids.h>
 #include <linux/bcma/bcma.h>
 #include <linux/bcma/bcma_regs.h>
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index ea138583dd92..2e4e37bf9d8f 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -17,6 +17,7 @@
 
 #include <uapi/asm/kvm.h>
 
+#include <linux/export.h>
 #include <linux/hardirq.h>
 #include <linux/pkeys.h>
 #include <linux/vmalloc.h>
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 9aa9ac8399ae..6e1dcafc457d 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -7,6 +7,7 @@
 #include <linux/bitops.h>
 #include <linux/compat.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 #include <linux/mman.h>
 #include <linux/nospec.h>
 #include <linux/pkeys.h>
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 533fcf5636fc..b58c6128554f 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -19,6 +19,7 @@
 #include <linux/memblock.h>
 #include <linux/cc_platform.h>
 #include <linux/pgtable.h>
+#include <linux/export.h>
 
 #include <asm/asm.h>
 #include <asm/page_64.h>
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 2bade73f49e3..212f5e9959e1 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/linkage.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 921c1c783bc1..37a94e2a2d46 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -29,6 +29,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/cc_platform.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <asm/timer.h>
 #include <asm/cpu.h>
 #include <asm/traps.h>
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c
index 9e1ea99ad9df..7f131a15ac9e 100644
--- a/arch/x86/kernel/paravirt-spinlocks.c
+++ b/arch/x86/kernel/paravirt-spinlocks.c
@@ -4,7 +4,6 @@
  * compiled in a FTRACE-compatible way.
  */
 #include <linux/spinlock.h>
-#include <linux/export.h>
 #include <linux/jump_label.h>
 
 #include <asm/paravirt.h>
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 095f04bdabdc..dfc8ebc8b0f8 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -22,7 +22,6 @@
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/rcupdate.h>
-#include <linux/export.h>
 #include <linux/context_tracking.h>
 #include <linux/nospec.h>
 
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index b3f81379c2fc..96d944e26dbe 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -11,6 +11,7 @@
 #include <linux/gfp.h>
 #include <linux/memblock.h>
 #include <linux/nmi.h>
+#include <linux/export.h>
 
 #include <asm/fixmap.h>
 #include <asm/pvclock.h>
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index a92f18db9610..221014f3d306 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -5,6 +5,7 @@
 #include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <linux/export.h>
 
 #include <asm/hpet.h>
 #include <asm/setup.h>
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index fb27be697128..ea43a022f9a8 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -11,6 +11,7 @@
 #include <linux/crash_dump.h>
 #include <linux/dma-map-ops.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/hugetlb.h>
 #include <linux/ima.h>
 #include <linux/init_ohci1394_dma.h>
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index ee117fcf46ed..ddce014f29b2 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -7,7 +7,6 @@
 #include <linux/sched/debug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
-#include <linux/export.h>
 #include <linux/uaccess.h>
 #include <asm/stacktrace.h>
 #include <asm/unwind.h>
diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c
index 378c388d1b31..3ab922966ab4 100644
--- a/arch/x86/kernel/static_call.c
+++ b/arch/x86/kernel/static_call.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/static_call.h>
+#include <linux/export.h>
 #include <linux/memory.h>
 #include <linux/bug.h>
 #include <asm/text-patching.h>
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 46b8f1f16676..b6a1bb741ebd 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -8,7 +8,6 @@
 
 #include <linux/init_task.h>
 #include <linux/spinlock.h>
-#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/init.h>
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c5c897a86418..5a038f66271b 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -22,7 +22,6 @@
 #include <linux/kdebug.h>
 #include <linux/kgdb.h>
 #include <linux/kernel.h>
-#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/uprobes.h>
 #include <linux/string.h>
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c
index d8ba93778ae3..f3b893c0e5e7 100644
--- a/arch/x86/kernel/unwind_frame.c
+++ b/arch/x86/kernel/unwind_frame.c
@@ -3,6 +3,7 @@
 #include <linux/sched/task.h>
 #include <linux/sched/task_stack.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <asm/sections.h>
 #include <asm/ptrace.h>
 #include <asm/bitops.h>
diff --git a/arch/x86/kernel/unwind_guess.c b/arch/x86/kernel/unwind_guess.c
index 884d68a6e714..86813ae9d57c 100644
--- a/arch/x86/kernel/unwind_guess.c
+++ b/arch/x86/kernel/unwind_guess.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/sched.h>
 #include <linux/ftrace.h>
+#include <linux/export.h>
 #include <asm/ptrace.h>
 #include <asm/bitops.h>
 #include <asm/stacktrace.h>
diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index 977ee75e047c..ec0cd3c54616 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/objtool.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/sort.h>
 #include <asm/ptrace.h>
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 24f0318c50d7..09f9de4555dd 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -33,6 +33,7 @@
 #include <linux/sched/cputime.h>
 #include <linux/spinlock.h>
 #include <linux/eventfd.h>
+#include <linux/export.h>
 
 #include <asm/apicdef.h>
 #include <asm/mshyperv.h>
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 45dae2d5d2f1..bfa87e74fe18 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -36,7 +36,6 @@
 #include <linux/hrtimer.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/export.h>
 #include <linux/nospec.h>
 #include <asm/processor.h>
 #include <asm/page.h>
diff --git a/arch/x86/kvm/kvm_onhyperv.c b/arch/x86/kvm/kvm_onhyperv.c
index ded0bd688c65..73a97e1dcdbd 100644
--- a/arch/x86/kvm/kvm_onhyperv.c
+++ b/arch/x86/kvm/kvm_onhyperv.c
@@ -4,6 +4,7 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/export.h>
 #include <linux/kvm_host.h>
 #include <asm/mshyperv.h>
 
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 1b17b12393a8..2c407d7edd09 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -15,6 +15,7 @@
 #include <linux/lockdep.h>
 #include <linux/kvm_host.h>
 #include <linux/rculist.h>
+#include <linux/export.h>
 
 #include "mmu.h"
 #include "mmu_internal.h"
diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c
index cfce03d8f123..217a802e86f9 100644
--- a/arch/x86/kvm/mmu/spte.c
+++ b/arch/x86/kvm/mmu/spte.c
@@ -9,6 +9,7 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/export.h>
 #include <linux/kvm_host.h>
 #include "mmu.h"
 #include "mmu_internal.h"
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 7f3d7229b2c1..1df1726f506c 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -8,6 +8,7 @@
 #include "tdp_mmu.h"
 #include "spte.h"
 
+#include <linux/export.h>
 #include <asm/cmpxchg.h>
 #include <trace/events/kvm.h>
 
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 75e9cfc689f8..308a6ae502e3 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -16,6 +16,7 @@
 #include <linux/perf_event.h>
 #include <linux/bsearch.h>
 #include <linux/sort.h>
+#include <linux/export.h>
 #include <asm/perf_event.h>
 #include <asm/cpu_device_id.h>
 #include "x86.h"
diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c
index 9864c057187d..4b13a6346f06 100644
--- a/arch/x86/kvm/smm.c
+++ b/arch/x86/kvm/smm.c
@@ -2,6 +2,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kvm_host.h>
+#include <linux/export.h>
 #include "x86.h"
 #include "kvm_cache_regs.h"
 #include "kvm_emulate.h"
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c
index a0b4a350daa7..04a6901a8969 100644
--- a/arch/x86/lib/atomic64_32.c
+++ b/arch/x86/lib/atomic64_32.c
@@ -1,4 +1,3 @@
 #define ATOMIC64_EXPORT EXPORT_SYMBOL
 
-#include <linux/export.h>
 #include <linux/atomic.h>
diff --git a/arch/x86/lib/crc-t10dif.c b/arch/x86/lib/crc-t10dif.c
index db7ce59c31ac..c8c2108675cd 100644
--- a/arch/x86/lib/crc-t10dif.c
+++ b/arch/x86/lib/crc-t10dif.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/crc-t10dif.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include "crc-pclmul-template.h"
 
diff --git a/arch/x86/lib/crc32.c b/arch/x86/lib/crc32.c
index d09343e2cea9..21e84e3c94eb 100644
--- a/arch/x86/lib/crc32.c
+++ b/arch/x86/lib/crc32.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/crc32.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include "crc-pclmul-template.h"
 
diff --git a/arch/x86/lib/crc64.c b/arch/x86/lib/crc64.c
index 351a09f5813e..6c1a1beb5c97 100644
--- a/arch/x86/lib/crc64.c
+++ b/arch/x86/lib/crc64.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/crc64.h>
+#include <linux/export.h>
 #include <linux/module.h>
 #include "crc-pclmul-template.h"
 
diff --git a/arch/x86/lib/crypto/blake2s-glue.c b/arch/x86/lib/crypto/blake2s-glue.c
index adc296cd17c9..e65cebbdc043 100644
--- a/arch/x86/lib/crypto/blake2s-glue.c
+++ b/arch/x86/lib/crypto/blake2s-glue.c
@@ -8,6 +8,7 @@
 #include <asm/processor.h>
 #include <asm/simd.h>
 #include <crypto/internal/blake2s.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
diff --git a/arch/x86/lib/crypto/chacha_glue.c b/arch/x86/lib/crypto/chacha_glue.c
index 10b2c945f541..7e3bf4b091f1 100644
--- a/arch/x86/lib/crypto/chacha_glue.c
+++ b/arch/x86/lib/crypto/chacha_glue.c
@@ -7,6 +7,7 @@
 
 #include <asm/simd.h>
 #include <crypto/chacha.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/arch/x86/lib/crypto/poly1305_glue.c b/arch/x86/lib/crypto/poly1305_glue.c
index b7e78a583e07..c2bc5b831551 100644
--- a/arch/x86/lib/crypto/poly1305_glue.c
+++ b/arch/x86/lib/crypto/poly1305_glue.c
@@ -6,6 +6,7 @@
 #include <asm/cpu_device_id.h>
 #include <asm/fpu/api.h>
 #include <crypto/internal/poly1305.h>
+#include <linux/export.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/arch/x86/lib/crypto/sha256.c b/arch/x86/lib/crypto/sha256.c
index 80380f8fdcee..46d5d174e821 100644
--- a/arch/x86/lib/crypto/sha256.c
+++ b/arch/x86/lib/crypto/sha256.c
@@ -6,6 +6,7 @@
  */
 #include <asm/fpu/api.h>
 #include <crypto/internal/sha2.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/static_call.h>
diff --git a/arch/x86/lib/iomem.c b/arch/x86/lib/iomem.c
index c20e04764edc..20f90c60e34e 100644
--- a/arch/x86/lib/iomem.c
+++ b/arch/x86/lib/iomem.c
@@ -1,5 +1,6 @@
 #include <linux/string.h>
 #include <linux/module.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/kmsan-checks.h>
 
diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c
index 575f863f3c75..2ffd4628643b 100644
--- a/arch/x86/mm/cpu_entry_area.c
+++ b/arch/x86/mm/cpu_entry_area.c
@@ -5,6 +5,7 @@
 #include <linux/kallsyms.h>
 #include <linux/kcore.h>
 #include <linux/pgtable.h>
+#include <linux/export.h>
 
 #include <asm/cpu_entry_area.h>
 #include <asm/fixmap.h>
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index a4700ef6eb64..90df00f4ef88 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/kasan.h>
 #include <linux/mm.h>
 #include <linux/init.h>
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 7456df985d96..00c7088c5835 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -8,6 +8,7 @@
 #include <linux/kmemleak.h>
 #include <linux/sched/task.h>
 #include <linux/execmem.h>
+#include <linux/export.h>
 
 #include <asm/set_memory.h>
 #include <asm/cpu_device_id.h>
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 607d6a2e66e2..633887c582af 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -31,6 +31,7 @@
 #include <linux/cpumask.h>
 #include <linux/gfp.h>
 #include <linux/execmem.h>
+#include <linux/export.h>
 
 #include <asm/asm.h>
 #include <asm/bios_ebda.h>
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index ee66fae9ebcc..e3bd8adea411 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -35,6 +35,7 @@
 #include <linux/kcore.h>
 #include <linux/bootmem_info.h>
 #include <linux/execmem.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/bios_ebda.h>
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 12c8180ca1ba..4e2101e637ba 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -17,6 +17,7 @@
 #include <linux/mmiotrace.h>
 #include <linux/cc_platform.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/pgtable.h>
 #include <linux/kmsan.h>
 
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index faf3a13fb6ba..cb069276f756 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -18,6 +18,7 @@
 #include <linux/bitops.h>
 #include <linux/dma-mapping.h>
 #include <linux/cc_platform.h>
+#include <linux/export.h>
 
 #include <asm/tlbflush.h>
 #include <asm/fixmap.h>
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index c3317f0650d8..7555c0ef2cf3 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -21,6 +21,7 @@
 #include <linux/atomic.h>
 #include <linux/percpu.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 
 #include "pf_in.h"
 
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index c24890c40138..5e3ac16ceea5 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -14,6 +14,7 @@
 #include <linux/topology.h>
 #include <linux/sort.h>
 #include <linux/numa_memblks.h>
+#include <linux/export.h>
 
 #include <asm/e820/api.h>
 #include <asm/proto.h>
diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
index 2e7923844afe..3eeee5b2384a 100644
--- a/arch/x86/mm/pat/memtype.c
+++ b/arch/x86/mm/pat/memtype.c
@@ -34,6 +34,7 @@
 #include <linux/seq_file.h>
 #include <linux/memblock.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/pfn_t.h>
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 46edc11726b7..89973d5e4327 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -22,6 +22,7 @@
 #include <linux/cc_platform.h>
 #include <linux/set_memory.h>
 #include <linux/memregion.h>
+#include <linux/export.h>
 
 #include <asm/e820/api.h>
 #include <asm/processor.h>
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index ddf248c3ee7d..92ee7b5cd93b 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/mm.h>
 #include <linux/gfp.h>
+#include <linux/export.h>
 #include <linux/hugetlb.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index c234634e26ba..2acb05736cf1 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -9,6 +9,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 
 #include <asm/cpu_entry_area.h>
 #include <asm/fixmap.h>
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index 244c643bb0b5..1956cb58e281 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -5,6 +5,7 @@
 
 #include <linux/bits.h>
 #include <linux/bitfield.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 463b784499a8..6288436d8ec3 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -35,7 +35,6 @@
 #include <linux/init.h>
 #include <linux/efi.h>
 #include <linux/efi-bgrt.h>
-#include <linux/export.h>
 #include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index e7e8f77f77f8..627d084c344d 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -27,7 +27,6 @@
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
 #include <linux/efi.h>
-#include <linux/export.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/reboot.h>
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 553f330198f2..4119b2f693bc 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -7,6 +7,7 @@
 #include <linux/time.h>
 #include <linux/types.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/memblock.h>
 #include <linux/acpi.h>
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index a8e75f8c14fd..a877e52cb38e 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -15,7 +15,6 @@
 #include <linux/regulator/machine.h>
 #include <linux/scatterlist.h>
 #include <linux/irq.h>
-#include <linux/export.h>
 #include <linux/notifier.h>
 
 #include <asm/setup.h>
diff --git a/arch/x86/platform/intel-mid/pwr.c b/arch/x86/platform/intel-mid/pwr.c
index cd7e0c71adde..77c0ff63ee28 100644
--- a/arch/x86/platform/intel-mid/pwr.c
+++ b/arch/x86/platform/intel-mid/pwr.c
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
 
diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c
index ee25b032c0b3..f97c11d3c1d2 100644
--- a/arch/x86/platform/intel-quark/imr.c
+++ b/arch/x86/platform/intel-quark/imr.c
@@ -32,6 +32,7 @@
 #include <asm/io.h>
 
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/types.h>
diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c
index 40ae94db20d8..49af88f1deda 100644
--- a/arch/x86/platform/intel/iosf_mbi.c
+++ b/arch/x86/platform/intel/iosf_mbi.c
@@ -18,6 +18,7 @@
 #include <linux/capability.h>
 #include <linux/pm_qos.h>
 #include <linux/wait.h>
+#include <linux/export.h>
 
 #include <asm/iosf_mbi.h>
 
diff --git a/arch/x86/platform/scx200/scx200_32.c b/arch/x86/platform/scx200/scx200_32.c
index 80662b72035d..97386353b0f5 100644
--- a/arch/x86/platform/scx200/scx200_32.c
+++ b/arch/x86/platform/scx200/scx200_32.c
@@ -7,6 +7,7 @@
 
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
diff --git a/arch/x86/video/video-common.c b/arch/x86/video/video-common.c
index 81fc97a2a837..57070d9e1a56 100644
--- a/arch/x86/video/video-common.c
+++ b/arch/x86/video/video-common.c
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/export.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index 942372e69b4d..7cd06bb3aa9f 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -19,6 +19,7 @@
 #include <linux/iommu.h>
 #include <linux/amd-iommu.h>
 #include <linux/nospec.h>
+#include <linux/export.h>
 
 #include <asm/sev.h>
 #include <asm/processor.h>
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 2457d13c3f9e..e5bb81dc8497 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -12,6 +12,7 @@
 #include <linux/cache.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/printk.h>
 #include <linux/cpu.h>
 #include <linux/spinlock.h>
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 53282dc7d5ac..4b2b038a1ec8 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -2,6 +2,7 @@
 
 #include <linux/console.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 #include <linux/instrumentation.h>
 #include <linux/kexec.h>
 #include <linux/memblock.h>
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index fe57ff85d004..4399a1796861 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -2,6 +2,7 @@
 
 #include <linux/acpi.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 #include <linux/kexec.h>
 #include <linux/memblock.h>
 #include <linux/virtio_anchor.h>
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index c4c479373249..da38470e6131 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/pfn.h>
+#include <linux/export.h>
 #include <asm/xen/page.h>
 #include <asm/xen/hypercall.h>
 #include <xen/interface/memory.h>
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH v3 3/4] fbdev/deferred-io: Support contiguous kernel memory framebuffers
From: Thomas Zimmermann @ 2025-06-12  7:25 UTC (permalink / raw)
  To: Michael Kelley, Simona Vetter
  Cc: David Hildenbrand, simona@ffwll.ch, deller@gmx.de,
	haiyangz@microsoft.com, kys@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, akpm@linux-foundation.org, weh@microsoft.com,
	hch@lst.de, dri-devel@lists.freedesktop.org,
	linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-hyperv@vger.kernel.org, linux-mm@kvack.org
In-Reply-To: <SN6PR02MB41579713B557A32674252865D475A@SN6PR02MB4157.namprd02.prod.outlook.com>

Hi

Am 12.06.25 um 01:18 schrieb Michael Kelley:
> From: Michael Kelley Sent: Thursday, June 5, 2025 10:39 AM
>> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Thursday, June 5, 2025
>> 8:36 AM
>>> Hi
>>>
>>> Am 04.06.25 um 23:43 schrieb Michael Kelley:
>>> [...]
>>>> Nonetheless, there's an underlying issue. A main cause of the difference
>>>> is the number of messages to Hyper-V to update dirty regions. With
>>>> hyperv_fb using deferred I/O, the messages are limited 20/second, so
>>>> the total number of messages to Hyper-V is about 480. But hyperv_drm
>>>> appears to send 3 messages to Hyper-V for each line of output, or a total of
>>>> about 3,000,000 messages (~90K/second). That's a lot of additional load
>>>> on the Hyper-V host, and it adds the 10 seconds of additional elapsed
>>>> time seen in the guest. There also this ugly output in dmesg because the
>>>> ring buffer for sending messages to the Hyper-V host gets full -- Hyper-V
>>>> doesn't always keep up, at least not on my local laptop where I'm
>>>> testing:
>>>>
>>>> [12574.327615] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12574.327684] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12574.327760] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12574.327841] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12597.016128] hyperv_sendpacket: 6211 callbacks suppressed
>>>> [12597.016133] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12597.016172] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12597.016220] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> [12597.016267] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
>>> *ERROR* Unable to send packet via vmbus; error -11
>>>> hyperv_drm could be fixed to not output the ugly messages, but there's
>>>> still the underlying issue of overrunning the ring buffer, and excessively
>>>> hammering on the host. If we could get hyperv_drm doing deferred I/O, I
>>>> would feel much better about going full-on with deprecating hyperv_fb.
>>> I try to address the problem with the patches at
>>>
>>> https://lore.kernel.org/dri-devel/20250605152637.98493-1-
>> tzimmermann@suse.de/
>>> Testing and feedback is much appreciated.
>>>
>> Nice!
>>
>> I ran the same test case with your patches, and everything works well. The
>> hyperv_drm numbers are now pretty much the same as the hyperv_fb
>> numbers for both elapsed time and system CPU time -- within a few percent.
>> For hyperv_drm, there's no longer a gap in the elapsed time and system
>> CPU time. No errors due to the guest-to-host ring buffer being full. Total
>> messages to Hyper-V for hyperv_drm are now a few hundred instead of 3M.
>> The hyperv_drm message count is still a little higher than for hyperv_fb,
>> presumably because the simulated vblank rate in hyperv_drm is higher than
>> the 20 Hz rate used by hyperv_fb deferred I/O. But the overall numbers are
>> small enough that the difference is in the noise. Question: what is the default
>> value for the simulated vblank rate? Just curious ...
>>
> FYI, I'm seeing this message occasionally when running with your simulated
> vblank code and hyperv_drm:
>
> [90920.128278] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm] vblank timer overrun
>
> "Occasionally" is about a dozen occurrences over the last day or so. I can't
> yet correlate to any particular activity in the VM. The graphics console has
> not been very busy.

Thanks for the report. It can happen that the vblank timer is handled 
late. It's not strictly an error as the whole thing is best-effort 
anyway. Maybe the timeout could be adjusted.

Best regards
Thomas

>
> Michael
>

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


^ permalink raw reply

* Re: [PATCH v6 0/5] Allow dyn MSI-X vector allocation of MANA
From: Shradha Gupta @ 2025-06-12  6:10 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: linux-hyperv, linux-pci, linux-kernel, Nipun Gupta, Yury Norov,
	Jason Gunthorpe, Jonathan Cameron, Anna-Maria Behnsen, Kevin Tian,
	Long Li, Thomas Gleixner, Bjorn Helgaas, Rob Herring,
	Manivannan Sadhasivam, Krzysztof Wilczy???~Dski,
	Lorenzo Pieralisi, Dexuan Cui, Wei Liu, Haiyang Zhang,
	K. Y. Srinivasan, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Konstantin Taranov, Simon Horman, Leon Romanovsky,
	Maxim Levitsky, Erni Sri Satya Vennela, Peter Zijlstra, netdev,
	linux-rdma, Paul Rosswurm, Shradha Gupta
In-Reply-To: <20250611085416.2e09b8cd@kernel.org>

On Wed, Jun 11, 2025 at 08:54:16AM -0700, Jakub Kicinski wrote:
> On Wed, 11 Jun 2025 07:09:44 -0700 Shradha Gupta wrote:
> > Changes in v6
> >  * rebased to linux-next's v6.16-rc1 as per Jakub's suggestion
> 
> I meant a branch, basically apply the patches on the v6.16-rc1 tag
> and push it out to GitHub, kernel.org or somewhere else public.
> Then we can pull it in and maintain the stable commit IDs.
> No need to repost the patches, FWIW, just share the branch here
> once you pushed it out..

Oh, understood. Thanks for the clarity. Here is a github repo branch
with the changes on v6.16-rc1 tag
https://github.com/shradhagupta6/linux/tree/shradha_v6.16-rc1

Would this suffice?

regards,
Shradha.

^ permalink raw reply

* Re: [PATCH 3/6] KVM: x86: hyper-v: Fix warnings for missing export.h header inclusion
From: Naman Jain @ 2025-06-12  4:04 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H . Peter Anvin, Vitaly Kuznetsov, Paolo Bonzini, Daniel Lezcano,
	Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
	Konstantin Taranov, Leon Romanovsky, Long Li, Shiraz Saleem,
	Shradha Gupta, Maxim Levitsky, Peter Zijlstra,
	Erni Sri Satya Vennela, Souradeep Chakrabarti, linux-hyperv,
	linux-kernel, kvm, netdev, linux-pci
In-Reply-To: <aEl9kO81-kp0hhw0@google.com>



On 6/11/2025 6:28 PM, Sean Christopherson wrote:
> On Wed, Jun 11, 2025, Naman Jain wrote:
>> Fix below warning in Hyper-V drivers
> 
> KVM is quite obviously not a Hyper-V driver.
> 
>> that comes when kernel is compiled with W=1 option. Include export.h in
>> driver files to fix it.  * warning: EXPORT_SYMBOL() is used, but #include
>> <linux/export.h> is missing
> 
> NAK.  I agree with Heiko[*], this is absurd.  And if the W=1 change isn't reverted
> for some reason, I'd rather "fix" all of KVM in one shot, not update random files
> just because of their name.
> 
> Sorry.
> 
> [*] https://lore.kernel.org/all/20250611075533.8102A57-hca@linux.ibm.com
> 

Sure, thanks for reviewing.

Regards,
Naman

>> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
>> ---
>>   arch/x86/kvm/hyperv.c       | 1 +
>>   arch/x86/kvm/kvm_onhyperv.c | 1 +
>>   2 files changed, 2 insertions(+)
>>
>> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
>> index 24f0318c50d7..09f9de4555dd 100644
>> --- a/arch/x86/kvm/hyperv.c
>> +++ b/arch/x86/kvm/hyperv.c
>> @@ -33,6 +33,7 @@
>>   #include <linux/sched/cputime.h>
>>   #include <linux/spinlock.h>
>>   #include <linux/eventfd.h>
>> +#include <linux/export.h>
>>   
>>   #include <asm/apicdef.h>
>>   #include <asm/mshyperv.h>
>> diff --git a/arch/x86/kvm/kvm_onhyperv.c b/arch/x86/kvm/kvm_onhyperv.c
>> index ded0bd688c65..ba45f8364187 100644
>> --- a/arch/x86/kvm/kvm_onhyperv.c
>> +++ b/arch/x86/kvm/kvm_onhyperv.c
>> @@ -5,6 +5,7 @@
>>   #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>>   
>>   #include <linux/kvm_host.h>
>> +#include <linux/export.h>
>>   #include <asm/mshyperv.h>
>>   
>>   #include "hyperv.h"
>> -- 
>> 2.34.1
>>


^ permalink raw reply

* RE: [PATCH v3 3/4] fbdev/deferred-io: Support contiguous kernel memory framebuffers
From: Michael Kelley @ 2025-06-11 23:18 UTC (permalink / raw)
  To: Thomas Zimmermann, Simona Vetter
  Cc: David Hildenbrand, simona@ffwll.ch, deller@gmx.de,
	haiyangz@microsoft.com, kys@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, akpm@linux-foundation.org, weh@microsoft.com,
	hch@lst.de, dri-devel@lists.freedesktop.org,
	linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-hyperv@vger.kernel.org, linux-mm@kvack.org
In-Reply-To: <SN6PR02MB4157F630284939E084486AFED46FA@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Michael Kelley Sent: Thursday, June 5, 2025 10:39 AM
> 
> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Thursday, June 5, 2025
> 8:36 AM
> >
> > Hi
> >
> > Am 04.06.25 um 23:43 schrieb Michael Kelley:
> > [...]
> > > Nonetheless, there's an underlying issue. A main cause of the difference
> > > is the number of messages to Hyper-V to update dirty regions. With
> > > hyperv_fb using deferred I/O, the messages are limited 20/second, so
> > > the total number of messages to Hyper-V is about 480. But hyperv_drm
> > > appears to send 3 messages to Hyper-V for each line of output, or a total of
> > > about 3,000,000 messages (~90K/second). That's a lot of additional load
> > > on the Hyper-V host, and it adds the 10 seconds of additional elapsed
> > > time seen in the guest. There also this ugly output in dmesg because the
> > > ring buffer for sending messages to the Hyper-V host gets full -- Hyper-V
> > > doesn't always keep up, at least not on my local laptop where I'm
> > > testing:
> > >
> > > [12574.327615] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12574.327684] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12574.327760] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12574.327841] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12597.016128] hyperv_sendpacket: 6211 callbacks suppressed
> > > [12597.016133] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12597.016172] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12597.016220] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > > [12597.016267] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm]
> > *ERROR* Unable to send packet via vmbus; error -11
> > >
> > > hyperv_drm could be fixed to not output the ugly messages, but there's
> > > still the underlying issue of overrunning the ring buffer, and excessively
> > > hammering on the host. If we could get hyperv_drm doing deferred I/O, I
> > > would feel much better about going full-on with deprecating hyperv_fb.
> >
> > I try to address the problem with the patches at
> >
> > https://lore.kernel.org/dri-devel/20250605152637.98493-1-
> tzimmermann@suse.de/
> >
> > Testing and feedback is much appreciated.
> >
> 
> Nice!
> 
> I ran the same test case with your patches, and everything works well. The
> hyperv_drm numbers are now pretty much the same as the hyperv_fb
> numbers for both elapsed time and system CPU time -- within a few percent.
> For hyperv_drm, there's no longer a gap in the elapsed time and system
> CPU time. No errors due to the guest-to-host ring buffer being full. Total
> messages to Hyper-V for hyperv_drm are now a few hundred instead of 3M.
> The hyperv_drm message count is still a little higher than for hyperv_fb,
> presumably because the simulated vblank rate in hyperv_drm is higher than
> the 20 Hz rate used by hyperv_fb deferred I/O. But the overall numbers are
> small enough that the difference is in the noise. Question: what is the default
> value for the simulated vblank rate? Just curious ...
> 

FYI, I'm seeing this message occasionally when running with your simulated
vblank code and hyperv_drm:

[90920.128278] hyperv_drm 5620e0c7-8062-4dce-aeb7-520c7ef76171: [drm] vblank timer overrun

"Occasionally" is about a dozen occurrences over the last day or so. I can't
yet correlate to any particular activity in the VM. The graphics console has
not been very busy.

Michael

^ permalink raw reply

* RE: [PATCH 4/4] PCI: hv: Use the correct hypercall for unmasking interrupts on nested
From: Michael Kelley @ 2025-06-11 23:07 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org
  Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, catalin.marinas@arm.com, will@kernel.org,
	tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, hpa@zytor.com, lpieralisi@kernel.org,
	kw@linux.com, robh@kernel.org, bhelgaas@google.com,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org
In-Reply-To: <1749599526-19963-5-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Tuesday, June 10, 2025 4:52 PM
> 
> From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> 
> Running as nested root on MSHV imposes a different requirement
> for the pci-hyperv controller.
> 
> In this setup, the interrupt will first come to the L1 (nested) hypervisor,
> which will deliver it to the appropriate root CPU. Instead of issuing the
> RETARGET hypercall, we should issue the MAP_DEVICE_INTERRUPT
> hypercall to L1 to complete the setup.
> 
> Rename hv_arch_irq_unmask() to hv_irq_retarget_interrupt().
> 
> Co-developed-by: Jinank Jain <jinankjain@linux.microsoft.com>
> Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
>  drivers/pci/controller/pci-hyperv.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index 4d25754dfe2f..0f491c802fb9 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -600,7 +600,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
>  #define hv_msi_prepare		pci_msi_prepare
> 
>  /**
> - * hv_arch_irq_unmask() - "Unmask" the IRQ by setting its current
> + * hv_irq_retarget_interrupt() - "Unmask" the IRQ by setting its current
>   * affinity.
>   * @data:	Describes the IRQ
>   *
> @@ -609,7 +609,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
>   * is built out of this PCI bus's instance GUID and the function
>   * number of the device.
>   */
> -static void hv_arch_irq_unmask(struct irq_data *data)
> +static void hv_irq_retarget_interrupt(struct irq_data *data)
>  {
>  	struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
>  	struct hv_retarget_device_interrupt *params;
> @@ -714,6 +714,20 @@ static void hv_arch_irq_unmask(struct irq_data *data)
>  		dev_err(&hbus->hdev->device,
>  			"%s() failed: %#llx", __func__, res);
>  }
> +
> +static void hv_arch_irq_unmask(struct irq_data *data)
> +{
> +	if (hv_nested && hv_root_partition())

Based on Patch 1 of this series, this driver is not loaded for the root
partition in the non-nested case. So testing hv_nested is redundant.

> +		/*
> +		 * In case of the nested root partition, the nested hypervisor
> +		 * is taking care of interrupt remapping and thus the
> +		 * MAP_DEVICE_INTERRUPT hypercall is required instead of
> +		 * RETARGET_INTERRUPT.
> +		 */
> +		(void)hv_map_msi_interrupt(data, NULL);
> +	else
> +		hv_irq_retarget_interrupt(data);
> +}
>  #elif defined(CONFIG_ARM64)
>  /*
>   * SPI vectors to use for vPCI; arch SPIs range is [32, 1019], but leaving a bit
> --
> 2.34.1


^ permalink raw reply

* RE: [PATCH 3/4] x86: hyperv: Expose hv_map_msi_interrupt function
From: Michael Kelley @ 2025-06-11 23:07 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org
  Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, catalin.marinas@arm.com, will@kernel.org,
	tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, hpa@zytor.com, lpieralisi@kernel.org,
	kw@linux.com, robh@kernel.org, bhelgaas@google.com,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org
In-Reply-To: <1749599526-19963-4-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Tuesday, June 10, 2025 4:52 PM
> 
> From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>

The preferred patch Subject prefix is "x86/hyperv:"

> 
> This patch moves a part of currently internal logic into the
> hv_map_msi_interrupt function and makes it globally available helper
> function, which will be used to map PCI interrupts in case of root
> partition.

Avoid "this patch" in commit messages.  Suggest:

Create a helper function hv_map_msi_interrupt() that contains some
logic that is currently internal to irqdomain.c. Make the helper function
globally available so it can be used to map PCI interrupts when running
in the root partition.

> 
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
>  arch/x86/hyperv/irqdomain.c     | 47 ++++++++++++++++++++++++---------
>  arch/x86/include/asm/mshyperv.h |  2 ++
>  2 files changed, 36 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
> index 31f0d29cbc5e..82f3bafb93d6 100644
> --- a/arch/x86/hyperv/irqdomain.c
> +++ b/arch/x86/hyperv/irqdomain.c
> @@ -169,13 +169,40 @@ static union hv_device_id hv_build_pci_dev_id(struct pci_dev *dev)
>  	return dev_id;
>  }
> 
> -static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector,
> -				struct hv_interrupt_entry *entry)
> +/**
> + * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
> + * @data:      Describes the IRQ
> + * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
> + *
> + * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
> + */
> +int hv_map_msi_interrupt(struct irq_data *data,
> +			 struct hv_interrupt_entry *out_entry)
>  {
> -	union hv_device_id device_id = hv_build_pci_dev_id(dev);
> +	struct msi_desc *msidesc;
> +	struct pci_dev *dev;
> +	union hv_device_id device_id;
> +	struct hv_interrupt_entry dummy;
> +	struct irq_cfg *cfg = irqd_cfg(data);
> +	const cpumask_t *affinity;
> +	int cpu;
> +	u64 res;
> 
> -	return hv_map_interrupt(device_id, false, cpu, vector, entry);
> +	msidesc = irq_data_get_msi_desc(data);
> +	dev = msi_desc_to_pci_dev(msidesc);
> +	device_id = hv_build_pci_dev_id(dev);
> +	affinity = irq_data_get_effective_affinity_mask(data);
> +	cpu = cpumask_first_and(affinity, cpu_online_mask);

Is the cpus_read_lock held at this point? I'm not sure what the
overall calling sequence looks like. If it is not held, the CPU that
is selected could go offline before hv_map_interrupt() is called.
This computation of the target CPU is the same as in the code
before this patch, but that existing code looks like it has the
same problem.

> +
> +	res = hv_map_interrupt(device_id, false, cpu, cfg->vector,
> +			       out_entry ? out_entry : &dummy);
> +	if (!hv_result_success(res))
> +		pr_err("%s: failed to map interrupt: %s",
> +		       __func__, hv_result_to_string(res));

hv_map_interrupt() already outputs a message if the hypercall
fails. Is another message needed here?

> +
> +	return hv_result_to_errno(res);

The error handling is rather messed up. First hv_map_interrupt()
sometimes returns a Linux errno (not negated), and sometimes a
hypercall result. The errno is EINVAL, which has value "22", which is
the same as hypercall result HV_STATUS_ACKNOWLEDGED. And
the hypercall result returned from hv_map_interrupt() is just
the result code, not the full 64-bit status, as hv_map_interrupt()
has already done hv_result(status). Hence the "res" input arg to
hv_result_to_errno() isn't really the correct input. For example,
if the hypercall returns U64_MAX, that won't be caught by
hv_result_to_errno() since the value has been truncated to
32 bits. Fixing all this will require some unscrambling.

>  }
> +EXPORT_SYMBOL_GPL(hv_map_msi_interrupt);
> 
>  static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg)
>  {
> @@ -190,10 +217,8 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  {
>  	struct msi_desc *msidesc;
>  	struct pci_dev *dev;
> -	struct hv_interrupt_entry out_entry, *stored_entry;
> +	struct hv_interrupt_entry *stored_entry;
>  	struct irq_cfg *cfg = irqd_cfg(data);
> -	const cpumask_t *affinity;
> -	int cpu;
>  	u64 status;
> 
>  	msidesc = irq_data_get_msi_desc(data);
> @@ -204,9 +229,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  		return;
>  	}
> 
> -	affinity = irq_data_get_effective_affinity_mask(data);
> -	cpu = cpumask_first_and(affinity, cpu_online_mask);
> -
>  	if (data->chip_data) {
>  		/*
>  		 * This interrupt is already mapped. Let's unmap first.
> @@ -235,15 +257,14 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  		return;
>  	}
> 
> -	status = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
> +	status = hv_map_msi_interrupt(data, stored_entry);
>  	if (status != HV_STATUS_SUCCESS) {

hv_map_msi_interrupt() returns an errno, so testing for HV_STATUS_SUCCESS
is bogus.

>  		kfree(stored_entry);
>  		return;
>  	}
> 
> -	*stored_entry = out_entry;
>  	data->chip_data = stored_entry;
> -	entry_to_msi_msg(&out_entry, msg);
> +	entry_to_msi_msg(data->chip_data, msg);
> 
>  	return;
>  }
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index 5ec92e3e2e37..843121465ddd 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -261,6 +261,8 @@ static inline void hv_apic_init(void) {}
> 
>  struct irq_domain *hv_create_pci_msi_domain(void);
> 
> +int hv_map_msi_interrupt(struct irq_data *data,
> +			 struct hv_interrupt_entry *out_entry);
>  int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
>  		struct hv_interrupt_entry *entry);
>  int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
> --
> 2.34.1


^ permalink raw reply

* RE: [PATCH 2/4] Drivers: hv: Use nested hypercall for post message and signal event
From: Michael Kelley @ 2025-06-11 23:06 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org
  Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, catalin.marinas@arm.com, will@kernel.org,
	tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, hpa@zytor.com, lpieralisi@kernel.org,
	kw@linux.com, manivannan.sadhasivam@linaro.org, robh@kernel.org,
	bhelgaas@google.com, jinankjain@linux.microsoft.com,
	skinsburskii@linux.microsoft.com, mrathor@linux.microsoft.com,
	x86@kernel.org
In-Reply-To: <1749599526-19963-3-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Tuesday, June 10, 2025 4:52 PM
> 
> When running nested, these hypercalls must be sent to the L0 hypervisor
> or vmbus will fail.

s/vmbus/VMBus/

> 
> Add ARM64 stubs for the nested hypercall helpers to not break
> compilation (nested is still only supported in x86).
> 
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
>  arch/arm64/include/asm/mshyperv.h | 10 ++++++++++
>  drivers/hv/connection.c           |  3 +++
>  drivers/hv/hv.c                   |  3 +++
>  3 files changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/mshyperv.h
> b/arch/arm64/include/asm/mshyperv.h
> index b721d3134ab6..893d6a2e8dab 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -53,6 +53,16 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
>  	return hv_get_msr(reg);
>  }
> 
> +static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output)
> +{
> +	return U64_MAX;
> +}
> +
> +static inline u64 hv_do_fast_nested_hypercall8(u64 control, u64 input1)
> +{
> +	return U64_MAX;
> +}

I think the definitions of hv_do_nested_hypercall() and
hv_do_fast_nested_hypercall8() are architecture independent. All
they do is add the HV_HYPERCALL_NESTED flag, which when
implemented for ARM64, will presumably be the same flag as
currently defined for x86.  As such, couldn't the definitions of
hv_do_nested_hypercall() and hv_do_fast_nested_hypercall8()
be moved to asm-generic/mshyperv.h? Then stubs would not
be needed for ARM64. These two functions would never be
called on ARM64 because hv_nested is never true on ARM64
(at least for now), but the code would compile. And if either
function was erroneously called on ARM64, presumably
Hyper-V would return an error because HV_HYPERCALL_NESTED
is set.

> +
>  /* SMCCC hypercall parameters */
>  #define HV_SMCCC_FUNC_NUMBER	1
>  #define HV_FUNC_ID	ARM_SMCCC_CALL_VAL(			\
> diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
> index be490c598785..992022bc770c 100644
> --- a/drivers/hv/connection.c
> +++ b/drivers/hv/connection.c
> @@ -518,6 +518,9 @@ void vmbus_set_event(struct vmbus_channel *channel)
>  					 channel->sig_event, 0);
>  		else
>  			WARN_ON_ONCE(1);
> +	} else if (hv_nested) {
> +		hv_do_fast_nested_hypercall8(HVCALL_SIGNAL_EVENT,
> +					     channel->sig_event);
>  	} else {
>  		hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
>  	}
> diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
> index 308c8f279df8..99b73e779bf0 100644
> --- a/drivers/hv/hv.c
> +++ b/drivers/hv/hv.c
> @@ -84,6 +84,9 @@ int hv_post_message(union hv_connection_id connection_id,
>  						   sizeof(*aligned_msg));
>  		else
>  			status = HV_STATUS_INVALID_PARAMETER;
> +	} else if (hv_nested) {
> +		status = hv_do_nested_hypercall(HVCALL_POST_MESSAGE,
> +						aligned_msg, NULL);
>  	} else {
>  		status = hv_do_hypercall(HVCALL_POST_MESSAGE,
>  					 aligned_msg, NULL);

Are HVCALL_SIGNAL_EVENT and HVCALL_POST_MESSAGE the only two
hypercalls that are ever expected to need a "nested" version? I'm
wondering if the function hv_do_nested_hypercall() and
hv_do_fast_nested_hypercall8() could be dropped entirely, and just
pass the first argument to hv_do_hypercall() or hv_do_fast_hypercall8()
as <hypercall_name> | HV_HYPERCALL_NESTED. For only two cases, a
little bit of open coding might be preferable to the overhead of defining
functions just to wrap the or'ing of HV_HYPERCALL_NESTED. 

The code above could then look like:

	} else {
		u64 control = HVCALL_POST_MESSAGE;

		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
		status = hv_do_hypercall(control, aligned_msg, NULL);
	}

Again, ARM64 is implicitly handled because hv_nested is never set.

This is just a suggestion. It's motivated by the fact that we already have
three flavors of hypercall for HVCALL_SIGNAL_EVENT and
HVCALL_POST_MESSAGE, and I was looking for a way to avoid adding
a fourth flavor. But it's a marginal win, and if you prefer to keep the
inline functions, I'm OK with that.

Michael

^ permalink raw reply

* RE: [PATCH 1/4] PCI: hv: Do not do vmbus initialization on baremetal
From: Michael Kelley @ 2025-06-11 23:06 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org
  Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, catalin.marinas@arm.com, will@kernel.org,
	tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, hpa@zytor.com, lpieralisi@kernel.org,
	kw@linux.com, manivannan.sadhasivam@linaro.org, robh@kernel.org,
	bhelgaas@google.com, jinankjain@linux.microsoft.com,
	skinsburskii@linux.microsoft.com, mrathor@linux.microsoft.com,
	x86@kernel.org
In-Reply-To: <1749599526-19963-2-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Tuesday, June 10, 2025 4:52 PM
> 
> From: Mukesh Rathor <mrathor@linux.microsoft.com>

The patch Subject line is confusing to me. Perhaps this better captures
the intent:

 "PCI: hv: Don't load the driver for the root partition on a bare-metal hypervisor"

> 
> init_hv_pci_drv() is not relevant for root partition on baremetal as there
> is no vmbus. On nested (with a Windows L1 root), vmbus is present.

This needs more precision. init_hv_pci_drv() isn't what is
"not relevant". It's the entire driver that doesn't need to be loaded
because the root partition on a bare-metal hypervisor doesn't use
VMBus. It's only when the root partition is running on a nested
hypervisor that it uses VMBus, and hence may need the Hyper-V
PCI driver to be loaded.

> 
> Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
>  drivers/pci/controller/pci-hyperv.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index b4f29ee75848..4d25754dfe2f 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -4150,6 +4150,9 @@ static int __init init_hv_pci_drv(void)
>  	if (!hv_is_hyperv_initialized())
>  		return -ENODEV;
> 
> +	if (hv_root_partition() && !hv_nested)
> +		return -ENODEV;
> +
>  	ret = hv_pci_irqchip_init();
>  	if (ret)
>  		return ret;
> --
> 2.34.1


^ permalink raw reply

* Re: [PATCH v5 2/2] Drivers: hv: Introduce mshv_vtl driver
From: Easwar Hariharan @ 2025-06-11 18:00 UTC (permalink / raw)
  To: Nuno Das Neves
  Cc: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, eahariha, Roman Kisel, Anirudh Rayabharam,
	Saurabh Sengar, Stanislav Kinsburskii, ALOK TIWARI, linux-kernel,
	linux-hyperv
In-Reply-To: <2f2a252f-c2cb-40ee-a416-c07fd120dd49@linux.microsoft.com>

On 6/11/2025 9:46 AM, Nuno Das Neves wrote:
> On 6/11/2025 12:27 AM, Naman Jain wrote:
>> Provide an interface for Virtual Machine Monitor like OpenVMM and its
>> use as OpenHCL paravisor to control VTL0 (Virtual trust Level).
>> Expose devices and support IOCTLs for features like VTL creation,
>> VTL0 memory management, context switch, making hypercalls,
>> mapping VTL0 address space to VTL2 userspace, getting new VMBus
>> messages and channel events in VTL2 etc.
>>
>> Co-developed-by: Roman Kisel <romank@linux.microsoft.com>
>> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
>> Co-developed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
>> Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
>> Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
>> Reviewed-by: Alok Tiwari <alok.a.tiwari@oracle.com>
>> Message-ID: <20250512140432.2387503-3-namjain@linux.microsoft.com>
>> Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
>> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
>> ---
>>  drivers/hv/Kconfig          |   23 +
>>  drivers/hv/Makefile         |    7 +-
>>  drivers/hv/mshv_vtl.h       |   52 +
>>  drivers/hv/mshv_vtl_main.c  | 1783 +++++++++++++++++++++++++++++++++++
>>  include/hyperv/hvgdk_mini.h |   81 ++
>>  include/hyperv/hvhdk.h      |    1 +
>>  include/uapi/linux/mshv.h   |   82 ++
>>  7 files changed, 2028 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/hv/mshv_vtl.h
>>  create mode 100644 drivers/hv/mshv_vtl_main.c
>>

<snip>

> 
> Reviewed-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>

Hi Nuno,

In the future, please trim unnecessary context, example above, following 
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#use-trimmed-interleaved-replies-in-email-discussions

"Similarly, please trim all unneeded quotations that aren’t relevant to your reply.
This makes responses easier to find, and saves time and space. For more details see:
 http://daringfireball.net/2007/07/on_top"

Thanks,
Easwar (he/him)

^ permalink raw reply

* Re: [PATCH 0/4] Nested virtualization fixes for root partition
From: Roman Kisel @ 2025-06-11 17:55 UTC (permalink / raw)
  To: Nuno Das Neves
  Cc: kys, haiyangz, wei.liu, mhklinux, decui, catalin.marinas, will,
	tglx, mingo, bp, dave.hansen, hpa, lpieralisi, kw,
	manivannan.sadhasivam, robh, bhelgaas, jinankjain, skinsburskii,
	mrathor, x86, linux-hyperv, linux-arm-kernel, linux-kernel,
	linux-pci
In-Reply-To: <1749599526-19963-1-git-send-email-nunodasneves@linux.microsoft.com>



On 6/10/2025 4:52 PM, Nuno Das Neves wrote:
> Fixes for running as nested root partition on the Microsoft Hypervisor.
> 
> The first patch prevents the vmbus driver being registered on baremetal, since
> there's no vmbus in this scenario.
> 
> The second patch changes vmbus to make hypercalls to the L0 hypervisor instead
> of the L1. This is needed because L0 hypervisor, not the L1, is the one hosting
> the Windows root partition with the VMM that provides vmbus.
> 
> The 3rd and 4th patches fix interrupt unmasking on nested. In this scenario,
> the L1 (nested) hypervisor does the interrupt mapping to root partition cores.
> The vectors just need to be mapped with MAP_DEVICE_INTERRUPT instead of
> affinitized with RETARGET_INTERRUPT.
> 
> Mukesh Rathor (1):
>    PCI: hv: Do not do vmbus initialization on baremetal
> 
> Nuno Das Neves (1):
>    Drivers: hv: Use nested hypercall for post message and signal event
> 
> Stanislav Kinsburskii (2):
>    x86: hyperv: Expose hv_map_msi_interrupt function
>    PCI: hv: Use the correct hypercall for unmasking interrupts on nested
> 
>   arch/arm64/include/asm/mshyperv.h   | 10 ++++++
>   arch/x86/hyperv/irqdomain.c         | 47 +++++++++++++++++++++--------
>   arch/x86/include/asm/mshyperv.h     |  2 ++
>   drivers/hv/connection.c             |  3 ++
>   drivers/hv/hv.c                     |  3 ++
>   drivers/pci/controller/pci-hyperv.c | 21 +++++++++++--
>   6 files changed, 71 insertions(+), 15 deletions(-)
> 

Very cool stuff :) LGTM.

For the patch series:
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>

-- 
Thank you,
Roman


^ permalink raw reply

* RE: [PATCH net-next 1/4] net: mana: Fix potential deadlocks in mana napi ops
From: Long Li @ 2025-06-11 17:36 UTC (permalink / raw)
  To: Saurabh Singh Sengar, Erni Sri Satya Vennela
  Cc: KY Srinivasan, Haiyang Zhang, wei.liu@kernel.org, Dexuan Cui,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, Konstantin Taranov,
	horms@kernel.org, Shiraz Saleem, leon@kernel.org,
	shradhagupta@linux.microsoft.com,
	schakrabarti@linux.microsoft.com, rosenp@gmail.com,
	sdf@fomichev.me, linux-hyperv@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-rdma@vger.kernel.org
In-Reply-To: <20250611125509.GA22813@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>

> Subject: Re: [PATCH net-next 1/4] net: mana: Fix potential deadlocks in mana
> napi ops
> 
> On Wed, Jun 11, 2025 at 04:03:52AM -0700, Saurabh Singh Sengar wrote:
> > On Wed, Jun 11, 2025 at 01:46:13AM -0700, Erni Sri Satya Vennela wrote:
> > > When net_shaper_ops are enabled for MANA, netdev_ops_lock becomes
> > > active.
> > >
> > > The netvsc sets up MANA VF via following call chain:
> > >
> > > netvsc_vf_setup()
> > >         dev_change_flags()
> > > 		...
> > >          __dev_open() OR __dev_close()
> > >
> > > dev_change_flags() holds the netdev mutex via netdev_lock_ops.
> > >
> > > During this process, mana_create_txq() and mana_create_rxq() invoke
> > > netif_napi_add_tx(), netif_napi_add_weight(), and napi_enable(), all
> > > of which attempt to acquire the same lock, leading to a potential
> > > deadlock.
> >
> > commit message could be better oriented.
> >
> > >
> > > Similarly, mana_destroy_txq() and mana_destroy_rxq() call
> > > netif_napi_disable() and netif_napi_del(), which also contend for
> > > the same lock.
> > >
> > > Switch to the _locked variants of these APIs to avoid deadlocks when
> > > the netdev_ops_lock is held.
> > >
> > > Fixes: d4c22ec680c8 ("net: hold netdev instance lock during
> > > ndo_open/ndo_stop")
> > > Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> > > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> > > ---
> > >  drivers/net/ethernet/microsoft/mana/mana_en.c | 39
> > > ++++++++++++++-----
> > >  1 file changed, 30 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > index ccd2885c939e..3c879d8a39e3 100644
> > > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > > @@ -1911,8 +1911,13 @@ static void mana_destroy_txq(struct
> mana_port_context *apc)
> > >  		napi = &apc->tx_qp[i].tx_cq.napi;
> > >  		if (apc->tx_qp[i].txq.napi_initialized) {
> > >  			napi_synchronize(napi);
> > > -			napi_disable(napi);
> > > -			netif_napi_del(napi);
> > > +			if (netdev_need_ops_lock(napi->dev)) {
> > > +				napi_disable_locked(napi);
> > > +				netif_napi_del_locked(napi);
> > > +			} else {
> > > +				napi_disable(napi);
> > > +				netif_napi_del(napi);
> > > +			}
> >
> > Instead of using if-else, we can used netdev_lock_ops(), followed by *_locked
> api-s.
> > Same for rest of the patch.
> >
> 
> I later realized that what we actually need is:
> 
>   if (!netdev_need_ops_lock(napi->dev))
> 	netdev_lock(dev);
> 
> not
> 
>   if (netdev_need_ops_lock(napi->dev))
>         netdev_lock(dev);
> 
> Hence, netdev_lock_ops() is not appropriate. Instead, netdev_lock_ops_to_full()
> seems to be a better choice.

Yes, netdev_lock_ops_to_full() seems better.

Long

^ permalink raw reply

* Re: [PATCH 1/6] Drivers: hv: Fix warnings for missing export.h header inclusion
From: Nuno Das Neves @ 2025-06-11 16:50 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, Vitaly Kuznetsov,
	Sean Christopherson, Paolo Bonzini, Daniel Lezcano, Andrew Lunn,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
	Konstantin Taranov, Leon Romanovsky, Long Li, Shiraz Saleem,
	Shradha Gupta, Maxim Levitsky, Peter Zijlstra,
	Erni Sri Satya Vennela, Souradeep Chakrabarti
  Cc: linux-hyperv, linux-kernel, kvm, netdev, linux-pci
In-Reply-To: <20250611100459.92900-2-namjain@linux.microsoft.com>

On 6/11/2025 3:04 AM, Naman Jain wrote:
> Fix below warning in Hyper-V drivers that comes when kernel is compiled
> with W=1 option. Include export.h in driver files to fix it.
> * warning: EXPORT_SYMBOL() is used, but #include <linux/export.h>
> is missing
> 
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  drivers/hv/channel.c           | 1 +
>  drivers/hv/channel_mgmt.c      | 1 +
>  drivers/hv/hv_proc.c           | 1 +
>  drivers/hv/mshv_common.c       | 1 +
>  drivers/hv/mshv_root_hv_call.c | 1 +
>  drivers/hv/ring_buffer.c       | 1 +
>  6 files changed, 6 insertions(+)
> 
> diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
> index 35f26fa1ffe7..7c7c66e0dc3f 100644
> --- a/drivers/hv/channel.c
> +++ b/drivers/hv/channel.c
> @@ -18,6 +18,7 @@
>  #include <linux/uio.h>
>  #include <linux/interrupt.h>
>  #include <linux/set_memory.h>
> +#include <linux/export.h>
>  #include <asm/page.h>
>  #include <asm/mshyperv.h>
>  
> diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
> index 6e084c207414..65dd299e2944 100644
> --- a/drivers/hv/channel_mgmt.c
> +++ b/drivers/hv/channel_mgmt.c
> @@ -20,6 +20,7 @@
>  #include <linux/delay.h>
>  #include <linux/cpu.h>
>  #include <linux/hyperv.h>
> +#include <linux/export.h>
>  #include <asm/mshyperv.h>
>  #include <linux/sched/isolation.h>
>  
> diff --git a/drivers/hv/hv_proc.c b/drivers/hv/hv_proc.c
> index 7d7ecb6f6137..fbb4eb3901bb 100644
> --- a/drivers/hv/hv_proc.c
> +++ b/drivers/hv/hv_proc.c
> @@ -6,6 +6,7 @@
>  #include <linux/slab.h>
>  #include <linux/cpuhotplug.h>
>  #include <linux/minmax.h>
> +#include <linux/export.h>
>  #include <asm/mshyperv.h>
>  
>  /*
> diff --git a/drivers/hv/mshv_common.c b/drivers/hv/mshv_common.c
> index 2575e6d7a71f..6f227a8a5af7 100644
> --- a/drivers/hv/mshv_common.c
> +++ b/drivers/hv/mshv_common.c
> @@ -13,6 +13,7 @@
>  #include <linux/mm.h>
>  #include <asm/mshyperv.h>
>  #include <linux/resume_user_mode.h>
> +#include <linux/export.h>
>  
>  #include "mshv.h"
>  
> diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
> index a222a16107f6..c9c274f29c3c 100644
> --- a/drivers/hv/mshv_root_hv_call.c
> +++ b/drivers/hv/mshv_root_hv_call.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/mm.h>
> +#include <linux/export.h>
>  #include <asm/mshyperv.h>
>  
>  #include "mshv_root.h"
> diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
> index 3c9b02471760..23ce1fb70de1 100644
> --- a/drivers/hv/ring_buffer.c
> +++ b/drivers/hv/ring_buffer.c
> @@ -18,6 +18,7 @@
>  #include <linux/slab.h>
>  #include <linux/prefetch.h>
>  #include <linux/io.h>
> +#include <linux/export.h>
>  #include <asm/mshyperv.h>
>  
>  #include "hyperv_vmbus.h"

Reviewed-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>

^ permalink raw reply

* Re: [PATCH v5 2/2] Drivers: hv: Introduce mshv_vtl driver
From: Nuno Das Neves @ 2025-06-11 16:46 UTC (permalink / raw)
  To: Naman Jain, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui
  Cc: Roman Kisel, Anirudh Rayabharam, Saurabh Sengar,
	Stanislav Kinsburskii, ALOK TIWARI, linux-kernel, linux-hyperv
In-Reply-To: <20250611072704.83199-3-namjain@linux.microsoft.com>

On 6/11/2025 12:27 AM, Naman Jain wrote:
> Provide an interface for Virtual Machine Monitor like OpenVMM and its
> use as OpenHCL paravisor to control VTL0 (Virtual trust Level).
> Expose devices and support IOCTLs for features like VTL creation,
> VTL0 memory management, context switch, making hypercalls,
> mapping VTL0 address space to VTL2 userspace, getting new VMBus
> messages and channel events in VTL2 etc.
> 
> Co-developed-by: Roman Kisel <romank@linux.microsoft.com>
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Co-developed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
> Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
> Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
> Reviewed-by: Alok Tiwari <alok.a.tiwari@oracle.com>
> Message-ID: <20250512140432.2387503-3-namjain@linux.microsoft.com>
> Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
>  drivers/hv/Kconfig          |   23 +
>  drivers/hv/Makefile         |    7 +-
>  drivers/hv/mshv_vtl.h       |   52 +
>  drivers/hv/mshv_vtl_main.c  | 1783 +++++++++++++++++++++++++++++++++++
>  include/hyperv/hvgdk_mini.h |   81 ++
>  include/hyperv/hvhdk.h      |    1 +
>  include/uapi/linux/mshv.h   |   82 ++
>  7 files changed, 2028 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/hv/mshv_vtl.h
>  create mode 100644 drivers/hv/mshv_vtl_main.c
> 
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> index 1cd188b73b74..1403b4abbece 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -73,4 +73,27 @@ config MSHV_ROOT
>  
>  	  If unsure, say N.
>  
> +config MSHV_VTL
> +	tristate "Microsoft Hyper-V VTL driver"
> +	depends on HYPERV && X86_64
> +	# Mapping VTL0 memory to a userspace process in VTL2 is supported in OpenHCL.
> +	# VTL2 for OpenHCL makes use of Huge Pages to improve performance on VMs,
> +	# specially with large memory requirements.
> +	depends on TRANSPARENT_HUGEPAGE
> +	# MTRRs are controlled by VTL0, and are not specific to individual VTLs.
> +	# Therefore, do not attempt to access or modify MTRRs here.
> +	depends on !MTRR
> +	select CPUMASK_OFFSTACK
> +	select HYPERV_VTL_MODE
> +	default n
> +	help
> +	  Select this option to enable Hyper-V VTL driver support.
> +	  This driver provides interfaces for Virtual Machine Manager (VMM) running in VTL2
> +	  userspace to create VTLs and partitions, setup and manage VTL0 memory and
> +	  allow userspace to make direct hypercalls. This also allows to map VTL0's address
> +	  space to a usermode process in VTL2 and supports getting new VMBus messages and channel
> +	  events in VTL2.
> +
> +	  If unsure, say N.
> +
>  endmenu
> diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
> index 976189c725dc..c53a0df746b7 100644
> --- a/drivers/hv/Makefile
> +++ b/drivers/hv/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_HYPERV)		+= hv_vmbus.o
>  obj-$(CONFIG_HYPERV_UTILS)	+= hv_utils.o
>  obj-$(CONFIG_HYPERV_BALLOON)	+= hv_balloon.o
>  obj-$(CONFIG_MSHV_ROOT)		+= mshv_root.o
> +obj-$(CONFIG_MSHV_VTL)          += mshv_vtl.o
>  
>  CFLAGS_hv_trace.o = -I$(src)
>  CFLAGS_hv_balloon.o = -I$(src)
> @@ -14,7 +15,11 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING)	+= hv_debugfs.o
>  hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o
>  mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \
>  	       mshv_root_hv_call.o mshv_portid_table.o
> +mshv_vtl-y := mshv_vtl_main.o
>  
>  # Code that must be built-in
>  obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o
> -obj-$(subst m,y,$(CONFIG_MSHV_ROOT)) += hv_proc.o mshv_common.o
> +obj-$(subst m,y,$(CONFIG_MSHV_ROOT)) += hv_proc.o
> +ifneq ($(CONFIG_MSHV_ROOT) $(CONFIG_MSHV_VTL),)
> +    obj-y += mshv_common.o
> +endif
> diff --git a/drivers/hv/mshv_vtl.h b/drivers/hv/mshv_vtl.h
> new file mode 100644
> index 000000000000..f765fda3601b
> --- /dev/null
> +++ b/drivers/hv/mshv_vtl.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _MSHV_VTL_H
> +#define _MSHV_VTL_H
> +
> +#include <linux/mshv.h>
> +#include <linux/types.h>
> +#include <asm/fpu/types.h>
> +
> +struct mshv_vtl_cpu_context {
> +	union {
> +		struct {
> +			u64 rax;
> +			u64 rcx;
> +			u64 rdx;
> +			u64 rbx;
> +			u64 cr2;
> +			u64 rbp;
> +			u64 rsi;
> +			u64 rdi;
> +			u64 r8;
> +			u64 r9;
> +			u64 r10;
> +			u64 r11;
> +			u64 r12;
> +			u64 r13;
> +			u64 r14;
> +			u64 r15;
> +		};
> +		u64 gp_regs[16];
> +	};
> +
> +	struct fxregs_state fx_state;
> +};
> +
> +struct mshv_vtl_run {
> +	u32 cancel;
> +	u32 vtl_ret_action_size;
> +	u32 pad[2];
> +	char exit_message[MSHV_MAX_RUN_MSG_SIZE];
> +	union {
> +		struct mshv_vtl_cpu_context cpu_context;
> +
> +		/*
> +		 * Reserving room for the cpu context to grow and to maintain compatibility
> +		 * with user mode.
> +		 */
> +		char reserved[1024];
> +	};
> +	char vtl_ret_actions[MSHV_MAX_RUN_MSG_SIZE];
> +};
> +
> +#endif /* _MSHV_VTL_H */
> diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c
> new file mode 100644
> index 000000000000..b1717b118772
> --- /dev/null
> +++ b/drivers/hv/mshv_vtl_main.c
> @@ -0,0 +1,1783 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2023, Microsoft Corporation.
> + *
> + * Author:
> + *   Roman Kisel <romank@linux.microsoft.com>
> + *   Saurabh Sengar <ssengar@linux.microsoft.com>
> + *   Naman Jain <namjain@linux.microsoft.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/miscdevice.h>
> +#include <linux/anon_inodes.h>
> +#include <linux/pfn_t.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/count_zeros.h>
> +#include <linux/eventfd.h>
> +#include <linux/poll.h>
> +#include <linux/file.h>
> +#include <linux/vmalloc.h>
> +#include <asm/debugreg.h>
> +#include <asm/mshyperv.h>
> +#include <trace/events/ipi.h>
> +#include <uapi/asm/mtrr.h>
> +#include <uapi/linux/mshv.h>
> +#include <hyperv/hvhdk.h>
> +
> +#include "../../kernel/fpu/legacy.h"
> +#include "mshv.h"
> +#include "mshv_vtl.h"
> +#include "hyperv_vmbus.h"
> +
> +MODULE_AUTHOR("Microsoft");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Microsoft Hyper-V VTL Driver");
> +
> +#define MSHV_ENTRY_REASON_LOWER_VTL_CALL     0x1
> +#define MSHV_ENTRY_REASON_INTERRUPT          0x2
> +#define MSHV_ENTRY_REASON_INTERCEPT          0x3
> +
> +#define MAX_GUEST_MEM_SIZE	BIT_ULL(40)
> +#define MSHV_PG_OFF_CPU_MASK	0xFFFF
> +#define MSHV_REAL_OFF_SHIFT	16
> +#define MSHV_RUN_PAGE_OFFSET	0
> +#define MSHV_REG_PAGE_OFFSET	1
> +#define VTL2_VMBUS_SINT_INDEX	7
> +
> +static struct device *mem_dev;
> +
> +static struct tasklet_struct msg_dpc;
> +static wait_queue_head_t fd_wait_queue;
> +static bool has_message;
> +static struct eventfd_ctx *flag_eventfds[HV_EVENT_FLAGS_COUNT];
> +static DEFINE_MUTEX(flag_lock);
> +static bool __read_mostly mshv_has_reg_page;
> +
> +struct mshv_vtl_hvcall_fd {
> +	u64 allow_bitmap[2 * PAGE_SIZE];
> +	bool allow_map_initialized;
> +	/*
> +	 * Used to protect hvcall setup in IOCTLs
> +	 */
> +	struct mutex init_mutex;
> +	struct miscdevice *dev;
> +};
> +
> +struct mshv_vtl_poll_file {
> +	struct file *file;
> +	wait_queue_entry_t wait;
> +	wait_queue_head_t *wqh;
> +	poll_table pt;
> +	int cpu;
> +};
> +
> +struct mshv_vtl {
> +	struct device *module_dev;
> +	u64 id;
> +};
> +
> +union mshv_synic_overlay_page_msr {
> +	u64 as_uint64;
> +	struct {
> +		u64 enabled: 1;
> +		u64 reserved: 11;
> +		u64 pfn: 52;
> +	};
> +};
> +
> +union hv_register_vsm_capabilities {
> +	u64 as_uint64;
> +	struct {
> +		u64 dr6_shared: 1;
> +		u64 mbec_vtl_mask: 16;
> +		u64 deny_lower_vtl_startup: 1;
> +		u64 supervisor_shadow_stack: 1;
> +		u64 hardware_hvpt_available: 1;
> +		u64 software_hvpt_available: 1;
> +		u64 hardware_hvpt_range_bits: 6;
> +		u64 intercept_page_available: 1;
> +		u64 return_action_available: 1;
> +		u64 reserved: 35;
> +	} __packed;
> +};
> +
> +union hv_register_vsm_page_offsets {
> +	struct {
> +		u64 vtl_call_offset : 12;
> +		u64 vtl_return_offset : 12;
> +		u64 reserved_mbz : 40;
> +	};
> +	u64 as_uint64;
> +} __packed;
> +
> +struct mshv_vtl_per_cpu {
> +	struct mshv_vtl_run *run;
> +	struct page *reg_page;
> +};
> +
> +static struct mutex mshv_vtl_poll_file_lock;
> +static union hv_register_vsm_page_offsets mshv_vsm_page_offsets;
> +static union hv_register_vsm_capabilities mshv_vsm_capabilities;
> +
> +static DEFINE_PER_CPU(struct mshv_vtl_poll_file, mshv_vtl_poll_file);
> +static DEFINE_PER_CPU(unsigned long long, num_vtl0_transitions);
> +static DEFINE_PER_CPU(struct mshv_vtl_per_cpu, mshv_vtl_per_cpu);
> +
> +static const struct file_operations mshv_vtl_fops;
> +
> +static long
> +mshv_ioctl_create_vtl(void __user *user_arg, struct device *module_dev)
> +{
> +	struct mshv_vtl *vtl;
> +	struct file *file;
> +	int fd;
> +
> +	vtl = kzalloc(sizeof(*vtl), GFP_KERNEL);
> +	if (!vtl)
> +		return -ENOMEM;
> +
> +	fd = get_unused_fd_flags(O_CLOEXEC);
> +	if (fd < 0) {
> +		kfree(vtl);
> +		return fd;
> +	}
> +	file = anon_inode_getfile("mshv_vtl", &mshv_vtl_fops,
> +				  vtl, O_RDWR);
> +	if (IS_ERR(file)) {
> +		kfree(vtl);
> +		return PTR_ERR(file);
> +	}
> +	vtl->module_dev = module_dev;
> +	fd_install(fd, file);
> +
> +	return fd;
> +}
> +
> +static long
> +mshv_ioctl_check_extension(void __user *user_arg)
> +{
> +	u32 arg;
> +
> +	if (copy_from_user(&arg, user_arg, sizeof(arg)))
> +		return -EFAULT;
> +
> +	switch (arg) {
> +	case MSHV_CAP_CORE_API_STABLE:
> +		return 0;
> +	case MSHV_CAP_REGISTER_PAGE:
> +		return mshv_has_reg_page;
> +	case MSHV_CAP_VTL_RETURN_ACTION:
> +		return mshv_vsm_capabilities.return_action_available;
> +	case MSHV_CAP_DR6_SHARED:
> +		return mshv_vsm_capabilities.dr6_shared;
> +	}
> +
> +	return -EOPNOTSUPP;
> +}
> +
> +static long
> +mshv_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
> +{
> +	struct miscdevice *misc = filp->private_data;
> +
> +	switch (ioctl) {
> +	case MSHV_CHECK_EXTENSION:
> +		return mshv_ioctl_check_extension((void __user *)arg);
> +	case MSHV_CREATE_VTL:
> +		return mshv_ioctl_create_vtl((void __user *)arg, misc->this_device);
> +	}
> +
> +	return -ENOTTY;
> +}
> +
> +static const struct file_operations mshv_dev_fops = {
> +	.owner		= THIS_MODULE,
> +	.unlocked_ioctl	= mshv_dev_ioctl,
> +	.llseek		= noop_llseek,
> +};
> +
> +static struct miscdevice mshv_dev = {
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.name = "mshv",
> +	.fops = &mshv_dev_fops,
> +	.mode = 0600,
> +};
> +
> +static struct mshv_vtl_run *mshv_vtl_this_run(void)
> +{
> +	return *this_cpu_ptr(&mshv_vtl_per_cpu.run);
> +}
> +
> +static struct mshv_vtl_run *mshv_vtl_cpu_run(int cpu)
> +{
> +	return *per_cpu_ptr(&mshv_vtl_per_cpu.run, cpu);
> +}
> +
> +static struct page *mshv_vtl_cpu_reg_page(int cpu)
> +{
> +	return *per_cpu_ptr(&mshv_vtl_per_cpu.reg_page, cpu);
> +}
> +
> +static void mshv_vtl_configure_reg_page(struct mshv_vtl_per_cpu *per_cpu)
> +{
> +	struct hv_register_assoc reg_assoc = {};
> +	union mshv_synic_overlay_page_msr overlay = {};
> +	struct page *reg_page;
> +	union hv_input_vtl vtl = { .as_uint8 = 0 };
> +
> +	reg_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL);
> +	if (!reg_page) {
> +		WARN(1, "failed to allocate register page\n");
> +		return;
> +	}
> +
> +	overlay.enabled = 1;
> +	overlay.pfn = page_to_phys(reg_page) >> HV_HYP_PAGE_SHIFT;
> +	reg_assoc.name = HV_X64_REGISTER_REG_PAGE;
> +	reg_assoc.value.reg64 = overlay.as_uint64;
> +
> +	if (hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> +				     1, vtl, &reg_assoc)) {
> +		WARN(1, "failed to setup register page\n");
> +		__free_page(reg_page);
> +		return;
> +	}
> +
> +	per_cpu->reg_page = reg_page;
> +	mshv_has_reg_page = true;
> +}
> +
> +static void mshv_vtl_synic_enable_regs(unsigned int cpu)
> +{
> +	union hv_synic_sint sint;
> +
> +	sint.as_uint64 = 0;
> +	sint.vector = HYPERVISOR_CALLBACK_VECTOR;
> +	sint.masked = false;
> +	sint.auto_eoi = hv_recommend_using_aeoi();
> +
> +	/* Enable intercepts */
> +	if (!mshv_vsm_capabilities.intercept_page_available)
> +		hv_set_msr(HV_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX,
> +			   sint.as_uint64);
> +
> +	/* VTL2 Host VSP SINT is (un)masked when the user mode requests that */
> +}
> +
> +static int mshv_vtl_get_vsm_regs(void)
> +{
> +	struct hv_register_assoc registers[2];
> +	union hv_input_vtl input_vtl;
> +	int ret, count = 2;
> +
> +	input_vtl.as_uint8 = 0;
> +	registers[0].name = HV_REGISTER_VSM_CODE_PAGE_OFFSETS;
> +	registers[1].name = HV_REGISTER_VSM_CAPABILITIES;
> +
> +	ret = hv_call_get_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> +				       count, input_vtl, registers);
> +	if (ret)
> +		return ret;
> +
> +	mshv_vsm_page_offsets.as_uint64 = registers[0].value.reg64;
> +	mshv_vsm_capabilities.as_uint64 = registers[1].value.reg64;
> +
> +	return ret;
> +}
> +
> +static int mshv_vtl_configure_vsm_partition(struct device *dev)
> +{
> +	union hv_register_vsm_partition_config config;
> +	struct hv_register_assoc reg_assoc;
> +	union hv_input_vtl input_vtl;
> +
> +	config.as_uint64 = 0;
> +	config.default_vtl_protection_mask = HV_MAP_GPA_PERMISSIONS_MASK;
> +	config.enable_vtl_protection = 1;
> +	config.zero_memory_on_reset = 1;
> +	config.intercept_vp_startup = 1;
> +	config.intercept_cpuid_unimplemented = 1;
> +
> +	if (mshv_vsm_capabilities.intercept_page_available) {
> +		dev_dbg(dev, "using intercept page\n");
> +		config.intercept_page = 1;
> +	}
> +
> +	reg_assoc.name = HV_REGISTER_VSM_PARTITION_CONFIG;
> +	reg_assoc.value.reg64 = config.as_uint64;
> +	input_vtl.as_uint8 = 0;
> +
> +	return hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> +				       1, input_vtl, &reg_assoc);
> +}
> +
> +static void mshv_vtl_vmbus_isr(void)
> +{
> +	struct hv_per_cpu_context *per_cpu;
> +	struct hv_message *msg;
> +	u32 message_type;
> +	union hv_synic_event_flags *event_flags;
> +	unsigned long word;
> +	int i, j;
> +	struct eventfd_ctx *eventfd;
> +
> +	per_cpu = this_cpu_ptr(hv_context.cpu_context);
> +	if (smp_processor_id() == 0) {
> +		msg = (struct hv_message *)per_cpu->synic_message_page + VTL2_VMBUS_SINT_INDEX;
> +		message_type = READ_ONCE(msg->header.message_type);
> +		if (message_type != HVMSG_NONE)
> +			tasklet_schedule(&msg_dpc);
> +	}
> +
> +	event_flags = (union hv_synic_event_flags *)per_cpu->synic_event_page +
> +			VTL2_VMBUS_SINT_INDEX;
> +	for (i = 0; i < HV_EVENT_FLAGS_LONG_COUNT; i++) {
> +		if (READ_ONCE(event_flags->flags[i])) {
> +			word = xchg(&event_flags->flags[i], 0);
> +			for_each_set_bit(j, &word, BITS_PER_LONG) {
> +				rcu_read_lock();
> +				eventfd = READ_ONCE(flag_eventfds[i * BITS_PER_LONG + j]);
> +				if (eventfd)
> +					eventfd_signal(eventfd);
> +				rcu_read_unlock();
> +			}
> +		}
> +	}
> +
> +	vmbus_isr();
> +}
> +
> +static int mshv_vtl_alloc_context(unsigned int cpu)
> +{
> +	struct mshv_vtl_per_cpu *per_cpu = this_cpu_ptr(&mshv_vtl_per_cpu);
> +	struct page *run_page;
> +
> +	run_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +	if (!run_page)
> +		return -ENOMEM;
> +
> +	per_cpu->run = page_address(run_page);
> +	if (mshv_vsm_capabilities.intercept_page_available)
> +		mshv_vtl_configure_reg_page(per_cpu);
> +
> +	mshv_vtl_synic_enable_regs(cpu);
> +
> +	return 0;
> +}
> +
> +static int mshv_vtl_cpuhp_online;
> +
> +static int hv_vtl_setup_synic(void)
> +{
> +	int ret;
> +
> +	/* Use our isr to first filter out packets destined for userspace */
> +	hv_setup_vmbus_handler(mshv_vtl_vmbus_isr);
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hyperv/vtl:online",
> +				mshv_vtl_alloc_context, NULL);
> +	if (ret < 0) {
> +		hv_remove_vmbus_handler();
> +		return ret;
> +	}
> +
> +	mshv_vtl_cpuhp_online = ret;
> +
> +	return 0;
> +}
> +
> +static void hv_vtl_remove_synic(void)
> +{
> +	hv_remove_vmbus_handler();
> +	cpuhp_remove_state(mshv_vtl_cpuhp_online);
> +}
> +
> +static int vtl_get_vp_registers(u16 count,
> +				struct hv_register_assoc *registers)
> +{
> +	union hv_input_vtl input_vtl;
> +
> +	input_vtl.as_uint8 = 0;
> +	input_vtl.use_target_vtl = 1;
> +
> +	return hv_call_get_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> +					count, input_vtl, registers);
> +}
> +
> +static int vtl_set_vp_registers(u16 count,
> +				struct hv_register_assoc *registers)
> +{
> +	union hv_input_vtl input_vtl;
> +
> +	input_vtl.as_uint8 = 0;
> +	input_vtl.use_target_vtl = 1;
> +
> +	return hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
> +					count, input_vtl, registers);
> +}
> +
> +static int mshv_vtl_ioctl_add_vtl0_mem(struct mshv_vtl *vtl, void __user *arg)
> +{
> +	struct mshv_vtl_ram_disposition vtl0_mem;
> +	struct dev_pagemap *pgmap;
> +	void *addr;
> +
> +	if (copy_from_user(&vtl0_mem, arg, sizeof(vtl0_mem)))
> +		return -EFAULT;
> +
> +	if (vtl0_mem.last_pfn <= vtl0_mem.start_pfn) {
> +		dev_err(vtl->module_dev, "range start pfn (%llx) > end pfn (%llx)\n",
> +			vtl0_mem.start_pfn, vtl0_mem.last_pfn);
> +		return -EFAULT;
> +	}
> +
> +	pgmap = kzalloc(sizeof(*pgmap), GFP_KERNEL);
> +	if (!pgmap)
> +		return -ENOMEM;
> +
> +	pgmap->ranges[0].start = PFN_PHYS(vtl0_mem.start_pfn);
> +	pgmap->ranges[0].end = PFN_PHYS(vtl0_mem.last_pfn) - 1;
> +	pgmap->nr_range = 1;
> +	pgmap->type = MEMORY_DEVICE_GENERIC;
> +
> +	/*
> +	 * Determine the highest page order that can be used for the given memory range.
> +	 * This works best when the range is aligned; i.e. both the start and the length.
> +	 */
> +	pgmap->vmemmap_shift = count_trailing_zeros(vtl0_mem.start_pfn | vtl0_mem.last_pfn);
> +	dev_dbg(vtl->module_dev,
> +		"Add VTL0 memory: start: 0x%llx, end_pfn: 0x%llx, page order: %lu\n",
> +		vtl0_mem.start_pfn, vtl0_mem.last_pfn, pgmap->vmemmap_shift);
> +
> +	addr = devm_memremap_pages(mem_dev, pgmap);
> +	if (IS_ERR(addr)) {
> +		dev_err(vtl->module_dev, "devm_memremap_pages error: %ld\n", PTR_ERR(addr));
> +		kfree(pgmap);
> +		return -EFAULT;
> +	}
> +
> +	/* Don't free pgmap, since it has to stick around until the memory
> +	 * is unmapped, which will never happen as there is no scenario
> +	 * where VTL0 can be released/shutdown without bringing down VTL2.
> +	 */
> +	return 0;
> +}
> +
> +static void mshv_vtl_cancel(int cpu)
> +{
> +	int here = get_cpu();
> +
> +	if (here != cpu) {
> +		if (!xchg_relaxed(&mshv_vtl_cpu_run(cpu)->cancel, 1))
> +			smp_send_reschedule(cpu);
> +	} else {
> +		WRITE_ONCE(mshv_vtl_this_run()->cancel, 1);
> +	}
> +	put_cpu();
> +}
> +
> +static int mshv_vtl_poll_file_wake(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
> +{
> +	struct mshv_vtl_poll_file *poll_file = container_of(wait, struct mshv_vtl_poll_file, wait);
> +
> +	mshv_vtl_cancel(poll_file->cpu);
> +
> +	return 0;
> +}
> +
> +static void mshv_vtl_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, poll_table *pt)
> +{
> +	struct mshv_vtl_poll_file *poll_file = container_of(pt, struct mshv_vtl_poll_file, pt);
> +
> +	WARN_ON(poll_file->wqh);
> +	poll_file->wqh = wqh;
> +	add_wait_queue(wqh, &poll_file->wait);
> +}
> +
> +static int mshv_vtl_ioctl_set_poll_file(struct mshv_vtl_set_poll_file __user *user_input)
> +{
> +	struct file *file, *old_file;
> +	struct mshv_vtl_poll_file *poll_file;
> +	struct mshv_vtl_set_poll_file input;
> +
> +	if (copy_from_user(&input, user_input, sizeof(input)))
> +		return -EFAULT;
> +
> +	if (!cpu_online(input.cpu))
> +		return -EINVAL;
> +
> +	file = NULL;
> +	file = fget(input.fd);
> +	if (!file)
> +		return -EBADFD;
> +
> +	poll_file = per_cpu_ptr(&mshv_vtl_poll_file, READ_ONCE(input.cpu));
> +	if (!poll_file)
> +		return -EINVAL;
> +
> +	mutex_lock(&mshv_vtl_poll_file_lock);
> +
> +	if (poll_file->wqh)
> +		remove_wait_queue(poll_file->wqh, &poll_file->wait);
> +	poll_file->wqh = NULL;
> +
> +	old_file = poll_file->file;
> +	poll_file->file = file;
> +	poll_file->cpu = input.cpu;
> +
> +	if (file) {
> +		init_waitqueue_func_entry(&poll_file->wait, mshv_vtl_poll_file_wake);
> +		init_poll_funcptr(&poll_file->pt, mshv_vtl_ptable_queue_proc);
> +		vfs_poll(file, &poll_file->pt);
> +	}
> +
> +	mutex_unlock(&mshv_vtl_poll_file_lock);
> +
> +	if (old_file)
> +		fput(old_file);
> +
> +	return 0;
> +}
> +
> +static int mshv_vtl_set_reg(struct hv_register_assoc *regs)
> +{
> +	u64 reg64;
> +	enum hv_register_name gpr_name;
> +
> +	gpr_name = regs->name;
> +	reg64 = regs->value.reg64;
> +
> +	switch (gpr_name) {
> +	case HV_X64_REGISTER_DR0:
> +		native_set_debugreg(0, reg64);
> +		break;
> +	case HV_X64_REGISTER_DR1:
> +		native_set_debugreg(1, reg64);
> +		break;
> +	case HV_X64_REGISTER_DR2:
> +		native_set_debugreg(2, reg64);
> +		break;
> +	case HV_X64_REGISTER_DR3:
> +		native_set_debugreg(3, reg64);
> +		break;
> +	case HV_X64_REGISTER_DR6:
> +		if (!mshv_vsm_capabilities.dr6_shared)
> +			goto hypercall;
> +		native_set_debugreg(6, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_CAP:
> +		wrmsrl(MSR_MTRRcap, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_DEF_TYPE:
> +		wrmsrl(MSR_MTRRdefType, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0:
> +		wrmsrl(MTRRphysBase_MSR(0), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1:
> +		wrmsrl(MTRRphysBase_MSR(1), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2:
> +		wrmsrl(MTRRphysBase_MSR(2), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3:
> +		wrmsrl(MTRRphysBase_MSR(3), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4:
> +		wrmsrl(MTRRphysBase_MSR(4), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5:
> +		wrmsrl(MTRRphysBase_MSR(5), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6:
> +		wrmsrl(MTRRphysBase_MSR(6), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7:
> +		wrmsrl(MTRRphysBase_MSR(7), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE8:
> +		wrmsrl(MTRRphysBase_MSR(8), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE9:
> +		wrmsrl(MTRRphysBase_MSR(9), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEA:
> +		wrmsrl(MTRRphysBase_MSR(0xa), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEB:
> +		wrmsrl(MTRRphysBase_MSR(0xb), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEC:
> +		wrmsrl(MTRRphysBase_MSR(0xc), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASED:
> +		wrmsrl(MTRRphysBase_MSR(0xd), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEE:
> +		wrmsrl(MTRRphysBase_MSR(0xe), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEF:
> +		wrmsrl(MTRRphysBase_MSR(0xf), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0:
> +		wrmsrl(MTRRphysMask_MSR(0), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1:
> +		wrmsrl(MTRRphysMask_MSR(1), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2:
> +		wrmsrl(MTRRphysMask_MSR(2), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3:
> +		wrmsrl(MTRRphysMask_MSR(3), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4:
> +		wrmsrl(MTRRphysMask_MSR(4), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5:
> +		wrmsrl(MTRRphysMask_MSR(5), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6:
> +		wrmsrl(MTRRphysMask_MSR(6), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7:
> +		wrmsrl(MTRRphysMask_MSR(7), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK8:
> +		wrmsrl(MTRRphysMask_MSR(8), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK9:
> +		wrmsrl(MTRRphysMask_MSR(9), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKA:
> +		wrmsrl(MTRRphysMask_MSR(0xa), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKB:
> +		wrmsrl(MTRRphysMask_MSR(0xb), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKC:
> +		wrmsrl(MTRRphysMask_MSR(0xc), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKD:
> +		wrmsrl(MTRRphysMask_MSR(0xd), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKE:
> +		wrmsrl(MTRRphysMask_MSR(0xe), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKF:
> +		wrmsrl(MTRRphysMask_MSR(0xf), reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX64K00000:
> +		wrmsrl(MSR_MTRRfix64K_00000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX16K80000:
> +		wrmsrl(MSR_MTRRfix16K_80000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX16KA0000:
> +		wrmsrl(MSR_MTRRfix16K_A0000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KC0000:
> +		wrmsrl(MSR_MTRRfix4K_C0000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KC8000:
> +		wrmsrl(MSR_MTRRfix4K_C8000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KD0000:
> +		wrmsrl(MSR_MTRRfix4K_D0000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KD8000:
> +		wrmsrl(MSR_MTRRfix4K_D8000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KE0000:
> +		wrmsrl(MSR_MTRRfix4K_E0000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KE8000:
> +		wrmsrl(MSR_MTRRfix4K_E8000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KF0000:
> +		wrmsrl(MSR_MTRRfix4K_F0000, reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KF8000:
> +		wrmsrl(MSR_MTRRfix4K_F8000, reg64);
> +		break;
> +
> +	default:
> +		goto hypercall;
> +	}
> +
> +	return 0;
> +
> +hypercall:
> +	return 1;
> +}
> +
> +static int mshv_vtl_get_reg(struct hv_register_assoc *regs)
> +{
> +	u64 *reg64;
> +	enum hv_register_name gpr_name;
> +
> +	gpr_name = regs->name;
> +	reg64 = (u64 *)&regs->value.reg64;
> +
> +	switch (gpr_name) {
> +	case HV_X64_REGISTER_DR0:
> +		*reg64 = native_get_debugreg(0);
> +		break;
> +	case HV_X64_REGISTER_DR1:
> +		*reg64 = native_get_debugreg(1);
> +		break;
> +	case HV_X64_REGISTER_DR2:
> +		*reg64 = native_get_debugreg(2);
> +		break;
> +	case HV_X64_REGISTER_DR3:
> +		*reg64 = native_get_debugreg(3);
> +		break;
> +	case HV_X64_REGISTER_DR6:
> +		if (!mshv_vsm_capabilities.dr6_shared)
> +			goto hypercall;
> +		*reg64 = native_get_debugreg(6);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_CAP:
> +		rdmsrl(MSR_MTRRcap, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_DEF_TYPE:
> +		rdmsrl(MSR_MTRRdefType, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0:
> +		rdmsrl(MTRRphysBase_MSR(0), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1:
> +		rdmsrl(MTRRphysBase_MSR(1), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2:
> +		rdmsrl(MTRRphysBase_MSR(2), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3:
> +		rdmsrl(MTRRphysBase_MSR(3), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4:
> +		rdmsrl(MTRRphysBase_MSR(4), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5:
> +		rdmsrl(MTRRphysBase_MSR(5), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6:
> +		rdmsrl(MTRRphysBase_MSR(6), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7:
> +		rdmsrl(MTRRphysBase_MSR(7), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE8:
> +		rdmsrl(MTRRphysBase_MSR(8), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASE9:
> +		rdmsrl(MTRRphysBase_MSR(9), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEA:
> +		rdmsrl(MTRRphysBase_MSR(0xa), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEB:
> +		rdmsrl(MTRRphysBase_MSR(0xb), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEC:
> +		rdmsrl(MTRRphysBase_MSR(0xc), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASED:
> +		rdmsrl(MTRRphysBase_MSR(0xd), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEE:
> +		rdmsrl(MTRRphysBase_MSR(0xe), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_BASEF:
> +		rdmsrl(MTRRphysBase_MSR(0xf), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0:
> +		rdmsrl(MTRRphysMask_MSR(0), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1:
> +		rdmsrl(MTRRphysMask_MSR(1), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2:
> +		rdmsrl(MTRRphysMask_MSR(2), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3:
> +		rdmsrl(MTRRphysMask_MSR(3), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4:
> +		rdmsrl(MTRRphysMask_MSR(4), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5:
> +		rdmsrl(MTRRphysMask_MSR(5), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6:
> +		rdmsrl(MTRRphysMask_MSR(6), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7:
> +		rdmsrl(MTRRphysMask_MSR(7), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK8:
> +		rdmsrl(MTRRphysMask_MSR(8), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASK9:
> +		rdmsrl(MTRRphysMask_MSR(9), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKA:
> +		rdmsrl(MTRRphysMask_MSR(0xa), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKB:
> +		rdmsrl(MTRRphysMask_MSR(0xb), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKC:
> +		rdmsrl(MTRRphysMask_MSR(0xc), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKD:
> +		rdmsrl(MTRRphysMask_MSR(0xd), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKE:
> +		rdmsrl(MTRRphysMask_MSR(0xe), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_PHYS_MASKF:
> +		rdmsrl(MTRRphysMask_MSR(0xf), *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX64K00000:
> +		rdmsrl(MSR_MTRRfix64K_00000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX16K80000:
> +		rdmsrl(MSR_MTRRfix16K_80000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX16KA0000:
> +		rdmsrl(MSR_MTRRfix16K_A0000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KC0000:
> +		rdmsrl(MSR_MTRRfix4K_C0000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KC8000:
> +		rdmsrl(MSR_MTRRfix4K_C8000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KD0000:
> +		rdmsrl(MSR_MTRRfix4K_D0000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KD8000:
> +		rdmsrl(MSR_MTRRfix4K_D8000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KE0000:
> +		rdmsrl(MSR_MTRRfix4K_E0000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KE8000:
> +		rdmsrl(MSR_MTRRfix4K_E8000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KF0000:
> +		rdmsrl(MSR_MTRRfix4K_F0000, *reg64);
> +		break;
> +	case HV_X64_REGISTER_MSR_MTRR_FIX4KF8000:
> +		rdmsrl(MSR_MTRRfix4K_F8000, *reg64);
> +		break;
> +
> +	default:
> +		goto hypercall;
> +	}
> +
> +	return 0;
> +
> +hypercall:
> +	return 1;
> +}
> +
> +static void mshv_vtl_return(struct mshv_vtl_cpu_context *vtl0)
> +{
> +	struct hv_vp_assist_page *hvp;
> +	u64 hypercall_addr;
> +
> +	register u64 r8 asm("r8");
> +	register u64 r9 asm("r9");
> +	register u64 r10 asm("r10");
> +	register u64 r11 asm("r11");
> +	register u64 r12 asm("r12");
> +	register u64 r13 asm("r13");
> +	register u64 r14 asm("r14");
> +	register u64 r15 asm("r15");
> +
> +	hvp = hv_vp_assist_page[smp_processor_id()];
> +
> +	/*
> +	 * Process signal event direct set in the run page, if any.
> +	 */
> +	if (mshv_vsm_capabilities.return_action_available) {
> +		u32 offset = READ_ONCE(mshv_vtl_this_run()->vtl_ret_action_size);
> +
> +		WRITE_ONCE(mshv_vtl_this_run()->vtl_ret_action_size, 0);
> +
> +		/*
> +		 * Hypervisor will take care of clearing out the actions
> +		 * set in the assist page.
> +		 */
> +		memcpy(hvp->vtl_ret_actions,
> +		       mshv_vtl_this_run()->vtl_ret_actions,
> +		       min_t(u32, offset, sizeof(hvp->vtl_ret_actions)));
> +	}
> +
> +	hvp->vtl_ret_x64rax = vtl0->rax;
> +	hvp->vtl_ret_x64rcx = vtl0->rcx;
> +
> +	hypercall_addr = (u64)((u8 *)hv_hypercall_pg + mshv_vsm_page_offsets.vtl_return_offset);
> +
> +	kernel_fpu_begin_mask(0);
> +	fxrstor(&vtl0->fx_state);
> +	native_write_cr2(vtl0->cr2);
> +	r8 = vtl0->r8;
> +	r9 = vtl0->r9;
> +	r10 = vtl0->r10;
> +	r11 = vtl0->r11;
> +	r12 = vtl0->r12;
> +	r13 = vtl0->r13;
> +	r14 = vtl0->r14;
> +	r15 = vtl0->r15;
> +
> +	asm __volatile__ (	\
> +	/* Save rbp pointer to the lower VTL, keep the stack 16-byte aligned */
> +		"pushq	%%rbp\n"
> +		"pushq	%%rcx\n"
> +	/* Restore the lower VTL's rbp */
> +		"movq	(%%rcx), %%rbp\n"
> +	/* Load return kind into rcx (HV_VTL_RETURN_INPUT_NORMAL_RETURN == 0) */
> +		"xorl	%%ecx, %%ecx\n"
> +	/* Transition to the lower VTL */
> +		CALL_NOSPEC
> +	/* Save VTL0's rax and rcx temporarily on 16-byte aligned stack */
> +		"pushq	%%rax\n"
> +		"pushq	%%rcx\n"
> +	/* Restore pointer to lower VTL rbp */
> +		"movq	16(%%rsp), %%rax\n"
> +	/* Save the lower VTL's rbp */
> +		"movq	%%rbp, (%%rax)\n"
> +	/* Restore saved registers */
> +		"movq	8(%%rsp), %%rax\n"
> +		"movq	24(%%rsp), %%rbp\n"
> +		"addq	$32, %%rsp\n"
> +
> +		: "=a"(vtl0->rax), "=c"(vtl0->rcx),
> +		  "+d"(vtl0->rdx), "+b"(vtl0->rbx), "+S"(vtl0->rsi), "+D"(vtl0->rdi),
> +		  "+r"(r8), "+r"(r9), "+r"(r10), "+r"(r11),
> +		  "+r"(r12), "+r"(r13), "+r"(r14), "+r"(r15)
> +		: THUNK_TARGET(hypercall_addr), "c"(&vtl0->rbp)
> +		: "cc", "memory");
> +
> +	vtl0->r8 = r8;
> +	vtl0->r9 = r9;
> +	vtl0->r10 = r10;
> +	vtl0->r11 = r11;
> +	vtl0->r12 = r12;
> +	vtl0->r13 = r13;
> +	vtl0->r14 = r14;
> +	vtl0->r15 = r15;
> +	vtl0->cr2 = native_read_cr2();
> +
> +	fxsave(&vtl0->fx_state);
> +	kernel_fpu_end();
> +}
> +
> +/*
> + * Returning to a lower VTL treats the base pointer register
> + * as a general purpose one. Without adding this, objtool produces
> + * a warning.
> + */
> +STACK_FRAME_NON_STANDARD(mshv_vtl_return);
> +
> +static bool mshv_vtl_process_intercept(void)
> +{
> +	struct hv_per_cpu_context *mshv_cpu;
> +	void *synic_message_page;
> +	struct hv_message *msg;
> +	u32 message_type;
> +
> +	mshv_cpu = this_cpu_ptr(hv_context.cpu_context);
> +	synic_message_page = mshv_cpu->synic_message_page;
> +	if (unlikely(!synic_message_page))
> +		return true;
> +
> +	msg = (struct hv_message *)synic_message_page + HV_SYNIC_INTERCEPTION_SINT_INDEX;
> +	message_type = READ_ONCE(msg->header.message_type);
> +	if (message_type == HVMSG_NONE)
> +		return true;
> +
> +	memcpy(mshv_vtl_this_run()->exit_message, msg, sizeof(*msg));
> +	vmbus_signal_eom(msg, message_type);
> +
> +	return false;
> +}
> +
> +static int mshv_vtl_ioctl_return_to_lower_vtl(void)
> +{
> +	preempt_disable();
> +	for (;;) {
> +		const unsigned long VTL0_WORK = _TIF_SIGPENDING | _TIF_NEED_RESCHED |
> +						_TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL;
> +		unsigned long ti_work;
> +		u32 cancel;
> +		unsigned long irq_flags;
> +		struct hv_vp_assist_page *hvp;
> +		int ret;
> +
> +		local_irq_save(irq_flags);
> +		ti_work = READ_ONCE(current_thread_info()->flags);
> +		cancel = READ_ONCE(mshv_vtl_this_run()->cancel);
> +		if (unlikely((ti_work & VTL0_WORK) || cancel)) {
> +			local_irq_restore(irq_flags);
> +			preempt_enable();
> +			if (cancel)
> +				ti_work |= _TIF_SIGPENDING;
> +			ret = mshv_do_pre_guest_mode_work(ti_work);
> +			if (ret)
> +				return ret;
> +			preempt_disable();
> +			continue;
> +		}
> +
> +		mshv_vtl_return(&mshv_vtl_this_run()->cpu_context);
> +		local_irq_restore(irq_flags);
> +
> +		hvp = hv_vp_assist_page[smp_processor_id()];
> +		this_cpu_inc(num_vtl0_transitions);
> +		switch (hvp->vtl_entry_reason) {
> +		case MSHV_ENTRY_REASON_INTERRUPT:
> +			if (!mshv_vsm_capabilities.intercept_page_available &&
> +			    likely(!mshv_vtl_process_intercept()))
> +				goto done;
> +			break;
> +
> +		case MSHV_ENTRY_REASON_INTERCEPT:
> +			WARN_ON(!mshv_vsm_capabilities.intercept_page_available);
> +			memcpy(mshv_vtl_this_run()->exit_message, hvp->intercept_message,
> +			       sizeof(hvp->intercept_message));
> +			goto done;
> +
> +		default:
> +			panic("unknown entry reason: %d", hvp->vtl_entry_reason);
> +		}
> +	}
> +
> +done:
> +	preempt_enable();
> +
> +	return 0;
> +}
> +
> +static long
> +mshv_vtl_ioctl_get_regs(void __user *user_args)
> +{
> +	struct mshv_vp_registers args;
> +	struct hv_register_assoc *registers;
> +	long ret;
> +
> +	if (copy_from_user(&args, user_args, sizeof(args)))
> +		return -EFAULT;
> +
> +	if (args.count == 0 || args.count > MSHV_VP_MAX_REGISTERS)
> +		return -EINVAL;
> +
> +	registers = kmalloc_array(args.count,
> +				  sizeof(*registers),
> +				  GFP_KERNEL);
> +	if (!registers)
> +		return -ENOMEM;
> +
> +	if (copy_from_user(registers, (void __user *)args.regs_ptr,
> +			   sizeof(*registers) * args.count)) {
> +		ret = -EFAULT;
> +		goto free_return;
> +	}
> +
> +	ret = mshv_vtl_get_reg(registers);
> +	if (!ret)
> +		goto copy_args; /* No need of hypercall */
> +	ret = vtl_get_vp_registers(args.count, registers);
> +	if (ret)
> +		goto free_return;
> +
> +copy_args:
> +	if (copy_to_user((void __user *)args.regs_ptr, registers,
> +			 sizeof(*registers) * args.count))
> +		ret = -EFAULT;
> +free_return:
> +	kfree(registers);
> +
> +	return ret;
> +}
> +
> +static long
> +mshv_vtl_ioctl_set_regs(void __user *user_args)
> +{
> +	struct mshv_vp_registers args;
> +	struct hv_register_assoc *registers;
> +	long ret;
> +
> +	if (copy_from_user(&args, user_args, sizeof(args)))
> +		return -EFAULT;
> +
> +	if (args.count == 0 || args.count > MSHV_VP_MAX_REGISTERS)
> +		return -EINVAL;
> +
> +	registers = kmalloc_array(args.count,
> +				  sizeof(*registers),
> +				  GFP_KERNEL);
> +	if (!registers)
> +		return -ENOMEM;
> +
> +	if (copy_from_user(registers, (void __user *)args.regs_ptr,
> +			   sizeof(*registers) * args.count)) {
> +		ret = -EFAULT;
> +		goto free_return;
> +	}
> +
> +	ret = mshv_vtl_set_reg(registers);
> +	if (!ret)
> +		goto free_return; /* No need of hypercall */
> +	ret = vtl_set_vp_registers(args.count, registers);
> +
> +free_return:
> +	kfree(registers);
> +
> +	return ret;
> +}
> +
> +static long
> +mshv_vtl_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
> +{
> +	long ret;
> +	struct mshv_vtl *vtl = filp->private_data;
> +
> +	switch (ioctl) {
> +	case MSHV_SET_POLL_FILE:
> +		ret = mshv_vtl_ioctl_set_poll_file((struct mshv_vtl_set_poll_file *)arg);
> +		break;
> +	case MSHV_GET_VP_REGISTERS:
> +		ret = mshv_vtl_ioctl_get_regs((void __user *)arg);
> +		break;
> +	case MSHV_SET_VP_REGISTERS:
> +		ret = mshv_vtl_ioctl_set_regs((void __user *)arg);
> +		break;
> +	case MSHV_RETURN_TO_LOWER_VTL:
> +		ret = mshv_vtl_ioctl_return_to_lower_vtl();
> +		break;
> +	case MSHV_ADD_VTL0_MEMORY:
> +		ret = mshv_vtl_ioctl_add_vtl0_mem(vtl, (void __user *)arg);
> +		break;
> +	default:
> +		dev_err(vtl->module_dev, "invalid vtl ioctl: %#x\n", ioctl);
> +		ret = -ENOTTY;
> +	}
> +
> +	return ret;
> +}
> +
> +static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
> +{
> +	struct page *page;
> +	int cpu = vmf->pgoff & MSHV_PG_OFF_CPU_MASK;
> +	int real_off = vmf->pgoff >> MSHV_REAL_OFF_SHIFT;
> +
> +	if (!cpu_online(cpu))
> +		return VM_FAULT_SIGBUS;
> +
> +	if (real_off == MSHV_RUN_PAGE_OFFSET) {
> +		page = virt_to_page(mshv_vtl_cpu_run(cpu));
> +	} else if (real_off == MSHV_REG_PAGE_OFFSET) {
> +		if (!mshv_has_reg_page)
> +			return VM_FAULT_SIGBUS;
> +		page = mshv_vtl_cpu_reg_page(cpu);
> +	} else {
> +		return VM_FAULT_NOPAGE;
> +	}
> +
> +	get_page(page);
> +	vmf->page = page;
> +
> +	return 0;
> +}
> +
> +static const struct vm_operations_struct mshv_vtl_vm_ops = {
> +	.fault = mshv_vtl_fault,
> +};
> +
> +static int mshv_vtl_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> +	vma->vm_ops = &mshv_vtl_vm_ops;
> +
> +	return 0;
> +}
> +
> +static int mshv_vtl_release(struct inode *inode, struct file *filp)
> +{
> +	struct mshv_vtl *vtl = filp->private_data;
> +
> +	kfree(vtl);
> +
> +	return 0;
> +}
> +
> +static const struct file_operations mshv_vtl_fops = {
> +	.owner = THIS_MODULE,
> +	.unlocked_ioctl = mshv_vtl_ioctl,
> +	.release = mshv_vtl_release,
> +	.mmap = mshv_vtl_mmap,
> +};
> +
> +static void mshv_vtl_synic_mask_vmbus_sint(const u8 *mask)
> +{
> +	union hv_synic_sint sint;
> +
> +	sint.as_uint64 = 0;
> +	sint.vector = HYPERVISOR_CALLBACK_VECTOR;
> +	sint.masked = (*mask != 0);
> +	sint.auto_eoi = hv_recommend_using_aeoi();
> +
> +	hv_set_msr(HV_MSR_SINT0 + VTL2_VMBUS_SINT_INDEX,
> +		   sint.as_uint64);
> +
> +	if (!sint.masked)
> +		pr_debug("%s: Unmasking VTL2 VMBUS SINT on VP %d\n", __func__, smp_processor_id());
> +	else
> +		pr_debug("%s: Masking VTL2 VMBUS SINT on VP %d\n", __func__, smp_processor_id());
> +}
> +
> +static void mshv_vtl_read_remote(void *buffer)
> +{
> +	struct hv_per_cpu_context *mshv_cpu = this_cpu_ptr(hv_context.cpu_context);
> +	struct hv_message *msg = (struct hv_message *)mshv_cpu->synic_message_page +
> +					VTL2_VMBUS_SINT_INDEX;
> +	u32 message_type = READ_ONCE(msg->header.message_type);
> +
> +	WRITE_ONCE(has_message, false);
> +	if (message_type == HVMSG_NONE)
> +		return;
> +
> +	memcpy(buffer, msg, sizeof(*msg));
> +	vmbus_signal_eom(msg, message_type);
> +}
> +
> +static bool vtl_synic_mask_vmbus_sint_masked = true;
> +
> +static ssize_t mshv_vtl_sint_read(struct file *filp, char __user *arg, size_t size, loff_t *offset)
> +{
> +	struct hv_message msg = {};
> +	int ret;
> +
> +	if (size < sizeof(msg))
> +		return -EINVAL;
> +
> +	for (;;) {
> +		smp_call_function_single(VMBUS_CONNECT_CPU, mshv_vtl_read_remote, &msg, true);
> +		if (msg.header.message_type != HVMSG_NONE)
> +			break;
> +
> +		if (READ_ONCE(vtl_synic_mask_vmbus_sint_masked))
> +			return 0; /* EOF */
> +
> +		if (filp->f_flags & O_NONBLOCK)
> +			return -EAGAIN;
> +
> +		ret = wait_event_interruptible(fd_wait_queue,
> +					       READ_ONCE(has_message) ||
> +						READ_ONCE(vtl_synic_mask_vmbus_sint_masked));
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (copy_to_user(arg, &msg, sizeof(msg)))
> +		return -EFAULT;
> +
> +	return sizeof(msg);
> +}
> +
> +static __poll_t mshv_vtl_sint_poll(struct file *filp, poll_table *wait)
> +{
> +	__poll_t mask = 0;
> +
> +	poll_wait(filp, &fd_wait_queue, wait);
> +	if (READ_ONCE(has_message) || READ_ONCE(vtl_synic_mask_vmbus_sint_masked))
> +		mask |= EPOLLIN | EPOLLRDNORM;
> +
> +	return mask;
> +}
> +
> +static void mshv_vtl_sint_on_msg_dpc(unsigned long data)
> +{
> +	WRITE_ONCE(has_message, true);
> +	wake_up_interruptible_poll(&fd_wait_queue, EPOLLIN);
> +}
> +
> +static int mshv_vtl_sint_ioctl_post_message(struct mshv_vtl_sint_post_msg __user *arg)
> +{
> +	struct mshv_vtl_sint_post_msg message;
> +	u8 payload[HV_MESSAGE_PAYLOAD_BYTE_COUNT];
> +
> +	if (copy_from_user(&message, arg, sizeof(message)))
> +		return -EFAULT;
> +	if (message.payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
> +		return -EINVAL;
> +	if (copy_from_user(payload, (void __user *)message.payload_ptr,
> +			   message.payload_size))
> +		return -EFAULT;
> +
> +	return hv_post_message((union hv_connection_id)message.connection_id,
> +			       message.message_type, (void *)payload,
> +			       message.payload_size);
> +}
> +
> +static int mshv_vtl_sint_ioctl_signal_event(struct mshv_vtl_signal_event __user *arg)
> +{
> +	u64 input;
> +	struct mshv_vtl_signal_event signal_event;
> +
> +	if (copy_from_user(&signal_event, arg, sizeof(signal_event)))
> +		return -EFAULT;
> +
> +	input = signal_event.connection_id | ((u64)signal_event.flag << 32);
> +
> +	return hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, input) & HV_HYPERCALL_RESULT_MASK;
> +}
> +
> +static int mshv_vtl_sint_ioctl_set_eventfd(struct mshv_vtl_set_eventfd __user *arg)
> +{
> +	struct mshv_vtl_set_eventfd set_eventfd;
> +	struct eventfd_ctx *eventfd, *old_eventfd;
> +
> +	if (copy_from_user(&set_eventfd, arg, sizeof(set_eventfd)))
> +		return -EFAULT;
> +	if (set_eventfd.flag >= HV_EVENT_FLAGS_COUNT)
> +		return -EINVAL;
> +
> +	eventfd = NULL;
> +	if (set_eventfd.fd >= 0) {
> +		eventfd = eventfd_ctx_fdget(set_eventfd.fd);
> +		if (IS_ERR(eventfd))
> +			return PTR_ERR(eventfd);
> +	}
> +
> +	mutex_lock(&flag_lock);
> +	old_eventfd = flag_eventfds[set_eventfd.flag];
> +	WRITE_ONCE(flag_eventfds[set_eventfd.flag], eventfd);
> +	mutex_unlock(&flag_lock);
> +
> +	if (old_eventfd) {
> +		synchronize_rcu();
> +		eventfd_ctx_put(old_eventfd);
> +	}
> +
> +	return 0;
> +}
> +
> +static int mshv_vtl_sint_ioctl_pause_message_stream(struct mshv_sint_mask __user *arg)
> +{
> +	static DEFINE_MUTEX(vtl2_vmbus_sint_mask_mutex);
> +	struct mshv_sint_mask mask;
> +
> +	if (copy_from_user(&mask, arg, sizeof(mask)))
> +		return -EFAULT;
> +	mutex_lock(&vtl2_vmbus_sint_mask_mutex);
> +	on_each_cpu((smp_call_func_t)mshv_vtl_synic_mask_vmbus_sint, &mask.mask, 1);
> +	WRITE_ONCE(vtl_synic_mask_vmbus_sint_masked, mask.mask != 0);
> +	mutex_unlock(&vtl2_vmbus_sint_mask_mutex);
> +	if (mask.mask)
> +		wake_up_interruptible_poll(&fd_wait_queue, EPOLLIN);
> +
> +	return 0;
> +}
> +
> +static long mshv_vtl_sint_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
> +{
> +	switch (cmd) {
> +	case MSHV_SINT_POST_MESSAGE:
> +		return mshv_vtl_sint_ioctl_post_message((struct mshv_vtl_sint_post_msg *)arg);
> +	case MSHV_SINT_SIGNAL_EVENT:
> +		return mshv_vtl_sint_ioctl_signal_event((struct mshv_vtl_signal_event *)arg);
> +	case MSHV_SINT_SET_EVENTFD:
> +		return mshv_vtl_sint_ioctl_set_eventfd((struct mshv_vtl_set_eventfd *)arg);
> +	case MSHV_SINT_PAUSE_MESSAGE_STREAM:
> +		return mshv_vtl_sint_ioctl_pause_message_stream((struct mshv_sint_mask *)arg);
> +	default:
> +		return -ENOIOCTLCMD;
> +	}
> +}
> +
> +static const struct file_operations mshv_vtl_sint_ops = {
> +	.owner = THIS_MODULE,
> +	.read = mshv_vtl_sint_read,
> +	.poll = mshv_vtl_sint_poll,
> +	.unlocked_ioctl = mshv_vtl_sint_ioctl,
> +};
> +
> +static struct miscdevice mshv_vtl_sint_dev = {
> +	.name = "mshv_sint",
> +	.fops = &mshv_vtl_sint_ops,
> +	.mode = 0600,
> +	.minor = MISC_DYNAMIC_MINOR,
> +};
> +
> +static int mshv_vtl_hvcall_open(struct inode *node, struct file *f)
> +{
> +	struct miscdevice *dev = f->private_data;
> +	struct mshv_vtl_hvcall_fd *fd;
> +
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
> +	fd = vzalloc(sizeof(*fd));
> +	if (!fd)
> +		return -ENOMEM;
> +	fd->dev = dev;
> +	f->private_data = fd;
> +	mutex_init(&fd->init_mutex);
> +
> +	return 0;
> +}
> +
> +static int mshv_vtl_hvcall_release(struct inode *node, struct file *f)
> +{
> +	struct mshv_vtl_hvcall_fd *fd;
> +
> +	fd = f->private_data;
> +	if (fd) {
> +		vfree(fd);
> +		f->private_data = NULL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mshv_vtl_hvcall_setup(struct mshv_vtl_hvcall_fd *fd,
> +				 struct mshv_vtl_hvcall_setup __user *hvcall_setup_user)
> +{
> +	int ret = 0;
> +	struct mshv_vtl_hvcall_setup hvcall_setup;
> +
> +	mutex_lock(&fd->init_mutex);
> +
> +	if (fd->allow_map_initialized) {
> +		dev_err(fd->dev->this_device,
> +			"Hypercall allow map has already been set, pid %d\n",
> +			current->pid);
> +		ret = -EINVAL;
> +		goto exit;
> +	}
> +
> +	if (copy_from_user(&hvcall_setup, hvcall_setup_user,
> +			   sizeof(struct mshv_vtl_hvcall_setup))) {
> +		ret = -EFAULT;
> +		goto exit;
> +	}
> +	if (hvcall_setup.bitmap_size > ARRAY_SIZE(fd->allow_bitmap)) {
> +		ret = -EINVAL;
> +		goto exit;
> +	}
> +	if (copy_from_user(&fd->allow_bitmap,
> +			   (void __user *)hvcall_setup.allow_bitmap_ptr,
> +			   hvcall_setup.bitmap_size)) {
> +		ret = -EFAULT;
> +		goto exit;
> +	}
> +
> +	dev_info(fd->dev->this_device, "Hypercall allow map has been set, pid %d\n",
> +		 current->pid);
> +	fd->allow_map_initialized = true;
> +exit:
> +	mutex_unlock(&fd->init_mutex);
> +
> +	return ret;
> +}
> +
> +static bool mshv_vtl_hvcall_is_allowed(struct mshv_vtl_hvcall_fd *fd, u16 call_code)
> +{
> +	u8 bits_per_item = 8 * sizeof(fd->allow_bitmap[0]);
> +	u16 item_index = call_code / bits_per_item;
> +	u64 mask = 1ULL << (call_code % bits_per_item);
> +
> +	return fd->allow_bitmap[item_index] & mask;
> +}
> +
> +static int mshv_vtl_hvcall_call(struct mshv_vtl_hvcall_fd *fd,
> +				struct mshv_vtl_hvcall __user *hvcall_user)
> +{
> +	struct mshv_vtl_hvcall hvcall;
> +	void *in, *out;
> +	int ret;
> +
> +	if (copy_from_user(&hvcall, hvcall_user, sizeof(struct mshv_vtl_hvcall)))
> +		return -EFAULT;
> +	if (hvcall.input_size > HV_HYP_PAGE_SIZE)
> +		return -EINVAL;
> +	if (hvcall.output_size > HV_HYP_PAGE_SIZE)
> +		return -EINVAL;
> +
> +	/*
> +	 * By default, all hypercalls are not allowed.
> +	 * The user mode code has to set up the allow bitmap once.
> +	 */
> +
> +	if (!mshv_vtl_hvcall_is_allowed(fd, hvcall.control & 0xFFFF)) {
> +		dev_err(fd->dev->this_device,
> +			"Hypercall with control data %#llx isn't allowed\n",
> +			hvcall.control);
> +		return -EPERM;
> +	}
> +
> +	/*
> +	 * This may create a problem for Confidential VM (CVM) usecase where we need to use
> +	 * Hyper-V driver allocated per-cpu input and output pages (hyperv_pcpu_input_arg and
> +	 * hyperv_pcpu_output_arg) for making a hypervisor call.
> +	 *
> +	 * TODO: Take care of this when CVM support is added.
> +	 */
> +	in = (void *)__get_free_page(GFP_KERNEL);
> +	out = (void *)__get_free_page(GFP_KERNEL);
> +
> +	if (copy_from_user(in, (void __user *)hvcall.input_ptr, hvcall.input_size)) {
> +		ret = -EFAULT;
> +		goto free_pages;
> +	}
> +
> +	hvcall.status = hv_do_hypercall(hvcall.control, in, out);
> +
> +	if (copy_to_user((void __user *)hvcall.output_ptr, out, hvcall.output_size)) {
> +		ret = -EFAULT;
> +		goto free_pages;
> +	}
> +	ret = put_user(hvcall.status, &hvcall_user->status);
> +free_pages:
> +	free_page((unsigned long)in);
> +	free_page((unsigned long)out);
> +
> +	return ret;
> +}
> +
> +static long mshv_vtl_hvcall_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
> +{
> +	struct mshv_vtl_hvcall_fd *fd = f->private_data;
> +
> +	switch (cmd) {
> +	case MSHV_HVCALL_SETUP:
> +		return mshv_vtl_hvcall_setup(fd, (struct mshv_vtl_hvcall_setup __user *)arg);
> +	case MSHV_HVCALL:
> +		return mshv_vtl_hvcall_call(fd, (struct mshv_vtl_hvcall __user *)arg);
> +	default:
> +		break;
> +	}
> +
> +	return -ENOIOCTLCMD;
> +}
> +
> +static const struct file_operations mshv_vtl_hvcall_file_ops = {
> +	.owner = THIS_MODULE,
> +	.open = mshv_vtl_hvcall_open,
> +	.release = mshv_vtl_hvcall_release,
> +	.unlocked_ioctl = mshv_vtl_hvcall_ioctl,
> +};
> +
> +static struct miscdevice mshv_vtl_hvcall = {
> +	.name = "mshv_hvcall",
> +	.nodename = "mshv_hvcall",
> +	.fops = &mshv_vtl_hvcall_file_ops,
> +	.mode = 0600,
> +	.minor = MISC_DYNAMIC_MINOR,
> +};
> +
> +static int mshv_vtl_low_open(struct inode *inodep, struct file *filp)
> +{
> +	pid_t pid = task_pid_vnr(current);
> +	uid_t uid = current_uid().val;
> +	int ret = 0;
> +
> +	pr_debug("%s: Opening VTL low, task group %d, uid %d\n", __func__, pid, uid);
> +
> +	if (capable(CAP_SYS_ADMIN)) {
> +		filp->private_data = inodep;
> +	} else {
> +		pr_err("%s: VTL low open failed: CAP_SYS_ADMIN required. task group %d, uid %d",
> +		       __func__, pid, uid);
> +		ret = -EPERM;
> +	}
> +
> +	return ret;
> +}
> +
> +static bool can_fault(struct vm_fault *vmf, unsigned long size, pfn_t *pfn)
> +{
> +	unsigned long mask = size - 1;
> +	unsigned long start = vmf->address & ~mask;
> +	unsigned long end = start + size;
> +	bool is_valid;
> +
> +	is_valid = (vmf->address & mask) == ((vmf->pgoff << PAGE_SHIFT) & mask) &&
> +		start >= vmf->vma->vm_start &&
> +		end <= vmf->vma->vm_end;
> +
> +	if (is_valid)
> +		*pfn = __pfn_to_pfn_t(vmf->pgoff & ~(mask >> PAGE_SHIFT), PFN_DEV | PFN_MAP);
> +
> +	return is_valid;
> +}
> +
> +static vm_fault_t mshv_vtl_low_huge_fault(struct vm_fault *vmf, unsigned int order)
> +{
> +	pfn_t pfn;
> +	int ret = VM_FAULT_FALLBACK;
> +
> +	switch (order) {
> +	case 0:
> +		pfn = __pfn_to_pfn_t(vmf->pgoff, PFN_DEV | PFN_MAP);
> +		return vmf_insert_mixed(vmf->vma, vmf->address, pfn);
> +
> +	case PMD_ORDER:
> +		if (can_fault(vmf, PMD_SIZE, &pfn))
> +			ret = vmf_insert_pfn_pmd(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE);
> +		return ret;
> +
> +	case PUD_ORDER:
> +		if (can_fault(vmf, PUD_SIZE, &pfn))
> +			ret = vmf_insert_pfn_pud(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE);
> +		return ret;
> +
> +	default:
> +		return VM_FAULT_SIGBUS;
> +	}
> +}
> +
> +static vm_fault_t mshv_vtl_low_fault(struct vm_fault *vmf)
> +{
> +	return mshv_vtl_low_huge_fault(vmf, 0);
> +}
> +
> +static const struct vm_operations_struct mshv_vtl_low_vm_ops = {
> +	.fault = mshv_vtl_low_fault,
> +	.huge_fault = mshv_vtl_low_huge_fault,
> +};
> +
> +static int mshv_vtl_low_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> +	vma->vm_ops = &mshv_vtl_low_vm_ops;
> +	vm_flags_set(vma, VM_HUGEPAGE | VM_MIXEDMAP);
> +
> +	return 0;
> +}
> +
> +static const struct file_operations mshv_vtl_low_file_ops = {
> +	.owner		= THIS_MODULE,
> +	.open		= mshv_vtl_low_open,
> +	.mmap		= mshv_vtl_low_mmap,
> +};
> +
> +static struct miscdevice mshv_vtl_low = {
> +	.name = "mshv_vtl_low",
> +	.nodename = "mshv_vtl_low",
> +	.fops = &mshv_vtl_low_file_ops,
> +	.mode = 0600,
> +	.minor = MISC_DYNAMIC_MINOR,
> +};
> +
> +static int __init mshv_vtl_init(void)
> +{
> +	int ret;
> +	struct device *dev = mshv_dev.this_device;
> +
> +	/*
> +	 * This creates /dev/mshv which provides functionality to create VTLs and partitions.
> +	 */
> +	ret = misc_register(&mshv_dev);
> +	if (ret) {
> +		dev_err(dev, "mshv device register failed: %d\n", ret);
> +		goto free_dev;
> +	}
> +
> +	tasklet_init(&msg_dpc, mshv_vtl_sint_on_msg_dpc, 0);
> +	init_waitqueue_head(&fd_wait_queue);
> +
> +	if (mshv_vtl_get_vsm_regs()) {
> +		dev_emerg(dev, "Unable to get VSM capabilities !!\n");
> +		ret = -ENODEV;
> +		goto free_dev;
> +	}
> +	if (mshv_vtl_configure_vsm_partition(dev)) {
> +		dev_emerg(dev, "VSM configuration failed !!\n");
> +		ret = -ENODEV;
> +		goto free_dev;
> +	}
> +
> +	ret = hv_vtl_setup_synic();
> +	if (ret)
> +		goto free_dev;
> +
> +	/*
> +	 * mshv_sint device adds VMBus relay ioctl support.
> +	 * This provides a channel for VTL0 to communicate with VTL2.
> +	 */
> +	ret = misc_register(&mshv_vtl_sint_dev);
> +	if (ret)
> +		goto free_synic;
> +
> +	/*
> +	 * mshv_hvcall device adds interface to enable userspace for direct hypercalls support.
> +	 */
> +	ret = misc_register(&mshv_vtl_hvcall);
> +	if (ret)
> +		goto free_sint;
> +
> +	/*
> +	 * mshv_vtl_low device is used to map VTL0 address space to a user-mode process in VTL2.
> +	 * It implements mmap() to allow a user-mode process in VTL2 to map to the address of VTL0.
> +	 */
> +	ret = misc_register(&mshv_vtl_low);
> +	if (ret)
> +		goto free_hvcall;
> +
> +	/*
> +	 * "mshv vtl mem dev" device is later used to setup VTL0 memory.
> +	 */
> +	mem_dev = kzalloc(sizeof(*mem_dev), GFP_KERNEL);
> +	if (!mem_dev) {
> +		ret = -ENOMEM;
> +		goto free_low;
> +	}
> +
> +	mutex_init(&mshv_vtl_poll_file_lock);
> +
> +	device_initialize(mem_dev);
> +	dev_set_name(mem_dev, "mshv vtl mem dev");
> +	ret = device_add(mem_dev);
> +	if (ret) {
> +		dev_err(dev, "mshv vtl mem dev add: %d\n", ret);
> +		goto free_mem;
> +	}
> +
> +	return 0;
> +
> +free_mem:
> +	kfree(mem_dev);
> +free_low:
> +	misc_deregister(&mshv_vtl_low);
> +free_hvcall:
> +	misc_deregister(&mshv_vtl_hvcall);
> +free_sint:
> +	misc_deregister(&mshv_vtl_sint_dev);
> +free_synic:
> +	hv_vtl_remove_synic();
> +free_dev:
> +	misc_deregister(&mshv_dev);
> +
> +	return ret;
> +}
> +
> +static void __exit mshv_vtl_exit(void)
> +{
> +	device_del(mem_dev);
> +	kfree(mem_dev);
> +	misc_deregister(&mshv_vtl_low);
> +	misc_deregister(&mshv_vtl_hvcall);
> +	misc_deregister(&mshv_vtl_sint_dev);
> +	hv_vtl_remove_synic();
> +	misc_deregister(&mshv_dev);
> +}
> +
> +module_init(mshv_vtl_init);
> +module_exit(mshv_vtl_exit);
> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
> index 1be7f6a02304..cc9260c37c49 100644
> --- a/include/hyperv/hvgdk_mini.h
> +++ b/include/hyperv/hvgdk_mini.h
> @@ -882,6 +882,23 @@ struct hv_get_vp_from_apic_id_in {
>  	u32 apic_ids[];
>  } __packed;
>  
> +union hv_register_vsm_partition_config {
> +	u64 as_uint64;
> +	struct {
> +		u64 enable_vtl_protection : 1;
> +		u64 default_vtl_protection_mask : 4;
> +		u64 zero_memory_on_reset : 1;
> +		u64 deny_lower_vtl_startup : 1;
> +		u64 intercept_acceptance : 1;
> +		u64 intercept_enable_vtl_protection : 1;
> +		u64 intercept_vp_startup : 1;
> +		u64 intercept_cpuid_unimplemented : 1;
> +		u64 intercept_unrecoverable_exception : 1;
> +		u64 intercept_page : 1;
> +		u64 mbz : 51;
> +	};
> +};
> +
>  struct hv_nested_enlightenments_control {
>  	struct {
>  		u32 directhypercall : 1;
> @@ -1004,6 +1021,70 @@ enum hv_register_name {
>  
>  	/* VSM */
>  	HV_REGISTER_VSM_VP_STATUS				= 0x000D0003,
> +
> +	/* Synthetic VSM registers */
> +	HV_REGISTER_VSM_CODE_PAGE_OFFSETS	= 0x000D0002,
> +	HV_REGISTER_VSM_CAPABILITIES		= 0x000D0006,
> +	HV_REGISTER_VSM_PARTITION_CONFIG	= 0x000D0007,
> +
> +#if defined(CONFIG_X86)
> +	/* X64 Debug Registers */
> +	HV_X64_REGISTER_DR0	= 0x00050000,
> +	HV_X64_REGISTER_DR1	= 0x00050001,
> +	HV_X64_REGISTER_DR2	= 0x00050002,
> +	HV_X64_REGISTER_DR3	= 0x00050003,
> +	HV_X64_REGISTER_DR6	= 0x00050004,
> +	HV_X64_REGISTER_DR7	= 0x00050005,
> +
> +	/* X64 Cache control MSRs */
> +	HV_X64_REGISTER_MSR_MTRR_CAP		= 0x0008000D,
> +	HV_X64_REGISTER_MSR_MTRR_DEF_TYPE	= 0x0008000E,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0	= 0x00080010,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1	= 0x00080011,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2	= 0x00080012,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3	= 0x00080013,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4	= 0x00080014,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5	= 0x00080015,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6	= 0x00080016,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7	= 0x00080017,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE8	= 0x00080018,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASE9	= 0x00080019,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASEA	= 0x0008001A,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASEB	= 0x0008001B,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASEC	= 0x0008001C,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASED	= 0x0008001D,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASEE	= 0x0008001E,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_BASEF	= 0x0008001F,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0	= 0x00080040,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1	= 0x00080041,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2	= 0x00080042,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3	= 0x00080043,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4	= 0x00080044,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5	= 0x00080045,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6	= 0x00080046,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7	= 0x00080047,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK8	= 0x00080048,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASK9	= 0x00080049,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASKA	= 0x0008004A,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASKB	= 0x0008004B,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASKC	= 0x0008004C,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASKD	= 0x0008004D,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASKE	= 0x0008004E,
> +	HV_X64_REGISTER_MSR_MTRR_PHYS_MASKF	= 0x0008004F,
> +	HV_X64_REGISTER_MSR_MTRR_FIX64K00000	= 0x00080070,
> +	HV_X64_REGISTER_MSR_MTRR_FIX16K80000	= 0x00080071,
> +	HV_X64_REGISTER_MSR_MTRR_FIX16KA0000	= 0x00080072,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KC0000	= 0x00080073,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KC8000	= 0x00080074,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KD0000	= 0x00080075,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KD8000	= 0x00080076,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KE0000	= 0x00080077,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KE8000	= 0x00080078,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KF0000	= 0x00080079,
> +	HV_X64_REGISTER_MSR_MTRR_FIX4KF8000	= 0x0008007A,
> +
> +	HV_X64_REGISTER_REG_PAGE	= 0x0009001C,
> +#endif
>  };
>  
>  /*
> diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
> index b4067ada02cf..c6a62ec9f6da 100644
> --- a/include/hyperv/hvhdk.h
> +++ b/include/hyperv/hvhdk.h
> @@ -479,6 +479,7 @@ struct hv_connection_info {
>  #define HV_EVENT_FLAGS_COUNT		(256 * 8)
>  #define HV_EVENT_FLAGS_BYTE_COUNT	(256)
>  #define HV_EVENT_FLAGS32_COUNT		(256 / sizeof(u32))
> +#define HV_EVENT_FLAGS_LONG_COUNT	(HV_EVENT_FLAGS_BYTE_COUNT / sizeof(u64))
>  
>  /* linux side we create long version of flags to use long bit ops on flags */
>  #define HV_EVENT_FLAGS_UL_COUNT		(256 / sizeof(ulong))
> diff --git a/include/uapi/linux/mshv.h b/include/uapi/linux/mshv.h
> index 876bfe4e4227..a218536eaec1 100644
> --- a/include/uapi/linux/mshv.h
> +++ b/include/uapi/linux/mshv.h
> @@ -288,4 +288,86 @@ struct mshv_get_set_vp_state {
>   * #define MSHV_ROOT_HVCALL			_IOWR(MSHV_IOCTL, 0x07, struct mshv_root_hvcall)
>   */
>  
> +/* Structure definitions, macros and IOCTLs for mshv_vtl */
> +
> +#define MSHV_CAP_CORE_API_STABLE        0x0
> +#define MSHV_CAP_REGISTER_PAGE          0x1
> +#define MSHV_CAP_VTL_RETURN_ACTION      0x2
> +#define MSHV_CAP_DR6_SHARED             0x3
> +#define MSHV_MAX_RUN_MSG_SIZE                256
> +
> +#define MSHV_VP_MAX_REGISTERS   128
> +
> +struct mshv_vp_registers {
> +	__u32 count;	/* at most MSHV_VP_MAX_REGISTERS */
> +	__u32 reserved; /* Reserved for alignment or future use */
> +	__u64 regs_ptr;	/* pointer to struct hv_register_assoc */
> +};
> +
> +struct mshv_vtl_set_eventfd {
> +	__s32 fd;
> +	__u32 flag;
> +};
> +
> +struct mshv_vtl_signal_event {
> +	__u32 connection_id;
> +	__u32 flag;
> +};
> +
> +struct mshv_vtl_sint_post_msg {
> +	__u64 message_type;
> +	__u32 connection_id;
> +	__u32 payload_size; /* Must not exceed HV_MESSAGE_PAYLOAD_BYTE_COUNT */
> +	__u64 payload_ptr; /* pointer to message payload (bytes) */
> +};
> +
> +struct mshv_vtl_ram_disposition {
> +	__u64 start_pfn;
> +	__u64 last_pfn;
> +};
> +
> +struct mshv_vtl_set_poll_file {
> +	__u32 cpu;
> +	__u32 fd;
> +};
> +
> +struct mshv_vtl_hvcall_setup {
> +	__u64 bitmap_size;
> +	__u64 allow_bitmap_ptr; /* pointer to __u64 */
> +};
> +
> +struct mshv_vtl_hvcall {
> +	__u64 control;      /* Hypercall control code */
> +	__u64 input_size;   /* Size of the input data */
> +	__u64 input_ptr;    /* Pointer to the input struct */
> +	__u64 status;       /* Status of the hypercall (output) */
> +	__u64 output_size;  /* Size of the output data */
> +	__u64 output_ptr;   /* Pointer to the output struct */
> +};
> +
> +struct mshv_sint_mask {
> +	__u8 mask;
> +	__u8 reserved[7];
> +};
> +
> +/* /dev/mshv device IOCTL */
> +#define MSHV_CHECK_EXTENSION    _IOW(MSHV_IOCTL, 0x00, __u32)
> +
> +/* vtl device */
> +#define MSHV_CREATE_VTL			_IOR(MSHV_IOCTL, 0x1D, char)
> +#define MSHV_ADD_VTL0_MEMORY	_IOW(MSHV_IOCTL, 0x21, struct mshv_vtl_ram_disposition)
> +#define MSHV_SET_POLL_FILE		_IOW(MSHV_IOCTL, 0x25, struct mshv_vtl_set_poll_file)
> +#define MSHV_RETURN_TO_LOWER_VTL	_IO(MSHV_IOCTL, 0x27)
> +#define MSHV_GET_VP_REGISTERS		_IOWR(MSHV_IOCTL, 0x05, struct mshv_vp_registers)
> +#define MSHV_SET_VP_REGISTERS		_IOW(MSHV_IOCTL, 0x06, struct mshv_vp_registers)
> +
> +/* VMBus device IOCTLs */
> +#define MSHV_SINT_SIGNAL_EVENT    _IOW(MSHV_IOCTL, 0x22, struct mshv_vtl_signal_event)
> +#define MSHV_SINT_POST_MESSAGE    _IOW(MSHV_IOCTL, 0x23, struct mshv_vtl_sint_post_msg)
> +#define MSHV_SINT_SET_EVENTFD     _IOW(MSHV_IOCTL, 0x24, struct mshv_vtl_set_eventfd)
> +#define MSHV_SINT_PAUSE_MESSAGE_STREAM     _IOW(MSHV_IOCTL, 0x25, struct mshv_sint_mask)
> +
> +/* hv_hvcall device */
> +#define MSHV_HVCALL_SETUP        _IOW(MSHV_IOCTL, 0x1E, struct mshv_vtl_hvcall_setup)
> +#define MSHV_HVCALL              _IOWR(MSHV_IOCTL, 0x1F, struct mshv_vtl_hvcall)
>  #endif

Reviewed-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>

^ permalink raw reply

* Re: [PATCH v6 0/5] Allow dyn MSI-X vector allocation of MANA
From: Jakub Kicinski @ 2025-06-11 15:54 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: linux-hyperv, linux-pci, linux-kernel, Nipun Gupta, Yury Norov,
	Jason Gunthorpe, Jonathan Cameron, Anna-Maria Behnsen, Kevin Tian,
	Long Li, Thomas Gleixner, Bjorn Helgaas, Rob Herring,
	Manivannan Sadhasivam, Krzysztof Wilczy�~Dski,
	Lorenzo Pieralisi, Dexuan Cui, Wei Liu, Haiyang Zhang,
	K. Y. Srinivasan, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Konstantin Taranov, Simon Horman, Leon Romanovsky,
	Maxim Levitsky, Erni Sri Satya Vennela, Peter Zijlstra, netdev,
	linux-rdma, Paul Rosswurm, Shradha Gupta
In-Reply-To: <1749650984-9193-1-git-send-email-shradhagupta@linux.microsoft.com>

On Wed, 11 Jun 2025 07:09:44 -0700 Shradha Gupta wrote:
> Changes in v6
>  * rebased to linux-next's v6.16-rc1 as per Jakub's suggestion

I meant a branch, basically apply the patches on the v6.16-rc1 tag
and push it out to GitHub, kernel.org or somewhere else public.
Then we can pull it in and maintain the stable commit IDs.
No need to repost the patches, FWIW, just share the branch here
once you pushed it out..

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox