Linux-HyperV List
 help / color / mirror / Atom feed
* Re: [Patch net-next v2] net: mana: Record doorbell physical address in PF mode
From: Shradha Gupta @ 2025-06-16 15:32 UTC (permalink / raw)
  To: longli
  Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Konstantin Taranov, Souradeep Chakrabarti,
	Erick Archer, linux-hyperv, netdev, linux-kernel, linux-rdma
In-Reply-To: <1749836765-28886-1-git-send-email-longli@linuxonhyperv.com>

On Fri, Jun 13, 2025 at 10:46:05AM -0700, longli@linuxonhyperv.com wrote:
> From: Long Li <longli@microsoft.com>
> 
> MANA supports RDMA in PF mode. The driver should record the doorbell
> physical address when in PF mode.
> 
> The doorbell physical address is used by the RDMA driver to map
> doorbell pages of the device to user-mode applications through RDMA
> verbs interface. In the past, they have been mapped to user-mode while
> the device is in VF mode. With the support for PF mode implemented,
> also expose those pages in PF mode.
> 
> Signed-off-by: Long Li <longli@microsoft.com>
> ---
> Changes
> v2: add more details in commit message on how the doorbell physical address is used
> 
>  drivers/net/ethernet/microsoft/mana/gdma_main.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> index 3504507477c6..52cf7112762c 100644
> --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
> +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> @@ -31,6 +31,9 @@ static void mana_gd_init_pf_regs(struct pci_dev *pdev)
>  	gc->db_page_base = gc->bar0_va +
>  				mana_gd_r64(gc, GDMA_PF_REG_DB_PAGE_OFF);
>  
> +	gc->phys_db_page_base = gc->bar0_pa +
> +				mana_gd_r64(gc, GDMA_PF_REG_DB_PAGE_OFF);
> +
>  	sriov_base_off = mana_gd_r64(gc, GDMA_SRIOV_REG_CFG_BASE_OFF);
>  
>  	sriov_base_va = gc->bar0_va + sriov_base_off;
> -- 
> 2.25.1

Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>


^ permalink raw reply

* [PATCH 2/2] tools/hv: Make network-scripts DHCP status check more specific
From: Ben Hutchings @ 2025-06-15 23:06 UTC (permalink / raw)
  To: linux-hyperv
In-Reply-To: <aE9Ri42HK2L1YOn3@decadent.org.uk>

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

We currently look for the string 'dhcp' in a network-scripts
configuration file, but this could potentially be found in a comment
line.  The variable that controls whether DHCPv4 is used is BOOTPROTO,
so check for that variable name as well as the value 'dhcp'.

Also quote the interface name when constructing the configuration
filename, just in case it contains a special character.

Signed-off-by: Ben Hutchings <benh@debian.org>
---
 tools/hv/hv_get_dhcp_info.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/hv/hv_get_dhcp_info.sh b/tools/hv/hv_get_dhcp_info.sh
index 310b16a2f734..7815d55a9295 100755
--- a/tools/hv/hv_get_dhcp_info.sh
+++ b/tools/hv/hv_get_dhcp_info.sh
@@ -75,10 +75,10 @@ check_ifupdown() {
 }
 
 check_network_scripts() {
-    local if_file="/etc/sysconfig/network-scripts/ifcfg-"$1
+    local if_file="/etc/sysconfig/network-scripts/ifcfg-$1"
 
     if [ -f "$if_file" ]; then
-	grep -q dhcp "$if_file"
+	grep -q '^\s*BOOTPROTO=.*dhcp' "$if_file"
 	report
     else
 	return 1

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related

* [PATCH 1/2] tools/hv: Make the sample hv_get_dhcp_info script more useful
From: Ben Hutchings @ 2025-06-15 23:05 UTC (permalink / raw)
  To: linux-hyperv
In-Reply-To: <aE9Ri42HK2L1YOn3@decadent.org.uk>

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

Currently the sample hv_get_dhcp_info script only supports the old Red
Hat network-scripts configuration format and leaves everything else to
downstream distributions.

However, Network Manager and systemd-networkd are available across
many distributions, so it makes more sense to implement support for
them here.

Debian's ifupdown is also used in several distributions that are not
Debian derivatives, so I think it makes sense to implement support for
that here too.

Extend the script to support all of these:

- Add a report function that reports the status based on the result of
  the previous command
- Add a function for each configuration system that checks whether
  that system in use for the given interface, and:
  - If so, checks and reports the DHCP status
  - If not, returns failure
- Call each of those functions, exiting once one of them succeeds,
  with a final fallback to reporting 'Disabled'

The network-scripts check is placed last, because it only checks a
file and not the actual interface state and so is the least reliable
check.

Signed-off-by: Ben Hutchings <benh@debian.org>
---
 tools/hv/hv_get_dhcp_info.sh | 87 +++++++++++++++++++++++++++++++-----
 1 file changed, 75 insertions(+), 12 deletions(-)

diff --git a/tools/hv/hv_get_dhcp_info.sh b/tools/hv/hv_get_dhcp_info.sh
index 2f2a3c7df3de..310b16a2f734 100755
--- a/tools/hv/hv_get_dhcp_info.sh
+++ b/tools/hv/hv_get_dhcp_info.sh
@@ -12,18 +12,81 @@
 #	that DHCP is enabled on the interface. If DHCP is not enabled,
 #	the script prints the string "Disabled" to stdout.
 #
-# Each Distro is expected to implement this script in a distro specific
-# fashion. For instance, on Distros that ship with Network Manager enabled,
-# this script can be based on the Network Manager APIs for retrieving DHCP
-# information.
+# Distributions may need to adapt or replace this script for their
+# preferred network configuration system.
 
-if_file="/etc/sysconfig/network-scripts/ifcfg-"$1
+# Report status based on result of previous command
+report() {
+    if [ $? -eq 0 ]; then
+	echo "Enabled"
+    else
+	echo "Disabled"
+    fi
+}
 
-dhcp=$(grep "dhcp" $if_file 2>/dev/null)
+check_network_manager() {
+    local conn_name
 
-if [ "$dhcp" != "" ];
-then
-echo "Enabled"
-else
-echo "Disabled"
-fi
+    # Check that the interface has a configured connection, and get
+    # its name
+    if conn_name="$(nmcli -g GENERAL.CONNECTION device show "$1" 2>/dev/null)" &&
+       [ "$conn_name" ]; then
+	# Check whether the connection enables DHCPv4
+	test "$(nmcli -g ipv4.method connection show "$conn_name")" = auto
+	report
+    else
+	return 1
+    fi
+}
+
+check_systemd_networkd() {
+    local status
+
+    # Check that the interface is managed by networkd
+    if status="$(networkctl status --json=short -- "$1" 2>/dev/null)" &&
+       ! printf '%s' "$status" |
+	   grep -qE '"AdministrativeState":"unmanaged"'; then
+	# Check for DHCPv4 client state in the interface status
+	printf '%s' "$status" | grep -q '"DHCPv4Client":'
+	report
+    else
+	return 1
+    fi
+}
+
+check_ifupdown() {
+    local conf_name
+
+    # Check that a configuration has been applied to the interface
+    if command -v ifquery >/dev/null &&
+       conf_name="$(ifquery --state -- "$1" | sed 's/[^=]*=//')" &&
+       [ "$conf_name" ]; then
+	# Check whether that configuration enables DHCPv4.
+	# Unfortunately ifquery does not expose the method name, so we
+	# have to grep through the configuration file(s) and make an
+	# assumption about which are included.
+	find /etc/network/interfaces /etc/network/interfaces.d \
+	     -type f -regex '.*/[a-zA-Z0-9_-]+$' -print |
+	    xargs grep -qE '^\s*iface\s+'"$conf_name"'\s+inet\s+dhcp(\s|$)'
+	report
+    else
+	return 1
+    fi
+}
+
+check_network_scripts() {
+    local if_file="/etc/sysconfig/network-scripts/ifcfg-"$1
+
+    if [ -f "$if_file" ]; then
+	grep -q dhcp "$if_file"
+	report
+    else
+	return 1
+    fi
+}
+
+check_network_manager "$1" ||
+check_systemd_networkd "$1" ||
+check_ifupdown "$1" ||
+check_network_scripts "$1" ||
+report


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related

* [PATCH 0/2] tools/hv: Improve the sample hv_get_dhcp_info script
From: Ben Hutchings @ 2025-06-15 23:04 UTC (permalink / raw)
  To: linux-hyperv

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

The sample hv_get_dhcp_info script was originally supposed to be
replaced by downstream distributions, but:

- Network Manager and systemd-networkd are used across many
  distributions
- Debian's ifupdown is not only used in Debian derivatives but also
  Alpine and Void Linux

This adds support for all of those.

The check for DHCP in network-scripts configuration files was
also quite lax.  This makes the regex a bit more strict.

Ben.

Ben Hutchings (2):
  tools/hv: Make the sample hv_get_dhcp_info script more useful
  tools/hv: Make network-scripts DHCP status check more specific

 tools/hv/hv_get_dhcp_info.sh | 87 +++++++++++++++++++++++++++++++-----
 1 file changed, 75 insertions(+), 12 deletions(-)


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH net-next v2 0/4] Support bandwidth clamping in mana using net shapers
From: Jakub Kicinski @ 2025-06-14 20:03 UTC (permalink / raw)
  To: Erni Sri Satya Vennela
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	pabeni, longli, kotaranov, horms, shirazsaleem, leon,
	shradhagupta, schakrabarti, gerhard, rosenp, sdf, linux-hyperv,
	netdev, linux-kernel, linux-rdma
In-Reply-To: <1749813627-8377-1-git-send-email-ernis@linux.microsoft.com>

On Fri, 13 Jun 2025 04:20:23 -0700 Erni Sri Satya Vennela wrote:
> This patchset introduces hardware-backed bandwidth rate limiting
> for MANA NICs via the net_shaper_ops interface, enabling efficient and
> fine-grained traffic shaping directly on the device.
> 
> Previously, MANA lacked a mechanism for user-configurable bandwidth
> control. With this addition, users can now configure shaping parameters,
> allowing better traffic management and performance isolation.
> 
> The implementation includes the net_shaper_ops callbacks in the MANA
> driver and supports one shaper per vport. Add shaping support via
> mana_set_bw_clamp(), allowing the configuration of bandwidth rates
> in 100 Mbps increments (minimum 100 Mbps). The driver validates input
> and rejects unsupported values. On failure, it restores the previous
> configuration which is queried using mana_query_link_cfg() or
> retains the current state.
> 
> To prevent potential deadlocks introduced by net_shaper_ops, switch to
> _locked variants of NAPI APIs when netdevops_lock is held during
> VF setup and teardown.
> 
> Also, Add support for ethtool get_link_ksettings to report the maximum
> link speed supported by the SKU in mbps.
> 
> These APIs when invoked on hardware that are older or that do
> not support these APIs, the speed would be reported as UNKNOWN and
> the net-shaper calls to set speed would fail.

Failed to apply patch:
Applying: net: mana: Fix potential deadlocks in mana napi ops
error: patch fragment without header at line 23: @@ -2102,9 +2108,11 @@ static void mana_destroy_rxq(struct mana_port_context *apc,
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 net: mana: Fix potential deadlocks in mana napi ops

please rebase
-- 
pw-bot: cr

^ permalink raw reply

* [PATCH 1/1] Drivers: hv: Select CONFIG_SYSFB only if EFI is enabled
From: mhkelley58 @ 2025-06-13 23:00 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, deller, javierm, arnd
  Cc: linux-kernel, linux-hyperv, stable

From: Michael Kelley <mhklinux@outlook.com>

Commit 96959283a58d ("Drivers: hv: Always select CONFIG_SYSFB
for Hyper-V guests") selects CONFIG_SYSFB for Hyper-V guests
so that screen_info is available to the VMBus driver to get
the location of the framebuffer in Generation 2 VMs. However,
if CONFIG_HYPERV is enabled but CONFIG_EFI is not, a kernel
link error results in ARM64 builds because screen_info is
provided by the EFI firmware interface. While configuring
an ARM64 Hyper-V guest without EFI isn't useful since EFI is
required to boot, the configuration is still possible and
the link error should be prevented.

Fix this by making the selection of CONFIG_SYSFB conditional
on CONFIG_EFI being defined. For Generation 1 VMs on x86/x64,
which don't use EFI, the additional condition is OK because
such VMs get the framebuffer information via a mechanism
that doesn't use screen_info.

Fixes: 96959283a58d ("Drivers: hv: Always select CONFIG_SYSFB for Hyper-V guests")
Reported-by: Arnd Bergmann <arnd@arndb.de>
Closes: https://lore.kernel.org/linux-hyperv/20250610091810.2638058-1-arnd@kernel.org/
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202506080820.1wmkQufc-lkp@intel.com/
Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
 drivers/hv/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1cd188b73b74..57623ca7f350 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -9,7 +9,7 @@ config HYPERV
 	select PARAVIRT
 	select X86_HV_CALLBACK_VECTOR if X86
 	select OF_EARLY_FLATTREE if OF
-	select SYSFB if !HYPERV_VTL_MODE
+	select SYSFB if EFI && !HYPERV_VTL_MODE
 	help
 	  Select this option to run Linux as a Hyper-V client operating
 	  system.
-- 
2.25.1


^ permalink raw reply related

* Re: [PATCH v6 2/5] PCI: hv: Allow dynamic MSI-X vector allocation
From: Bjorn Helgaas @ 2025-06-13 22:03 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: Bjorn Helgaas, Rob Herring, Manivannan Sadhasivam,
	Krzysztof Wilczy�~Dski, Lorenzo Pieralisi, Dexuan Cui,
	Wei Liu, Haiyang Zhang, K. Y. Srinivasan, Michael Kelley,
	linux-hyperv, linux-pci, linux-kernel, Nipun Gupta, Yury Norov,
	Jason Gunthorpe, Jonathan Cameron, Anna-Maria Behnsen, Kevin Tian,
	Long Li, Thomas Gleixner, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, 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: <1749651015-9668-1-git-send-email-shradhagupta@linux.microsoft.com>

On Wed, Jun 11, 2025 at 07:10:15AM -0700, Shradha Gupta wrote:
> Allow dynamic MSI-X vector allocation for pci_hyperv PCI controller
> by adding support for the flag MSI_FLAG_PCI_MSIX_ALLOC_DYN and using
> pci_msix_prepare_desc() to prepare the MSI-X descriptors.
> 
> Feature support added for both x86 and ARM64
> 
> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>

Again, if you need it:

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  Changes in v4:
>  * use the same prepare_desc() callback for arm and x86
> ---
>  Changes in v3:
>  * Add arm64 support
> ---
>  Changes in v2:
>  * split the patch to keep changes in PCI and pci_hyperv controller
>    seperate
>  * replace strings "pci vectors" by "MSI-X vectors"
> ---
>  drivers/pci/controller/pci-hyperv.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index ef5d655a0052..86ca041bf74a 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -2119,6 +2119,7 @@ static struct irq_chip hv_msi_irq_chip = {
>  static struct msi_domain_ops hv_msi_ops = {
>  	.msi_prepare	= hv_msi_prepare,
>  	.msi_free	= hv_msi_free,
> +	.prepare_desc	= pci_msix_prepare_desc,
>  };
>  
>  /**
> @@ -2140,7 +2141,7 @@ static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
>  	hbus->msi_info.ops = &hv_msi_ops;
>  	hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
>  		MSI_FLAG_USE_DEF_CHIP_OPS | MSI_FLAG_MULTI_PCI_MSI |
> -		MSI_FLAG_PCI_MSIX);
> +		MSI_FLAG_PCI_MSIX | MSI_FLAG_PCI_MSIX_ALLOC_DYN);
>  	hbus->msi_info.handler = FLOW_HANDLER;
>  	hbus->msi_info.handler_name = FLOW_NAME;
>  	hbus->msi_info.data = hbus;
> -- 
> 2.34.1
> 

^ permalink raw reply

* Re: [PATCH v6 1/5] PCI/MSI: Export pci_msix_prepare_desc() for dynamic MSI-X allocations
From: Bjorn Helgaas @ 2025-06-13 22:03 UTC (permalink / raw)
  To: Shradha Gupta
  Cc: Jason Gunthorpe, Jonathan Cameron, Anna-Maria Behnsen,
	Thomas Gleixner, Bjorn Helgaas, Michael Kelley, linux-hyperv,
	linux-pci, linux-kernel, Nipun Gupta, Yury Norov, Kevin Tian,
	Long Li, 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, Jakub Kicinski, 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: <1749651001-9436-1-git-send-email-shradhagupta@linux.microsoft.com>

On Wed, Jun 11, 2025 at 07:10:01AM -0700, Shradha Gupta wrote:
> For supporting dynamic MSI-X vector allocation by PCI controllers, enabling
> the flag MSI_FLAG_PCI_MSIX_ALLOC_DYN is not enough, msix_prepare_msi_desc()
> to prepare the MSI descriptor is also needed.
> 
> Export pci_msix_prepare_desc() to allow PCI controllers to support dynamic
> MSI-X vector allocation.
> 
> Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>

If you need it; I see you already have a branch at
https://github.com/shradhagupta6/linux/tree/shradha_v6.16-rc1

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  drivers/pci/msi/irqdomain.c | 5 +++--
>  include/linux/msi.h         | 2 ++
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c
> index c05152733993..765312c92d9b 100644
> --- a/drivers/pci/msi/irqdomain.c
> +++ b/drivers/pci/msi/irqdomain.c
> @@ -222,13 +222,14 @@ static void pci_irq_unmask_msix(struct irq_data *data)
>  	pci_msix_unmask(irq_data_get_msi_desc(data));
>  }
>  
> -static void pci_msix_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *arg,
> -				  struct msi_desc *desc)
> +void pci_msix_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *arg,
> +			   struct msi_desc *desc)
>  {
>  	/* Don't fiddle with preallocated MSI descriptors */
>  	if (!desc->pci.mask_base)
>  		msix_prepare_msi_desc(to_pci_dev(desc->dev), desc);
>  }
> +EXPORT_SYMBOL_GPL(pci_msix_prepare_desc);
>  
>  static const struct msi_domain_template pci_msix_template = {
>  	.chip = {
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index 6863540f4b71..7f254bde5426 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -706,6 +706,8 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
>  					     struct irq_domain *parent);
>  u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev);
>  struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);
> +void pci_msix_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *arg,
> +			   struct msi_desc *desc);
>  #else /* CONFIG_PCI_MSI */
>  static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
>  {
> -- 
> 2.34.1
> 

^ permalink raw reply

* Re: [PATCH 4/4] PCI: hv: Use the correct hypercall for unmasking interrupts on nested
From: Bjorn Helgaas @ 2025-06-13 19:36 UTC (permalink / raw)
  To: Nuno Das Neves
  Cc: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, 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
In-Reply-To: <1749599526-19963-5-git-send-email-nunodasneves@linux.microsoft.com>

On Tue, Jun 10, 2025 at 04:52:06PM -0700, Nuno Das Neves wrote:
> 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.

Maybe strengthen this to say that this issues MAP_DEVICE_INTERRUPT
instead of RETARGET in this case?  (Not just that we "should".) 

> Rename hv_arch_irq_unmask() to hv_irq_retarget_interrupt().

^ permalink raw reply

* [Patch net-next v2] net: mana: Record doorbell physical address in PF mode
From: longli @ 2025-06-13 17:46 UTC (permalink / raw)
  To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shradha Gupta, Simon Horman, Konstantin Taranov,
	Souradeep Chakrabarti, Erick Archer, linux-hyperv, netdev,
	linux-kernel, linux-rdma
  Cc: Long Li

From: Long Li <longli@microsoft.com>

MANA supports RDMA in PF mode. The driver should record the doorbell
physical address when in PF mode.

The doorbell physical address is used by the RDMA driver to map
doorbell pages of the device to user-mode applications through RDMA
verbs interface. In the past, they have been mapped to user-mode while
the device is in VF mode. With the support for PF mode implemented,
also expose those pages in PF mode.

Signed-off-by: Long Li <longli@microsoft.com>
---
Changes
v2: add more details in commit message on how the doorbell physical address is used

 drivers/net/ethernet/microsoft/mana/gdma_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index 3504507477c6..52cf7112762c 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -31,6 +31,9 @@ static void mana_gd_init_pf_regs(struct pci_dev *pdev)
 	gc->db_page_base = gc->bar0_va +
 				mana_gd_r64(gc, GDMA_PF_REG_DB_PAGE_OFF);
 
+	gc->phys_db_page_base = gc->bar0_pa +
+				mana_gd_r64(gc, GDMA_PF_REG_DB_PAGE_OFF);
+
 	sriov_base_off = mana_gd_r64(gc, GDMA_SRIOV_REG_CFG_BASE_OFF);
 
 	sriov_base_va = gc->bar0_va + sriov_base_off;
-- 
2.25.1


^ permalink raw reply related

* Re: [PATCH net-next,v7] net: mana: Add handler for hardware servicing events
From: Haiyang Zhang @ 2025-06-13 17:06 UTC (permalink / raw)
  To: Jakub Kicinski, Haiyang Zhang
  Cc: linux-hyperv@vger.kernel.org, netdev@vger.kernel.org, Dexuan Cui,
	stephen@networkplumber.org, KY Srinivasan, Paul Rosswurm,
	olaf@aepfle.de, vkuznets@redhat.com, davem@davemloft.net,
	wei.liu@kernel.org, edumazet@google.com, pabeni@redhat.com,
	leon@kernel.org, Long Li, ssengar@linux.microsoft.com,
	linux-rdma@vger.kernel.org, daniel@iogearbox.net,
	john.fastabend@gmail.com, bpf@vger.kernel.org, ast@kernel.org,
	hawk@kernel.org, tglx@linutronix.de,
	shradhagupta@linux.microsoft.com, andrew+netdev@lunn.ch,
	Konstantin Taranov, horms@kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20250612182143.16f857a9@kernel.org>



> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Thursday, June 12, 2025 9:22 PM
> To: Haiyang Zhang <haiyangz@linux.microsoft.com>
> Cc: linux-hyperv@vger.kernel.org; netdev@vger.kernel.org; Haiyang Zhang
> <haiyangz@microsoft.com>; Dexuan Cui <decui@microsoft.com>;
> stephen@networkplumber.org; KY Srinivasan <kys@microsoft.com>; Paul
> Rosswurm <paulros@microsoft.com>; olaf@aepfle.de; vkuznets@redhat.com;
> davem@davemloft.net; wei.liu@kernel.org; edumazet@google.com;
> pabeni@redhat.com; leon@kernel.org; Long Li <longli@microsoft.com>;
> ssengar@linux.microsoft.com; linux-rdma@vger.kernel.org;
> daniel@iogearbox.net; john.fastabend@gmail.com; bpf@vger.kernel.org;
> ast@kernel.org; hawk@kernel.org; tglx@linutronix.de;
> shradhagupta@linux.microsoft.com; andrew+netdev@lunn.ch; Konstantin
> Taranov <kotaranov@microsoft.com>; horms@kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [EXTERNAL] Re: [PATCH net-next,v7] net: mana: Add handler for
> hardware servicing events
> 
> 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?

Thanks for your suggestion! I tested and found that I can rmmod mana 
during the sleep and caused accessing freed memory. And getting the extra 
module refcnt fixed this (prevented rmmod during sleep). So, I added back
the module refcnt holding, and submitted v8.

Thanks,
- Haiyang


^ permalink raw reply

* RE: [PATCH net-next v2 2/4] net: mana: Add support for net_shaper_ops
From: Long Li @ 2025-06-13 17:04 UTC (permalink / raw)
  To: Erni Sri Satya Vennela, 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, gerhard@engleder-embedded.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: <1749813627-8377-3-git-send-email-ernis@linux.microsoft.com>

> Subject: [PATCH net-next v2 2/4] net: mana: Add support for net_shaper_ops
> 
> Introduce support for net_shaper_ops in the MANA driver, enabling configuration
> of rate limiting on the MANA NIC.
> 
> To apply rate limiting, the driver issues a HWC command via
> mana_set_bw_clamp() and updates the corresponding shaper object in the
> net_shaper cache. If an error occurs during this process, the driver restores the
> previous speed by querying the current link configuration using
> mana_query_link_cfg().
> 
> The minimum supported bandwidth is 100 Mbps, and only values that are exact
> multiples of 100 Mbps are allowed. Any other values are rejected.
> 
> To remove a shaper, the driver resets the bandwidth to the maximum supported
> by the SKU using mana_set_bw_clamp() and clears the associated cache entry. If
> an error occurs during this process, the shaper details are retained.
> 
> On the hardware that does not support these APIs, the net-shaper calls to set
> speed would fail.
> 
> Set the speed:
> ./tools/net/ynl/pyynl/cli.py \
>  --spec Documentation/netlink/specs/net_shaper.yaml \  --do set --json
> '{"ifindex":'$IFINDEX',
> 		   "handle":{"scope": "netdev", "id":'$ID' },
> 		   "bw-max": 200000000 }'
> 
> Get the shaper details:
> ./tools/net/ynl/pyynl/cli.py \
>  --spec Documentation/netlink/specs/net_shaper.yaml \  --do get --json
> '{"ifindex":'$IFINDEX',
> 		      "handle":{"scope": "netdev", "id":'$ID' }}'
> 
> > {'bw-max': 200000000,
> > 'handle': {'scope': 'netdev'},
> > 'ifindex': $IFINDEX,
> > 'metric': 'bps'}
> 
> Delete the shaper object:
> ./tools/net/ynl/pyynl/cli.py \
>  --spec Documentation/netlink/specs/net_shaper.yaml \  --do delete --json
> '{"ifindex":'$IFINDEX',
> 		      "handle":{"scope": "netdev","id":'$ID' }}'
> 
> 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>
> Reviewed-by: Saurabh Singh Sengar <ssengar@linux.microsoft.com>

Reviewed-by: Long Li <longli@microsoft.com>

> ---
> Changes in v2:
> * No change.
> ---
>  drivers/net/ethernet/microsoft/mana/mana_en.c | 155 ++++++++++++++++++
>  include/net/mana/mana.h                       |  40 +++++
>  2 files changed, 195 insertions(+)
> 
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index ca5e9c3d374b..7e8bc2c6a194 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -719,6 +719,78 @@ static int mana_change_mtu(struct net_device *ndev,
> int new_mtu)
>  	return err;
>  }
> 
> +static int mana_shaper_set(struct net_shaper_binding *binding,
> +			   const struct net_shaper *shaper,
> +			   struct netlink_ext_ack *extack)
> +{
> +	struct mana_port_context *apc = netdev_priv(binding->netdev);
> +	u32 old_speed, rate;
> +	int err;
> +
> +	if (shaper->handle.scope != NET_SHAPER_SCOPE_NETDEV) {
> +		NL_SET_ERR_MSG_MOD(extack, "net shaper scope should be
> netdev");
> +		return -EINVAL;
> +	}
> +
> +	if (apc->handle.id && shaper->handle.id != apc->handle.id) {
> +		NL_SET_ERR_MSG_MOD(extack, "Cannot create multiple
> shapers");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	if (!shaper->bw_max || (shaper->bw_max % 100000000)) {
> +		NL_SET_ERR_MSG_MOD(extack, "Please use multiples of
> 100Mbps for bandwidth");
> +		return -EINVAL;
> +	}
> +
> +	rate = div_u64(shaper->bw_max, 1000); /* Convert bps to Kbps */
> +	rate = div_u64(rate, 1000);	      /* Convert Kbps to Mbps */
> +
> +	/* Get current speed */
> +	err = mana_query_link_cfg(apc);
> +	old_speed = (err) ? SPEED_UNKNOWN : apc->speed;
> +
> +	if (!err) {
> +		err = mana_set_bw_clamp(apc, rate, TRI_STATE_TRUE);
> +		apc->speed = (err) ? old_speed : rate;
> +		apc->handle = (err) ? apc->handle : shaper->handle;
> +	}
> +
> +	return err;
> +}
> +
> +static int mana_shaper_del(struct net_shaper_binding *binding,
> +			   const struct net_shaper_handle *handle,
> +			   struct netlink_ext_ack *extack)
> +{
> +	struct mana_port_context *apc = netdev_priv(binding->netdev);
> +	int err;
> +
> +	err = mana_set_bw_clamp(apc, 0, TRI_STATE_FALSE);
> +
> +	if (!err) {
> +		/* Reset mana port context parameters */
> +		apc->handle.id = 0;
> +		apc->handle.scope = NET_SHAPER_SCOPE_UNSPEC;
> +		apc->speed = 0;
> +	}
> +
> +	return err;
> +}
> +
> +static void mana_shaper_cap(struct net_shaper_binding *binding,
> +			    enum net_shaper_scope scope,
> +			    unsigned long *flags)
> +{
> +	*flags = BIT(NET_SHAPER_A_CAPS_SUPPORT_BW_MAX) |
> +		 BIT(NET_SHAPER_A_CAPS_SUPPORT_METRIC_BPS);
> +}
> +
> +static const struct net_shaper_ops mana_shaper_ops = {
> +	.set = mana_shaper_set,
> +	.delete = mana_shaper_del,
> +	.capabilities = mana_shaper_cap,
> +};
> +
>  static const struct net_device_ops mana_devops = {
>  	.ndo_open		= mana_open,
>  	.ndo_stop		= mana_close,
> @@ -729,6 +801,7 @@ static const struct net_device_ops mana_devops = {
>  	.ndo_bpf		= mana_bpf,
>  	.ndo_xdp_xmit		= mana_xdp_xmit,
>  	.ndo_change_mtu		= mana_change_mtu,
> +	.net_shaper_ops         = &mana_shaper_ops,
>  };
> 
>  static void mana_cleanup_port_context(struct mana_port_context *apc) @@ -
> 1162,6 +1235,86 @@ static int mana_cfg_vport_steering(struct
> mana_port_context *apc,
>  	return err;
>  }
> 
> +int mana_query_link_cfg(struct mana_port_context *apc) {
> +	struct net_device *ndev = apc->ndev;
> +	struct mana_query_link_config_resp resp = {};
> +	struct mana_query_link_config_req req = {};
> +	int err;
> +
> +	mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_LINK_CONFIG,
> +			     sizeof(req), sizeof(resp));
> +
> +	req.vport = apc->port_handle;
> +	req.hdr.resp.msg_version = GDMA_MESSAGE_V2;
> +
> +	err = mana_send_request(apc->ac, &req, sizeof(req), &resp,
> +				sizeof(resp));
> +
> +	if (err) {
> +		netdev_err(ndev, "Failed to query link config: %d\n", err);
> +		return err;
> +	}
> +
> +	err = mana_verify_resp_hdr(&resp.hdr, MANA_QUERY_LINK_CONFIG,
> +				   sizeof(resp));
> +
> +	if (err || resp.hdr.status) {
> +		netdev_err(ndev, "Failed to query link config: %d, 0x%x\n", err,
> +			   resp.hdr.status);
> +		if (!err)
> +			err = -EOPNOTSUPP;
> +		return err;
> +	}
> +
> +	if (resp.qos_unconfigured) {
> +		err = -EINVAL;
> +		return err;
> +	}
> +	apc->speed = resp.link_speed_mbps;
> +	return 0;
> +}
> +
> +int mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
> +		      int enable_clamping)
> +{
> +	struct mana_set_bw_clamp_resp resp = {};
> +	struct mana_set_bw_clamp_req req = {};
> +	struct net_device *ndev = apc->ndev;
> +	int err;
> +
> +	mana_gd_init_req_hdr(&req.hdr, MANA_SET_BW_CLAMP,
> +			     sizeof(req), sizeof(resp));
> +	req.vport = apc->port_handle;
> +	req.link_speed_mbps = speed;
> +	req.enable_clamping = enable_clamping;
> +
> +	err = mana_send_request(apc->ac, &req, sizeof(req), &resp,
> +				sizeof(resp));
> +
> +	if (err) {
> +		netdev_err(ndev, "Failed to set bandwidth clamp for speed %u,
> err = %d",
> +			   speed, err);
> +		return err;
> +	}
> +
> +	err = mana_verify_resp_hdr(&resp.hdr, MANA_SET_BW_CLAMP,
> +				   sizeof(resp));
> +
> +	if (err || resp.hdr.status) {
> +		netdev_err(ndev, "Failed to set bandwidth clamp: %d, 0x%x\n",
> err,
> +			   resp.hdr.status);
> +		if (!err)
> +			err = -EOPNOTSUPP;
> +		return err;
> +	}
> +
> +	if (resp.qos_unconfigured)
> +		netdev_info(ndev, "QoS is unconfigured\n");
> +
> +	return 0;
> +}
> +
>  int mana_create_wq_obj(struct mana_port_context *apc,
>  		       mana_handle_t vport,
>  		       u32 wq_type, struct mana_obj_spec *wq_spec, @@ -3013,6
> +3166,8 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
>  		goto free_indir;
>  	}
> 
> +	debugfs_create_u32("current_speed", 0400, apc->mana_port_debugfs,
> +&apc->speed);
> +
>  	return 0;
> 
>  free_indir:
> diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h index
> 4176edf1be71..038b18340e51 100644
> --- a/include/net/mana/mana.h
> +++ b/include/net/mana/mana.h
> @@ -5,6 +5,7 @@
>  #define _MANA_H
> 
>  #include <net/xdp.h>
> +#include <net/net_shaper.h>
> 
>  #include "gdma.h"
>  #include "hw_channel.h"
> @@ -526,7 +527,12 @@ struct mana_port_context {
>  	struct mutex vport_mutex;
>  	int vport_use_count;
> 
> +	/* Net shaper handle*/
> +	struct net_shaper_handle handle;
> +
>  	u16 port_idx;
> +	/* Currently configured speed (mbps) */
> +	u32 speed;
> 
>  	bool port_is_up;
>  	bool port_st_save; /* Saved port state */ @@ -562,6 +568,9 @@ struct
> bpf_prog *mana_xdp_get(struct mana_port_context *apc);  void
> mana_chn_setxdp(struct mana_port_context *apc, struct bpf_prog *prog);  int
> mana_bpf(struct net_device *ndev, struct netdev_bpf *bpf);  void
> mana_query_gf_stats(struct mana_port_context *apc);
> +int mana_query_link_cfg(struct mana_port_context *apc); int
> +mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
> +		      int enable_clamping);
>  void mana_query_phy_stats(struct mana_port_context *apc);  int
> mana_pre_alloc_rxbufs(struct mana_port_context *apc, int mtu, int
> num_queues);  void mana_pre_dealloc_rxbufs(struct mana_port_context *apc);
> @@ -589,6 +598,8 @@ enum mana_command_code {
>  	MANA_FENCE_RQ		= 0x20006,
>  	MANA_CONFIG_VPORT_RX	= 0x20007,
>  	MANA_QUERY_VPORT_CONFIG	= 0x20008,
> +	MANA_QUERY_LINK_CONFIG	= 0x2000A,
> +	MANA_SET_BW_CLAMP	= 0x2000B,
>  	MANA_QUERY_PHY_STAT     = 0x2000c,
> 
>  	/* Privileged commands for the PF mode */ @@ -598,6 +609,35 @@
> enum mana_command_code {
>  	MANA_DEREGISTER_HW_PORT	= 0x28004,
>  };
> 
> +/* Query Link Configuration*/
> +struct mana_query_link_config_req {
> +	struct gdma_req_hdr hdr;
> +	mana_handle_t vport;
> +}; /* HW DATA */
> +
> +struct mana_query_link_config_resp {
> +	struct gdma_resp_hdr hdr;
> +	u32 qos_speed_mbps;
> +	u8 qos_unconfigured;
> +	u8 reserved1[3];
> +	u32 link_speed_mbps;
> +	u8 reserved2[4];
> +}; /* HW DATA */
> +
> +/* Set Bandwidth Clamp*/
> +struct mana_set_bw_clamp_req {
> +	struct gdma_req_hdr hdr;
> +	mana_handle_t vport;
> +	enum TRI_STATE enable_clamping;
> +	u32 link_speed_mbps;
> +}; /* HW DATA */
> +
> +struct mana_set_bw_clamp_resp {
> +	struct gdma_resp_hdr hdr;
> +	u8 qos_unconfigured;
> +	u8 reserved[7];
> +}; /* HW DATA */
> +
>  /* Query Device Configuration */
>  struct mana_query_device_cfg_req {
>  	struct gdma_req_hdr hdr;
> --
> 2.34.1


^ permalink raw reply

* RE: [PATCH net-next v2 1/4] net: mana: Fix potential deadlocks in mana napi ops
From: Long Li @ 2025-06-13 17:01 UTC (permalink / raw)
  To: Erni Sri Satya Vennela, 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, gerhard@engleder-embedded.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: <1749813627-8377-2-git-send-email-ernis@linux.microsoft.com>

> Subject: [PATCH net-next v2 1/4] net: mana: Fix potential deadlocks in mana napi
> ops
> 
> When net_shaper_ops are enabled for MANA, netdev_ops_lock becomes active.
> 
> MANA VF setup/teardown by netvsc follows this call chain:
> 
> netvsc_vf_setup()
>         dev_change_flags()
> 		...
>          __dev_open() OR __dev_close()
> 
> dev_change_flags() holds the netdev mutex via netdev_lock_ops.
> 
> Meanwhile, mana_create_txq() and mana_create_rxq() in mana_open() path call
> NAPI APIs (netif_napi_add_tx(), netif_napi_add_weight(), napi_enable()), which
> also try to acquire the same lock, risking deadlock.
> 
> Similarly in the teardown path (mana_close()), netif_napi_disable() and
> netif_napi_del(), 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>
> Reviewed-by: Saurabh Singh Sengar <ssengar@linux.microsoft.com>

Reviewed-by: Long Li <longli@microsoft.com>

> ---
> Changes in v2:
> * Use netdev_lock_ops_to_full() instead of if...else statements for napi
>   APIs.
> * Edit commit message.
> ---
>  drivers/net/ethernet/microsoft/mana/mana_en.c | 30 +++++++++++++------
>  1 file changed, 21 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index e68b8190bb7a..ca5e9c3d374b 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -1912,8 +1912,11 @@ 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);
> +			netdev_lock_ops_to_full(napi->dev);
> +			napi_disable_locked(napi);
> +			netif_napi_del_locked(napi);
> +			netdev_unlock_full_to_ops(napi->dev);
>  			apc->tx_qp[i].txq.napi_initialized = false;
>  		}
>  		mana_destroy_wq_obj(apc, GDMA_SQ, apc-
> >tx_qp[i].tx_object); @@ -2065,8 +2068,11 @@ static int
> mana_create_txq(struct mana_port_context *apc,
> 
>  		mana_create_txq_debugfs(apc, i);
> 
> -		netif_napi_add_tx(net, &cq->napi, mana_poll);
> -		napi_enable(&cq->napi);
> +		set_bit(NAPI_STATE_NO_BUSY_POLL, &cq->napi.state);
> +		netdev_lock_ops_to_full(net);
> +		netif_napi_add_locked(net, &cq->napi, mana_poll);
> +		napi_enable_locked(&cq->napi);
> +		netdev_unlock_full_to_ops(net);
>  		txq->napi_initialized = true;
> 
>  		mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT); @@ -2102,9
> +2108,11 @@ static void mana_destroy_rxq(struct mana_port_context *apc,
>  	if (napi_initialized) {
>  		napi_synchronize(napi);
> 
> -		napi_disable(napi);
> -
> -		netif_napi_del(napi);
> +		netdev_lock_ops_to_full(napi->dev);
> +		napi_disable_locked(napi);
> +		netif_napi_del_locked(napi);
> +		netdev_unlock_full_to_ops(napi->dev);
>  	}
>  	xdp_rxq_info_unreg(&rxq->xdp_rxq);
> 
> @@ -2355,14 +2363,18 @@ static struct mana_rxq *mana_create_rxq(struct
> mana_port_context *apc,
> 
>  	gc->cq_table[cq->gdma_id] = cq->gdma_cq;
> 
> -	netif_napi_add_weight(ndev, &cq->napi, mana_poll, 1);
> +	netdev_lock_ops_to_full(ndev);
> +	netif_napi_add_weight_locked(ndev, &cq->napi, mana_poll, 1);
> +	netdev_unlock_full_to_ops(ndev);
> 
>  	WARN_ON(xdp_rxq_info_reg(&rxq->xdp_rxq, ndev, rxq_idx,
>  				 cq->napi.napi_id));
>  	WARN_ON(xdp_rxq_info_reg_mem_model(&rxq->xdp_rxq,
> MEM_TYPE_PAGE_POOL,
>  					   rxq->page_pool));
> 
> -	napi_enable(&cq->napi);
> +	netdev_lock_ops_to_full(ndev);
> +	napi_enable_locked(&cq->napi);
> +	netdev_unlock_full_to_ops(ndev);
> 
>  	mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT);
>  out:
> --
> 2.34.1


^ permalink raw reply

* [PATCH net-next,v8] net: mana: Add handler for hardware servicing events
From: Haiyang Zhang @ 2025-06-13 17:00 UTC (permalink / raw)
  To: linux-hyperv, netdev
  Cc: haiyangz, decui, stephen, kys, paulros, olaf, vkuznets, davem,
	wei.liu, edumazet, kuba, pabeni, leon, longli, ssengar,
	linux-rdma, daniel, john.fastabend, bpf, ast, hawk, tglx,
	shradhagupta, andrew+netdev, kotaranov, horms, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

To collaborate with hardware servicing events, upon receiving the special
EQE notification from the HW channel, remove the devices on this bus.
Then, after a waiting period based on the device specs, rescan the parent
bus to recover the devices.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Reviewed-by: Simon Horman <horms@kernel.org>
---
v8:
Tested rmmod as suggested by Jakub Kicinski, and found it's necessary to
add back: acquiring module refcnt.

v7:
rebased.

v6:
Not acquiring module refcnt as suggested by Paolo Abeni.

v5:
Get refcnt of the pdev struct to avoid removal before running the work
as suggested by Jakub Kicinski.

v4:
Renamed EQE type 135 to GDMA_EQE_HWC_RESET_REQUEST, since there can
be multiple cases of this reset request.

v3:
Updated for checkpatch warnings as suggested by Simon Horman.

v2:
Added dev_dbg for service type as suggested by Shradha Gupta.
Added driver cap bit.
---
 .../net/ethernet/microsoft/mana/gdma_main.c   | 75 +++++++++++++++++++
 include/net/mana/gdma.h                       | 10 ++-
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index 3504507477c6..069b7a871b78 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -352,11 +352,59 @@ void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit)
 }
 EXPORT_SYMBOL_NS(mana_gd_ring_cq, "NET_MANA");
 
+#define MANA_SERVICE_PERIOD 10
+
+struct mana_serv_work {
+	struct work_struct serv_work;
+	struct pci_dev *pdev;
+};
+
+static void mana_serv_func(struct work_struct *w)
+{
+	struct mana_serv_work *mns_wk;
+	struct pci_bus *bus, *parent;
+	struct pci_dev *pdev;
+
+	mns_wk = container_of(w, struct mana_serv_work, serv_work);
+	pdev = mns_wk->pdev;
+
+	pci_lock_rescan_remove();
+
+	if (!pdev)
+		goto out;
+
+	bus = pdev->bus;
+	if (!bus) {
+		dev_err(&pdev->dev, "MANA service: no bus\n");
+		goto out;
+	}
+
+	parent = bus->parent;
+	if (!parent) {
+		dev_err(&pdev->dev, "MANA service: no parent bus\n");
+		goto out;
+	}
+
+	pci_stop_and_remove_bus_device(bus->self);
+
+	msleep(MANA_SERVICE_PERIOD * 1000);
+
+	pci_rescan_bus(parent);
+
+out:
+	pci_unlock_rescan_remove();
+
+	pci_dev_put(pdev);
+	kfree(mns_wk);
+	module_put(THIS_MODULE);
+}
+
 static void mana_gd_process_eqe(struct gdma_queue *eq)
 {
 	u32 head = eq->head % (eq->queue_size / GDMA_EQE_SIZE);
 	struct gdma_context *gc = eq->gdma_dev->gdma_context;
 	struct gdma_eqe *eq_eqe_ptr = eq->queue_mem_ptr;
+	struct mana_serv_work *mns_wk;
 	union gdma_eqe_info eqe_info;
 	enum gdma_eqe_type type;
 	struct gdma_event event;
@@ -401,6 +449,33 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
 		eq->eq.callback(eq->eq.context, eq, &event);
 		break;
 
+	case GDMA_EQE_HWC_FPGA_RECONFIG:
+		dev_info(gc->dev, "Recv MANA service type:%d\n", type);
+
+		if (gc->in_service) {
+			dev_info(gc->dev, "Already in service\n");
+			break;
+		}
+
+		if (!try_module_get(THIS_MODULE)) {
+			dev_info(gc->dev, "Module is unloading\n");
+			break;
+		}
+
+		mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC);
+		if (!mns_wk) {
+			module_put(THIS_MODULE);
+			break;
+		}
+
+		dev_info(gc->dev, "Start MANA service type:%d\n", type);
+		gc->in_service = true;
+		mns_wk->pdev = to_pci_dev(gc->dev);
+		pci_dev_get(mns_wk->pdev);
+		INIT_WORK(&mns_wk->serv_work, mana_serv_func);
+		schedule_work(&mns_wk->serv_work);
+		break;
+
 	default:
 		break;
 	}
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 3ce56a816425..bfae59202669 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -58,7 +58,7 @@ enum gdma_eqe_type {
 	GDMA_EQE_HWC_INIT_EQ_ID_DB	= 129,
 	GDMA_EQE_HWC_INIT_DATA		= 130,
 	GDMA_EQE_HWC_INIT_DONE		= 131,
-	GDMA_EQE_HWC_SOC_RECONFIG	= 132,
+	GDMA_EQE_HWC_FPGA_RECONFIG	= 132,
 	GDMA_EQE_HWC_SOC_RECONFIG_DATA	= 133,
 	GDMA_EQE_HWC_SOC_SERVICE	= 134,
 	GDMA_EQE_RNIC_QP_FATAL		= 176,
@@ -403,6 +403,8 @@ struct gdma_context {
 	u32			test_event_eq_id;
 
 	bool			is_pf;
+	bool			in_service;
+
 	phys_addr_t		bar0_pa;
 	void __iomem		*bar0_va;
 	void __iomem		*shm_base;
@@ -578,12 +580,16 @@ enum {
 /* Driver can handle holes (zeros) in the device list */
 #define GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP BIT(11)
 
+/* Driver can self reset on FPGA Reconfig EQE notification */
+#define GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE BIT(17)
+
 #define GDMA_DRV_CAP_FLAGS1 \
 	(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
 	 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
 	 GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG | \
 	 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \
-	 GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP)
+	 GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP | \
+	 GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE)
 
 #define GDMA_DRV_CAP_FLAGS2 0
 
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH] hv: add CONFIG_EFI dependency
From: Arnd Bergmann @ 2025-06-13 16:06 UTC (permalink / raw)
  To: Michael Kelley, Roman Kisel, Arnd Bergmann
  Cc: Dexuan Cui, Haiyang Zhang, K. Y. Srinivasan,
	linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
	nunodasneves@linux.microsoft.com, Saurabh Singh Sengar, Wei Liu
In-Reply-To: <SN6PR02MB4157D600219C00D33D00C3B4D477A@SN6PR02MB4157.namprd02.prod.outlook.com>

On Fri, Jun 13, 2025, at 17:50, Michael Kelley wrote:
> From: Michael Kelley <mhklinux@outlook.com> Sent: Tuesday, June 10, 
>
> There are other ways to express the HYPERV dependency on EFI that is
> conditional. But if the condition includes HYPERV_VTL_MODE (which
> it needs to), then there's a dependency loop because
> HYPERV_VTL_MODE depends on HYPERV. So that doesn't work
> either.
>
> To solve the immediate problem, we'll just have to do
>
>     select SYSFB if EFI && !HYPERV_VTL_MODE

Right. Technically, you could do

    select HYPERV_VTL_MODE if !EFI

but that makes no sense from a usability point of view.

> Separately, if we want to express the broader dependency of
> HYPERV on EFI (at least for ARM64), then the dependency of
> HYPERV_VTL_MODE on HYPERV will need to go away. Three
> months back I had suggested not creating that dependency [1],
> but the eventual decision was to add it. [2, and follow discussion]
> We would need to revisit that discussion.
>
> Arnd -- if you'd prefer that I submit the patch, let me know.
> I created the original problem and can clean up the mess. :-)

Yes, please do, I trust you will come up with a better patch
description than I would.

      Arnd

^ permalink raw reply

* RE: [PATCH] hv: add CONFIG_EFI dependency
From: Michael Kelley @ 2025-06-13 15:50 UTC (permalink / raw)
  To: Michael Kelley, Arnd Bergmann, Roman Kisel, Arnd Bergmann
  Cc: Dexuan Cui, Haiyang Zhang, K. Y. Srinivasan,
	linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
	nunodasneves@linux.microsoft.com, Saurabh Singh Sengar, Wei Liu
In-Reply-To: <SN6PR02MB4157D3A61C5DB1357267D712D46AA@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Michael Kelley <mhklinux@outlook.com> Sent: Tuesday, June 10, 2025 11:46 AM
> 
> From: Michael Kelley <mhklinux@outlook.com> Sent: Tuesday, June 10, 2025 9:17 AM
> >
> > From: Arnd Bergmann <arnd@arndb.de> Sent: Tuesday, June 10, 2025 8:46 AM
> > >
> > > On Tue, Jun 10, 2025, at 17:33, Roman Kisel wrote:
> > > >> Selecting SYSFB causes a link failure on arm64 kernels with EFI disabled:
> > > >>
> > > >> ld.lld-21: error: undefined symbol: screen_info
> > > >> >>> referenced by sysfb.c
> > > >> >>>               drivers/firmware/sysfb.o:(sysfb_parent_dev) in archive vmlinux.a
> > > >> >>> referenced by sysfb.c
> > > >>
> > > >> The problem is that sysfb works on the global 'screen_info' structure, which
> > > >> is provided by the firmware interface, either the generic EFI code or the
> > > >> x86 BIOS startup.
> > > >>
> > > >> Assuming that HV always boots Linux using UEFI, the dependency also makes
> > > >> logical sense, since otherwise it is impossible to boot a guest.
> >
> > This problem was flagged by the kernel test robot over the weekend [1], and I
> > Had been thinking about the best solution.
> >
> > Just curious -- do you have real builds that have CONFIG_HYPERV=y (or =m)
> > and CONFIG_EFI=n? I had expected that to be a somewhat nonsense config,
> > but maybe not.
> >
> > Hyper-V supports what it calls "Generation 1" and "Generation 2" guest VMs.
> > Generation 1 guests boot from BIOS, while Generation 2 guests boot from UEFI.
> > x86/x64 can be either generation, while ARM64 is Generation 2 only. Furthermore,
> > the VTL2 paravisor is supported only in Generation 2 VMs. But I'm not clear on
> > what dependencies on EFI the VTL2 paravisor might have, if any. Roman -- are
> > VTL2 paravisors built with CONFIG_EFI=n?
> >
> > > >>
> > > >
> > > > Hyper-V as of recent can boot off DeviceTree with the direct kernel  boot, no UEFI
> > > > is required (examples would be OpenVMM and the OpenHCL paravisor on arm64).
> > >
> > > I was aware of hyperv no longer needing ACPI, but devicetree and UEFI
> > > are orthogonal concepts, and I had expected that even the devicetree
> > > based version would still get booted using a tiny UEFI implementation
> > > even if the kernel doesn't need that. Do you know what type of bootloader
> > > is actually used in the examples you mentioned? Does the hypervisor
> > > just start the kernel at the native entry point without a bootloader
> > > in this case?
> >
> > Need Roman to clarify this.
> >
> > >
> > > > Being no expert in Kconfig unfortunately... If another solution is possible to
> > > > find given the timing constraints (link errors can't wait iiuc) that would be
> > > > great :)
> > > >
> > > > Could something like "select EFI if SYSFB" work?
> > >
> > > You probably mean the reverse here:
> > >
> > >       select SYSFB if EFI && !HYPERV_VTL_MODE
> >
> > Yes, this is one approach I was thinking about. However, this problem
> > exposed the somewhat broader topic that at least for ARM64 normal
> > VMs, CONFIG_HYPERV really does have a dependency on EFI, and that
> > dependency isn't expressed anywhere. For x86/x64, I want to run some
> > experiments to be sure a Generation 1 VM really will build and boot
> > with CONFIG_EFI=n. Then if we can do so, I'd rather add the correct
> > broader dependency on EFI than embedding the dependency just in
> > the SYSFB selection.
> 
> I've built and tested x86/x64 Generation 1 VMs with CONFIG_EFI=n,
> and I don't see any problems. No build-time EFI dependencies have
> accidently crept into the Gen1 code paths over the years. Since
> Roman has confirmed that VTL2 images do not use EFI, we could
> express CONFIG_HYPERV's broader dependency on EFI as:
> 
>      depends on EFI if ARM64 && !HYPERV_VTL_MODE
> 
> which would allow building an image without EFI for an x86/x64
> Generation 1 VM. The newly added "select SYSFB" entry would do the
> right thing and stay unchanged.
> 
> An alternate viewpoint is that we've always built Hyper-V x86/x64
> guest images to be portable between Generation 1 or Generation 2
> VMs, and that allowing x86/x64 images with CONFIG_EFI=n for Gen 1
> VMs only isn't necessary. In that case we could just add
> 
>    depends on EFI if !HYPERV_VTL_MODE
> 
> I lean slightly toward the first of the two, and not requiring EFI on
> x86/x64 if someone really wanted to build an image that only runs
> on Gen 1 VMs. But the downside is that someone who built such an
> image might be surprised it won't run on a Gen 2 VM. Anyone at
> Microsoft want to weigh in on the choice?
> 
> Michael

What I suggested doesn't work. The "depends on" statement
doesn't take an "if" clause. :-(

There are other ways to express the HYPERV dependency on EFI that is
conditional. But if the condition includes HYPERV_VTL_MODE (which
it needs to), then there's a dependency loop because
HYPERV_VTL_MODE depends on HYPERV. So that doesn't work
either.

To solve the immediate problem, we'll just have to do

    select SYSFB if EFI && !HYPERV_VTL_MODE

Separately, if we want to express the broader dependency of
HYPERV on EFI (at least for ARM64), then the dependency of
HYPERV_VTL_MODE on HYPERV will need to go away. Three
months back I had suggested not creating that dependency [1],
but the eventual decision was to add it. [2, and follow discussion]
We would need to revisit that discussion.

Arnd -- if you'd prefer that I submit the patch, let me know.
I created the original problem and can clean up the mess. :-)

Michael

[1] https://lore.kernel.org/lkml/SN6PR02MB4157B22BD56677EFBD215D87D4BE2@SN6PR02MB4157.namprd02.prod.outlook.com/
[2] https://lore.kernel.org/linux-hyperv/20250307220304.247725-4-romank@linux.microsoft.com/

^ permalink raw reply

* [PATCH net-next v2 4/4] net: mana: Handle unsupported HWC commands
From: Erni Sri Satya Vennela @ 2025-06-13 11:20 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, longli, kotaranov, horms, shirazsaleem, leon, ernis,
	shradhagupta, schakrabarti, gerhard, rosenp, sdf, linux-hyperv,
	netdev, linux-kernel, linux-rdma
In-Reply-To: <1749813627-8377-1-git-send-email-ernis@linux.microsoft.com>

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>
Reviewed-by: Saurabh Singh Sengar <ssengar@linux.microsoft.com>
Reviewed-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
---
Changes in v2:
* Define GDMA_STATUS_CMD_UNSUPPORTED for unsupported HWC status code
  instead of using -1.
---
 drivers/net/ethernet/microsoft/mana/hw_channel.c |  4 ++++
 drivers/net/ethernet/microsoft/mana/mana_en.c    | 11 +++++++++++
 include/net/mana/gdma.h                          |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index 3d3677c0d014..650d22654d49 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -891,6 +891,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 == GDMA_STATUS_CMD_UNSUPPORTED) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
 		if (req_msg->req.msg_type != MANA_QUERY_PHY_STAT)
 			dev_err(hwc->dev, "HWC: Failed hw_channel req: 0x%x\n",
 				ctx->status_code);
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 54a86c233948..50a947859bd0 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -847,6 +847,9 @@ static int mana_send_request(struct mana_context *ac, void *in_buf,
 	err = mana_gd_send_request(gc, in_len, in_buf, out_len,
 				   out_buf);
 	if (err || resp->status) {
+		if (err == -EOPNOTSUPP)
+			return err;
+
 		if (req->req.msg_type != MANA_QUERY_PHY_STAT)
 			dev_err(dev, "Failed to send mana message: %d, 0x%x\n",
 				err, resp->status);
@@ -1252,6 +1255,10 @@ int mana_query_link_cfg(struct mana_port_context *apc)
 				sizeof(resp));
 
 	if (err) {
+		if (err == -EOPNOTSUPP) {
+			netdev_info_once(ndev, "MANA_QUERY_LINK_CONFIG not supported\n");
+			return err;
+		}
 		netdev_err(ndev, "Failed to query link config: %d\n", err);
 		return err;
 	}
@@ -1294,6 +1301,10 @@ int mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
 				sizeof(resp));
 
 	if (err) {
+		if (err == -EOPNOTSUPP) {
+			netdev_info_once(ndev, "MANA_SET_BW_CLAMP not supported\n");
+			return err;
+		}
 		netdev_err(ndev, "Failed to set bandwidth clamp for speed %u, err = %d",
 			   speed, err);
 		return err;
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 3ce56a816425..7752ab0a55cf 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -10,6 +10,7 @@
 #include "shm_channel.h"
 
 #define GDMA_STATUS_MORE_ENTRIES	0x00000105
+#define GDMA_STATUS_CMD_UNSUPPORTED	0xffffffff
 
 /* Structures labeled with "HW DATA" are exchanged with the hardware. All of
  * them are naturally aligned and hence don't need __packed.
-- 
2.34.1


^ permalink raw reply related

* [PATCH net-next v2 3/4] net: mana: Add speed support in mana_get_link_ksettings
From: Erni Sri Satya Vennela @ 2025-06-13 11:20 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, longli, kotaranov, horms, shirazsaleem, leon, ernis,
	shradhagupta, schakrabarti, gerhard, rosenp, sdf, linux-hyperv,
	netdev, linux-kernel, linux-rdma
In-Reply-To: <1749813627-8377-1-git-send-email-ernis@linux.microsoft.com>

Allow mana ethtool get_link_ksettings operation to report
the maximum speed supported by the SKU in mbps.

The driver retrieves this information by issuing a
HWC command to the hardware via mana_query_link_cfg(),
which retrieves the SKU's maximum supported speed.

These APIs when invoked on hardware that are older/do
not support these APIs, the speed would be reported as UNKNOWN.

Before:
$ethtool enP30832s1
> Settings for enP30832s1:
        Supported ports: [  ]
        Supported link modes:   Not reported
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: Unknown!
        Duplex: Full
        Auto-negotiation: off
        Port: Other
        PHYAD: 0
        Transceiver: internal
        Link detected: yes

After:
$ethtool enP30832s1
> Settings for enP30832s1:
        Supported ports: [  ]
        Supported link modes:   Not reported
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 16000Mb/s
        Duplex: Full
        Auto-negotiation: off
        Port: Other
        PHYAD: 0
        Transceiver: internal
        Link detected: yes

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>
Reviewed-by: Saurabh Singh Sengar <ssengar@linux.microsoft.com>
---
Changes in v2:
* No change.
---
 drivers/net/ethernet/microsoft/mana/mana_en.c      | 1 +
 drivers/net/ethernet/microsoft/mana/mana_ethtool.c | 6 ++++++
 include/net/mana/mana.h                            | 2 ++
 3 files changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 7e8bc2c6a194..54a86c233948 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -1272,6 +1272,7 @@ int mana_query_link_cfg(struct mana_port_context *apc)
 		return err;
 	}
 	apc->speed = resp.link_speed_mbps;
+	apc->max_speed = resp.qos_speed_mbps;
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
index 4fb3a04994a2..a1afa75a9463 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
@@ -495,6 +495,12 @@ static int mana_set_ringparam(struct net_device *ndev,
 static int mana_get_link_ksettings(struct net_device *ndev,
 				   struct ethtool_link_ksettings *cmd)
 {
+	struct mana_port_context *apc = netdev_priv(ndev);
+	int err;
+
+	err = mana_query_link_cfg(apc);
+	cmd->base.speed = (err) ? SPEED_UNKNOWN : apc->max_speed;
+
 	cmd->base.duplex = DUPLEX_FULL;
 	cmd->base.port = PORT_OTHER;
 
diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
index 038b18340e51..e1030a7d2daa 100644
--- a/include/net/mana/mana.h
+++ b/include/net/mana/mana.h
@@ -533,6 +533,8 @@ struct mana_port_context {
 	u16 port_idx;
 	/* Currently configured speed (mbps) */
 	u32 speed;
+	/* Maximum speed supported by the SKU (mbps) */
+	u32 max_speed;
 
 	bool port_is_up;
 	bool port_st_save; /* Saved port state */
-- 
2.34.1


^ permalink raw reply related

* [PATCH net-next v2 2/4] net: mana: Add support for net_shaper_ops
From: Erni Sri Satya Vennela @ 2025-06-13 11:20 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, longli, kotaranov, horms, shirazsaleem, leon, ernis,
	shradhagupta, schakrabarti, gerhard, rosenp, sdf, linux-hyperv,
	netdev, linux-kernel, linux-rdma
In-Reply-To: <1749813627-8377-1-git-send-email-ernis@linux.microsoft.com>

Introduce support for net_shaper_ops in the MANA driver,
enabling configuration of rate limiting on the MANA NIC.

To apply rate limiting, the driver issues a HWC command via
mana_set_bw_clamp() and updates the corresponding shaper object
in the net_shaper cache. If an error occurs during this process,
the driver restores the previous speed by querying the current link
configuration using mana_query_link_cfg().

The minimum supported bandwidth is 100 Mbps, and only values that are
exact multiples of 100 Mbps are allowed. Any other values are rejected.

To remove a shaper, the driver resets the bandwidth to the maximum
supported by the SKU using mana_set_bw_clamp() and clears the
associated cache entry. If an error occurs during this process,
the shaper details are retained.

On the hardware that does not support these APIs, the net-shaper
calls to set speed would fail.

Set the speed:
./tools/net/ynl/pyynl/cli.py \
 --spec Documentation/netlink/specs/net_shaper.yaml \
 --do set --json '{"ifindex":'$IFINDEX',
		   "handle":{"scope": "netdev", "id":'$ID' },
		   "bw-max": 200000000 }'

Get the shaper details:
./tools/net/ynl/pyynl/cli.py \
 --spec Documentation/netlink/specs/net_shaper.yaml \
 --do get --json '{"ifindex":'$IFINDEX',
		      "handle":{"scope": "netdev", "id":'$ID' }}'

> {'bw-max': 200000000,
> 'handle': {'scope': 'netdev'},
> 'ifindex': $IFINDEX,
> 'metric': 'bps'}

Delete the shaper object:
./tools/net/ynl/pyynl/cli.py \
 --spec Documentation/netlink/specs/net_shaper.yaml \
 --do delete --json '{"ifindex":'$IFINDEX',
		      "handle":{"scope": "netdev","id":'$ID' }}'

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>
Reviewed-by: Saurabh Singh Sengar <ssengar@linux.microsoft.com>
---
Changes in v2:
* No change.
---
 drivers/net/ethernet/microsoft/mana/mana_en.c | 155 ++++++++++++++++++
 include/net/mana/mana.h                       |  40 +++++
 2 files changed, 195 insertions(+)

diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index ca5e9c3d374b..7e8bc2c6a194 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -719,6 +719,78 @@ static int mana_change_mtu(struct net_device *ndev, int new_mtu)
 	return err;
 }
 
+static int mana_shaper_set(struct net_shaper_binding *binding,
+			   const struct net_shaper *shaper,
+			   struct netlink_ext_ack *extack)
+{
+	struct mana_port_context *apc = netdev_priv(binding->netdev);
+	u32 old_speed, rate;
+	int err;
+
+	if (shaper->handle.scope != NET_SHAPER_SCOPE_NETDEV) {
+		NL_SET_ERR_MSG_MOD(extack, "net shaper scope should be netdev");
+		return -EINVAL;
+	}
+
+	if (apc->handle.id && shaper->handle.id != apc->handle.id) {
+		NL_SET_ERR_MSG_MOD(extack, "Cannot create multiple shapers");
+		return -EOPNOTSUPP;
+	}
+
+	if (!shaper->bw_max || (shaper->bw_max % 100000000)) {
+		NL_SET_ERR_MSG_MOD(extack, "Please use multiples of 100Mbps for bandwidth");
+		return -EINVAL;
+	}
+
+	rate = div_u64(shaper->bw_max, 1000); /* Convert bps to Kbps */
+	rate = div_u64(rate, 1000);	      /* Convert Kbps to Mbps */
+
+	/* Get current speed */
+	err = mana_query_link_cfg(apc);
+	old_speed = (err) ? SPEED_UNKNOWN : apc->speed;
+
+	if (!err) {
+		err = mana_set_bw_clamp(apc, rate, TRI_STATE_TRUE);
+		apc->speed = (err) ? old_speed : rate;
+		apc->handle = (err) ? apc->handle : shaper->handle;
+	}
+
+	return err;
+}
+
+static int mana_shaper_del(struct net_shaper_binding *binding,
+			   const struct net_shaper_handle *handle,
+			   struct netlink_ext_ack *extack)
+{
+	struct mana_port_context *apc = netdev_priv(binding->netdev);
+	int err;
+
+	err = mana_set_bw_clamp(apc, 0, TRI_STATE_FALSE);
+
+	if (!err) {
+		/* Reset mana port context parameters */
+		apc->handle.id = 0;
+		apc->handle.scope = NET_SHAPER_SCOPE_UNSPEC;
+		apc->speed = 0;
+	}
+
+	return err;
+}
+
+static void mana_shaper_cap(struct net_shaper_binding *binding,
+			    enum net_shaper_scope scope,
+			    unsigned long *flags)
+{
+	*flags = BIT(NET_SHAPER_A_CAPS_SUPPORT_BW_MAX) |
+		 BIT(NET_SHAPER_A_CAPS_SUPPORT_METRIC_BPS);
+}
+
+static const struct net_shaper_ops mana_shaper_ops = {
+	.set = mana_shaper_set,
+	.delete = mana_shaper_del,
+	.capabilities = mana_shaper_cap,
+};
+
 static const struct net_device_ops mana_devops = {
 	.ndo_open		= mana_open,
 	.ndo_stop		= mana_close,
@@ -729,6 +801,7 @@ static const struct net_device_ops mana_devops = {
 	.ndo_bpf		= mana_bpf,
 	.ndo_xdp_xmit		= mana_xdp_xmit,
 	.ndo_change_mtu		= mana_change_mtu,
+	.net_shaper_ops         = &mana_shaper_ops,
 };
 
 static void mana_cleanup_port_context(struct mana_port_context *apc)
@@ -1162,6 +1235,86 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc,
 	return err;
 }
 
+int mana_query_link_cfg(struct mana_port_context *apc)
+{
+	struct net_device *ndev = apc->ndev;
+	struct mana_query_link_config_resp resp = {};
+	struct mana_query_link_config_req req = {};
+	int err;
+
+	mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_LINK_CONFIG,
+			     sizeof(req), sizeof(resp));
+
+	req.vport = apc->port_handle;
+	req.hdr.resp.msg_version = GDMA_MESSAGE_V2;
+
+	err = mana_send_request(apc->ac, &req, sizeof(req), &resp,
+				sizeof(resp));
+
+	if (err) {
+		netdev_err(ndev, "Failed to query link config: %d\n", err);
+		return err;
+	}
+
+	err = mana_verify_resp_hdr(&resp.hdr, MANA_QUERY_LINK_CONFIG,
+				   sizeof(resp));
+
+	if (err || resp.hdr.status) {
+		netdev_err(ndev, "Failed to query link config: %d, 0x%x\n", err,
+			   resp.hdr.status);
+		if (!err)
+			err = -EOPNOTSUPP;
+		return err;
+	}
+
+	if (resp.qos_unconfigured) {
+		err = -EINVAL;
+		return err;
+	}
+	apc->speed = resp.link_speed_mbps;
+	return 0;
+}
+
+int mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
+		      int enable_clamping)
+{
+	struct mana_set_bw_clamp_resp resp = {};
+	struct mana_set_bw_clamp_req req = {};
+	struct net_device *ndev = apc->ndev;
+	int err;
+
+	mana_gd_init_req_hdr(&req.hdr, MANA_SET_BW_CLAMP,
+			     sizeof(req), sizeof(resp));
+	req.vport = apc->port_handle;
+	req.link_speed_mbps = speed;
+	req.enable_clamping = enable_clamping;
+
+	err = mana_send_request(apc->ac, &req, sizeof(req), &resp,
+				sizeof(resp));
+
+	if (err) {
+		netdev_err(ndev, "Failed to set bandwidth clamp for speed %u, err = %d",
+			   speed, err);
+		return err;
+	}
+
+	err = mana_verify_resp_hdr(&resp.hdr, MANA_SET_BW_CLAMP,
+				   sizeof(resp));
+
+	if (err || resp.hdr.status) {
+		netdev_err(ndev, "Failed to set bandwidth clamp: %d, 0x%x\n", err,
+			   resp.hdr.status);
+		if (!err)
+			err = -EOPNOTSUPP;
+		return err;
+	}
+
+	if (resp.qos_unconfigured)
+		netdev_info(ndev, "QoS is unconfigured\n");
+
+	return 0;
+}
+
 int mana_create_wq_obj(struct mana_port_context *apc,
 		       mana_handle_t vport,
 		       u32 wq_type, struct mana_obj_spec *wq_spec,
@@ -3013,6 +3166,8 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
 		goto free_indir;
 	}
 
+	debugfs_create_u32("current_speed", 0400, apc->mana_port_debugfs, &apc->speed);
+
 	return 0;
 
 free_indir:
diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
index 4176edf1be71..038b18340e51 100644
--- a/include/net/mana/mana.h
+++ b/include/net/mana/mana.h
@@ -5,6 +5,7 @@
 #define _MANA_H
 
 #include <net/xdp.h>
+#include <net/net_shaper.h>
 
 #include "gdma.h"
 #include "hw_channel.h"
@@ -526,7 +527,12 @@ struct mana_port_context {
 	struct mutex vport_mutex;
 	int vport_use_count;
 
+	/* Net shaper handle*/
+	struct net_shaper_handle handle;
+
 	u16 port_idx;
+	/* Currently configured speed (mbps) */
+	u32 speed;
 
 	bool port_is_up;
 	bool port_st_save; /* Saved port state */
@@ -562,6 +568,9 @@ struct bpf_prog *mana_xdp_get(struct mana_port_context *apc);
 void mana_chn_setxdp(struct mana_port_context *apc, struct bpf_prog *prog);
 int mana_bpf(struct net_device *ndev, struct netdev_bpf *bpf);
 void mana_query_gf_stats(struct mana_port_context *apc);
+int mana_query_link_cfg(struct mana_port_context *apc);
+int mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
+		      int enable_clamping);
 void mana_query_phy_stats(struct mana_port_context *apc);
 int mana_pre_alloc_rxbufs(struct mana_port_context *apc, int mtu, int num_queues);
 void mana_pre_dealloc_rxbufs(struct mana_port_context *apc);
@@ -589,6 +598,8 @@ enum mana_command_code {
 	MANA_FENCE_RQ		= 0x20006,
 	MANA_CONFIG_VPORT_RX	= 0x20007,
 	MANA_QUERY_VPORT_CONFIG	= 0x20008,
+	MANA_QUERY_LINK_CONFIG	= 0x2000A,
+	MANA_SET_BW_CLAMP	= 0x2000B,
 	MANA_QUERY_PHY_STAT     = 0x2000c,
 
 	/* Privileged commands for the PF mode */
@@ -598,6 +609,35 @@ enum mana_command_code {
 	MANA_DEREGISTER_HW_PORT	= 0x28004,
 };
 
+/* Query Link Configuration*/
+struct mana_query_link_config_req {
+	struct gdma_req_hdr hdr;
+	mana_handle_t vport;
+}; /* HW DATA */
+
+struct mana_query_link_config_resp {
+	struct gdma_resp_hdr hdr;
+	u32 qos_speed_mbps;
+	u8 qos_unconfigured;
+	u8 reserved1[3];
+	u32 link_speed_mbps;
+	u8 reserved2[4];
+}; /* HW DATA */
+
+/* Set Bandwidth Clamp*/
+struct mana_set_bw_clamp_req {
+	struct gdma_req_hdr hdr;
+	mana_handle_t vport;
+	enum TRI_STATE enable_clamping;
+	u32 link_speed_mbps;
+}; /* HW DATA */
+
+struct mana_set_bw_clamp_resp {
+	struct gdma_resp_hdr hdr;
+	u8 qos_unconfigured;
+	u8 reserved[7];
+}; /* HW DATA */
+
 /* Query Device Configuration */
 struct mana_query_device_cfg_req {
 	struct gdma_req_hdr hdr;
-- 
2.34.1


^ permalink raw reply related

* [PATCH net-next v2 1/4] net: mana: Fix potential deadlocks in mana napi ops
From: Erni Sri Satya Vennela @ 2025-06-13 11:20 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, longli, kotaranov, horms, shirazsaleem, leon, ernis,
	shradhagupta, schakrabarti, gerhard, rosenp, sdf, linux-hyperv,
	netdev, linux-kernel, linux-rdma
In-Reply-To: <1749813627-8377-1-git-send-email-ernis@linux.microsoft.com>

When net_shaper_ops are enabled for MANA, netdev_ops_lock
becomes active.

MANA VF setup/teardown by netvsc follows this call chain:

netvsc_vf_setup()
        dev_change_flags()
		...
         __dev_open() OR __dev_close()

dev_change_flags() holds the netdev mutex via netdev_lock_ops.

Meanwhile, mana_create_txq() and mana_create_rxq() in mana_open()
path call NAPI APIs (netif_napi_add_tx(), netif_napi_add_weight(),
napi_enable()), which also try to acquire the same lock, risking
deadlock.

Similarly in the teardown path (mana_close()), netif_napi_disable()
and netif_napi_del(), 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>
Reviewed-by: Saurabh Singh Sengar <ssengar@linux.microsoft.com>
---
Changes in v2:
* Use netdev_lock_ops_to_full() instead of if...else statements for napi
  APIs.
* Edit commit message.
---
 drivers/net/ethernet/microsoft/mana/mana_en.c | 30 +++++++++++++------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index e68b8190bb7a..ca5e9c3d374b 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -1912,8 +1912,11 @@ 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);
+			netdev_lock_ops_to_full(napi->dev);
+			napi_disable_locked(napi);
+			netif_napi_del_locked(napi);
+			netdev_unlock_full_to_ops(napi->dev);
 			apc->tx_qp[i].txq.napi_initialized = false;
 		}
 		mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i].tx_object);
@@ -2065,8 +2068,11 @@ static int mana_create_txq(struct mana_port_context *apc,
 
 		mana_create_txq_debugfs(apc, i);
 
-		netif_napi_add_tx(net, &cq->napi, mana_poll);
-		napi_enable(&cq->napi);
+		set_bit(NAPI_STATE_NO_BUSY_POLL, &cq->napi.state);
+		netdev_lock_ops_to_full(net);
+		netif_napi_add_locked(net, &cq->napi, mana_poll);
+		napi_enable_locked(&cq->napi);
+		netdev_unlock_full_to_ops(net);
 		txq->napi_initialized = true;
 
 		mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT);
@@ -2102,9 +2108,11 @@ static void mana_destroy_rxq(struct mana_port_context *apc,
 	if (napi_initialized) {
 		napi_synchronize(napi);
 
-		napi_disable(napi);
-
-		netif_napi_del(napi);
+		netdev_lock_ops_to_full(napi->dev);
+		napi_disable_locked(napi);
+		netif_napi_del_locked(napi);
+		netdev_unlock_full_to_ops(napi->dev);
 	}
 	xdp_rxq_info_unreg(&rxq->xdp_rxq);
 
@@ -2355,14 +2363,18 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
 
 	gc->cq_table[cq->gdma_id] = cq->gdma_cq;
 
-	netif_napi_add_weight(ndev, &cq->napi, mana_poll, 1);
+	netdev_lock_ops_to_full(ndev);
+	netif_napi_add_weight_locked(ndev, &cq->napi, mana_poll, 1);
+	netdev_unlock_full_to_ops(ndev);
 
 	WARN_ON(xdp_rxq_info_reg(&rxq->xdp_rxq, ndev, rxq_idx,
 				 cq->napi.napi_id));
 	WARN_ON(xdp_rxq_info_reg_mem_model(&rxq->xdp_rxq, MEM_TYPE_PAGE_POOL,
 					   rxq->page_pool));
 
-	napi_enable(&cq->napi);
+	netdev_lock_ops_to_full(ndev);
+	napi_enable_locked(&cq->napi);
+	netdev_unlock_full_to_ops(ndev);
 
 	mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT);
 out:
-- 
2.34.1


^ permalink raw reply related

* [PATCH net-next v2 0/4] Support bandwidth clamping in mana using net shapers
From: Erni Sri Satya Vennela @ 2025-06-13 11:20 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, longli, kotaranov, horms, shirazsaleem, leon, ernis,
	shradhagupta, schakrabarti, gerhard, rosenp, sdf, linux-hyperv,
	netdev, linux-kernel, linux-rdma

This patchset introduces hardware-backed bandwidth rate limiting
for MANA NICs via the net_shaper_ops interface, enabling efficient and
fine-grained traffic shaping directly on the device.

Previously, MANA lacked a mechanism for user-configurable bandwidth
control. With this addition, users can now configure shaping parameters,
allowing better traffic management and performance isolation.

The implementation includes the net_shaper_ops callbacks in the MANA
driver and supports one shaper per vport. Add shaping support via
mana_set_bw_clamp(), allowing the configuration of bandwidth rates
in 100 Mbps increments (minimum 100 Mbps). The driver validates input
and rejects unsupported values. On failure, it restores the previous
configuration which is queried using mana_query_link_cfg() or
retains the current state.

To prevent potential deadlocks introduced by net_shaper_ops, switch to
_locked variants of NAPI APIs when netdevops_lock is held during
VF setup and teardown.

Also, Add support for ethtool get_link_ksettings to report the maximum
link speed supported by the SKU in mbps.

These APIs when invoked on hardware that are older or that do
not support these APIs, the speed would be reported as UNKNOWN and
the net-shaper calls to set speed would fail.
---
Changes in v2:
* Rebase to latest net-next branch.
* Edit commit message in 
  "net: mana: Fix potential deadlocks in mana napi ops".
* Use netdev_lock_ops_to_full() instead of explicit if..else statements
  for napi APIs.
* Define GDMA_STATUS_CMD_UNSUPPORTED for unsupported HWC status code.
---
Erni Sri Satya Vennela (4):
  net: mana: Fix potential deadlocks in mana napi ops
  net: mana: Add support for net_shaper_ops
  net: mana: Add speed support in mana_get_link_ksettings
  net: mana: Handle unsupported HWC commands

 .../net/ethernet/microsoft/mana/hw_channel.c  |   4 +
 drivers/net/ethernet/microsoft/mana/mana_en.c | 197 +++++++++++++++++-
 .../ethernet/microsoft/mana/mana_ethtool.c    |   6 +
 include/net/mana/gdma.h                       |   1 +
 include/net/mana/mana.h                       |  42 ++++
 5 files changed, 241 insertions(+), 9 deletions(-)

-- 
2.34.1


^ permalink raw reply

* [RFC Patch v2 4/4] x86/Hyper-V: Allow Hyper-V to inject Hyper-V vectors
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 enabled, call Secure AVIC
function to allow Hyper-V to inject STIMER0 interrupt.

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

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 3d1d3547095a..3b99fffb9ffd 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -132,6 +132,10 @@ static int hv_cpu_init(unsigned int cpu)
 		wrmsrq(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
 	}
 
+	/* Allow Hyper-V stimer vector to be injected from Hypervisor. */
+	if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
+		apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, true);
+
 	return hyperv_init_ghcb();
 }
 
-- 
2.25.1


^ permalink raw reply related

* [RFC Patch v2 3/4] x86/Hyper-V: Not use auto-eoi 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>

Hyper-V doesn't support auto-eoi with Secure AVIC.
So Enable HV_DEPRECATING_AEOI_RECOMMENDED flag
to force to write eoi register after handling
interrupt.

Signed-off-by: Tianyu Lan <tiala@microsoft.com>
---
 arch/x86/kernel/cpu/mshyperv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index c78f860419d6..8f029650f16c 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -463,6 +463,8 @@ static void __init ms_hyperv_init_platform(void)
 		 ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
 
 	hv_identify_partition_type();
+	if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+		ms_hyperv.hints |= HV_DEPRECATING_AEOI_RECOMMENDED;
 
 	if (ms_hyperv.hints & HV_X64_HYPERV_NESTED) {
 		hv_nested = true;
-- 
2.25.1


^ permalink raw reply related

* [RFC Patch v2 2/4] drivers/hv: Allow vmbus message synic interrupt injected from Hyper-V
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 enabled, Vmbus driver should
call x2apic Secure AVIC interface to allow Hyper-V
to inject Vmbus message interrupt.

Signed-off-by: Tianyu Lan <tiala@microsoft.com>
---
 drivers/hv/hv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 308c8f279df8..f78b46c51d69 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/mshyperv.h>
+#include <asm/apic.h>
 #include <linux/set_memory.h>
 #include "hyperv_vmbus.h"
 
@@ -310,6 +311,7 @@ void hv_synic_enable_regs(unsigned int cpu)
 	if (vmbus_irq != -1)
 		enable_percpu_irq(vmbus_irq, 0);
 	shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT);
+	apic_update_vector(smp_processor_id(), vmbus_interrupt, true);
 
 	shared_sint.vector = vmbus_interrupt;
 	shared_sint.masked = false;
-- 
2.25.1


^ permalink raw reply related

* [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


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