* [PATCH net-next v7 02/26] vsock/virtio: pack struct virtio_vsock_skb_cb
From: Bobby Eshleman @ 2025-10-21 23:46 UTC (permalink / raw)
To: Stefano Garzarella, Shuah Khan, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Stefan Hajnoczi,
Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Bryan Tan,
Vishnu Dasa, Broadcom internal kernel review list, Bobby Eshleman
Cc: virtualization, netdev, linux-kselftest, linux-kernel, kvm,
linux-hyperv, berrange, Bobby Eshleman
In-Reply-To: <20251021-vsock-vmtest-v7-0-0661b7b6f081@meta.com>
From: Bobby Eshleman <bobbyeshleman@meta.com>
Reduce holes in struct virtio_vsock_skb_cb. As this struct continues to
grow, we want to keep it trimmed down so it doesn't exceed the size of
skb->cb (currently 48 bytes). Eliminating the 2 byte hole provides an
additional two bytes for new fields at the end of the structure. It does
not shrink the total size, however.
Future work could include combining fields like reply and tap_delivered
into a single bitfield, but currently doing so will not make the total
struct size smaller (although, would extend the tail-end padding area by
one byte).
Before this patch:
struct virtio_vsock_skb_cb {
bool reply; /* 0 1 */
bool tap_delivered; /* 1 1 */
/* XXX 2 bytes hole, try to pack */
u32 offset; /* 4 4 */
/* size: 8, cachelines: 1, members: 3 */
/* sum members: 6, holes: 1, sum holes: 2 */
/* last cacheline: 8 bytes */
};
;
After this patch:
struct virtio_vsock_skb_cb {
u32 offset; /* 0 4 */
bool reply; /* 4 1 */
bool tap_delivered; /* 5 1 */
/* size: 8, cachelines: 1, members: 3 */
/* padding: 2 */
/* last cacheline: 8 bytes */
};
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
include/linux/virtio_vsock.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 0c67543a45c8..87cf4dcac78a 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -10,9 +10,9 @@
#define VIRTIO_VSOCK_SKB_HEADROOM (sizeof(struct virtio_vsock_hdr))
struct virtio_vsock_skb_cb {
+ u32 offset;
bool reply;
bool tap_delivered;
- u32 offset;
};
#define VIRTIO_VSOCK_SKB_CB(skb) ((struct virtio_vsock_skb_cb *)((skb)->cb))
--
2.47.3
^ permalink raw reply related
* [PATCH net-next v7 01/26] vsock: a per-net vsock NS mode state
From: Bobby Eshleman @ 2025-10-21 23:46 UTC (permalink / raw)
To: Stefano Garzarella, Shuah Khan, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Stefan Hajnoczi,
Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Bryan Tan,
Vishnu Dasa, Broadcom internal kernel review list, Bobby Eshleman
Cc: virtualization, netdev, linux-kselftest, linux-kernel, kvm,
linux-hyperv, berrange, Bobby Eshleman
In-Reply-To: <20251021-vsock-vmtest-v7-0-0661b7b6f081@meta.com>
From: Bobby Eshleman <bobbyeshleman@meta.com>
Add the per-net vsock NS mode state. This only adds the structure for
holding the mode and some of the functions for setting/getting and
checking the mode, but does not integrate the functionality yet.
A "net_mode" field is added to vsock_sock to store the mode of the
namespace when the vsock_sock was created. In order to evaluate
namespace mode rules we need to know both a) which namespace the
endpoints are in, and b) what mode that namespace had when the endpoints
were created. This allows us to handle the changing of modes from global
to local *after* a socket has been created by remembering that the mode
was global when the socket was created. If we were to use the current
net's mode instead, then the lookup would fail and the socket would
break.
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
Changes in v7:
- clarify vsock_net_check_mode() comments
- change to `orig_net_mode == VSOCK_NET_MODE_GLOBAL && orig_net_mode == vsk->orig_net_mode`
- remove extraneous explanation of `orig_net_mode`
- rename `written` to `mode_locked`
- rename `vsock_hdr` to `sysctl_hdr`
- change `orig_net_mode` to `net_mode`
- make vsock_net_check_mode() more generic by taking just net pointers
and modes, instead of a vsock_sock ptr, for reuse by transports
(e.g., vhost_vsock)
Changes in v6:
- add orig_net_mode to store mode at creation time which will be used to
avoid breakage when namespace changes mode during socket/VM lifespan
Changes in v5:
- use /proc/sys/net/vsock/ns_mode instead of /proc/net/vsock_ns_mode
- change from net->vsock.ns_mode to net->vsock.mode
- change vsock_net_set_mode() to vsock_net_write_mode()
- vsock_net_write_mode() returns bool for write success to avoid
need to use vsock_net_mode_can_set()
- remove vsock_net_mode_can_set()
---
MAINTAINERS | 1 +
include/net/af_vsock.h | 64 +++++++++++++++++++++++++++++++++++++++++++++
include/net/net_namespace.h | 4 +++
include/net/netns/vsock.h | 20 ++++++++++++++
4 files changed, 89 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4faa7719bf86..c58f9e38898a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27062,6 +27062,7 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/vhost/vsock.c
F: include/linux/virtio_vsock.h
+F: include/net/netns/vsock.h
F: include/uapi/linux/virtio_vsock.h
F: net/vmw_vsock/virtio_transport.c
F: net/vmw_vsock/virtio_transport_common.c
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index d40e978126e3..a1053d3668cf 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/workqueue.h>
+#include <net/netns/vsock.h>
#include <net/sock.h>
#include <uapi/linux/vm_sockets.h>
@@ -65,6 +66,7 @@ struct vsock_sock {
u32 peer_shutdown;
bool sent_request;
bool ignore_connecting_rst;
+ enum vsock_net_mode net_mode;
/* Protected by lock_sock(sk) */
u64 buffer_size;
@@ -256,4 +258,66 @@ static inline bool vsock_msgzerocopy_allow(const struct vsock_transport *t)
{
return t->msgzerocopy_allow && t->msgzerocopy_allow();
}
+
+static inline enum vsock_net_mode vsock_net_mode(struct net *net)
+{
+ enum vsock_net_mode ret;
+
+ spin_lock_bh(&net->vsock.lock);
+ ret = net->vsock.mode;
+ spin_unlock_bh(&net->vsock.lock);
+ return ret;
+}
+
+static inline bool vsock_net_write_mode(struct net *net, u8 mode)
+{
+ bool ret;
+
+ spin_lock_bh(&net->vsock.lock);
+
+ if (net->vsock.mode_locked) {
+ ret = false;
+ goto skip;
+ }
+
+ net->vsock.mode = mode;
+ net->vsock.mode_locked = true;
+ ret = true;
+
+skip:
+ spin_unlock_bh(&net->vsock.lock);
+ return ret;
+}
+
+/* Return true if two namespaces and modes pass the mode rules. Otherwise,
+ * return false.
+ *
+ * ns0 and ns1 are the namespaces being checked.
+ * mode0 and mode1 are the vsock namespace modes of ns0 and ns1.
+ *
+ * Read more about modes in the comment header of net/vmw_vsock/af_vsock.c.
+ */
+static inline bool vsock_net_check_mode(struct net *ns0, enum vsock_net_mode mode0,
+ struct net *ns1, enum vsock_net_mode mode1)
+{
+ /* Any vsocks within the same network namespace are always reachable,
+ * regardless of the mode.
+ */
+ if (net_eq(ns0, ns1))
+ return true;
+
+ /*
+ * If the network namespaces differ, vsocks are only reachable if both
+ * were created in VSOCK_NET_MODE_GLOBAL mode.
+ *
+ * The vsock namespace mode is write-once, and the default is
+ * VSOCK_NET_MODE_GLOBAL. Once set to VSOCK_NET_MODE_LOCAL, it cannot
+ * revert to GLOBAL. It is not possible to have a case where a socket
+ * was created in LOCAL mode, and then the mode switched to GLOBAL.
+ *
+ * As a result, we only need to check if the modes were global at
+ * creation time.
+ */
+ return mode0 == VSOCK_NET_MODE_GLOBAL && mode0 == mode1;
+}
#endif /* __AF_VSOCK_H__ */
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index cb664f6e3558..66d3de1d935f 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -37,6 +37,7 @@
#include <net/netns/smc.h>
#include <net/netns/bpf.h>
#include <net/netns/mctp.h>
+#include <net/netns/vsock.h>
#include <net/net_trackers.h>
#include <linux/ns_common.h>
#include <linux/idr.h>
@@ -196,6 +197,9 @@ struct net {
/* Move to a better place when the config guard is removed. */
struct mutex rtnl_mutex;
#endif
+#if IS_ENABLED(CONFIG_VSOCKETS)
+ struct netns_vsock vsock;
+#endif
} __randomize_layout;
#include <linux/seq_file_net.h>
diff --git a/include/net/netns/vsock.h b/include/net/netns/vsock.h
new file mode 100644
index 000000000000..c9a438ad52f2
--- /dev/null
+++ b/include/net/netns/vsock.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NET_NET_NAMESPACE_VSOCK_H
+#define __NET_NET_NAMESPACE_VSOCK_H
+
+#include <linux/types.h>
+
+enum vsock_net_mode {
+ VSOCK_NET_MODE_GLOBAL,
+ VSOCK_NET_MODE_LOCAL,
+};
+
+struct netns_vsock {
+ struct ctl_table_header *sysctl_hdr;
+ spinlock_t lock;
+
+ /* protected by lock */
+ enum vsock_net_mode mode;
+ bool mode_locked;
+};
+#endif /* __NET_NET_NAMESPACE_VSOCK_H */
--
2.47.3
^ permalink raw reply related
* [PATCH net-next v7 00/26] vsock: add namespace support to vhost-vsock
From: Bobby Eshleman @ 2025-10-21 23:46 UTC (permalink / raw)
To: Stefano Garzarella, Shuah Khan, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Stefan Hajnoczi,
Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Bryan Tan,
Vishnu Dasa, Broadcom internal kernel review list, Bobby Eshleman
Cc: virtualization, netdev, linux-kselftest, linux-kernel, kvm,
linux-hyperv, berrange, Bobby Eshleman
This series adds namespace support to vhost-vsock and loopback. It does
not add namespaces to any of the other guest transports (virtio-vsock,
hyperv, or vmci).
The current revision supports two modes: local and global. Local
mode is complete isolation of namespaces, while global mode is complete
sharing between namespaces of CIDs (the original behavior).
The mode is set using /proc/sys/net/vsock/ns_mode.
Modes are per-netns and write-once. This allows a system to configure
namespaces independently (some may share CIDs, others are completely
isolated). This also supports future possible mixed use cases, where
there may be namespaces in global mode spinning up VMs while there are
mixed mode namespaces that provide services to the VMs, but are not
allowed to allocate from the global CID pool (this mode not implemented
in this series).
If a socket or VM is created when a namespace is global but the
namespace changes to local, the socket or VM will continue working
normally. That is, the socket or VM assumes the mode behavior of the
namespace at the time the socket/VM was created. The original mode is
captured in vsock_create() and so occurs at the time of socket(2) and
accept(2) for sockets and open(2) on /dev/vhost-vsock for VMs. This
prevents a socket/VM connection from suddenly breaking due to a
namespace mode change. Any new sockets/VMs created after the mode change
will adopt the new mode's behavior.
Additionally, added tests for the new namespace features:
tools/testing/selftests/vsock/vmtest.sh
1..30
ok 1 vm_server_host_client
ok 2 vm_client_host_server
ok 3 vm_loopback
ok 4 ns_host_vsock_ns_mode_ok
ok 5 ns_host_vsock_ns_mode_write_once_ok
ok 6 ns_global_same_cid_fails
ok 7 ns_local_same_cid_ok
ok 8 ns_global_local_same_cid_ok
ok 9 ns_local_global_same_cid_ok
ok 10 ns_diff_global_host_connect_to_global_vm_ok
ok 11 ns_diff_global_host_connect_to_local_vm_fails
ok 12 ns_diff_global_vm_connect_to_global_host_ok
ok 13 ns_diff_global_vm_connect_to_local_host_fails
ok 14 ns_diff_local_host_connect_to_local_vm_fails
ok 15 ns_diff_local_vm_connect_to_local_host_fails
ok 16 ns_diff_global_to_local_loopback_local_fails
ok 17 ns_diff_local_to_global_loopback_fails
ok 18 ns_diff_local_to_local_loopback_fails
ok 19 ns_diff_global_to_global_loopback_ok
ok 20 ns_same_local_loopback_ok
ok 21 ns_same_local_host_connect_to_local_vm_ok
ok 22 ns_same_local_vm_connect_to_local_host_ok
ok 23 ns_mode_change_connection_continue_vm_ok
ok 24 ns_mode_change_connection_continue_host_ok
ok 25 ns_mode_change_connection_continue_both_ok
ok 26 ns_delete_vm_ok
ok 27 ns_delete_host_ok
ok 28 ns_delete_both_ok
ok 29 ns_loopback_global_global_late_module_load_ok
ok 30 ns_loopback_local_local_late_module_load_fails
SUMMARY: PASS=30 SKIP=0 FAIL=0
Thanks again for everyone's help and reviews!
Signed-off-by: Bobby Eshleman <bobbyeshleman@gmail.com>
To: Stefano Garzarella <sgarzare@redhat.com>
To: Shuah Khan <shuah@kernel.org>
To: David S. Miller <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: Simon Horman <horms@kernel.org>
To: Stefan Hajnoczi <stefanha@redhat.com>
To: Michael S. Tsirkin <mst@redhat.com>
To: Jason Wang <jasowang@redhat.com>
To: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
To: Eugenio Pérez <eperezma@redhat.com>
To: K. Y. Srinivasan <kys@microsoft.com>
To: Haiyang Zhang <haiyangz@microsoft.com>
To: Wei Liu <wei.liu@kernel.org>
To: Dexuan Cui <decui@microsoft.com>
To: Bryan Tan <bryan-bt.tan@broadcom.com>
To: Vishnu Dasa <vishnu.dasa@broadcom.com>
To: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
Cc: virtualization@lists.linux.dev
Cc: netdev@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org
Cc: linux-hyperv@vger.kernel.org
Cc: berrange@redhat.com
Changes in v7:
- fix hv_sock build
- break out vmtest patches into distinct, more well-scoped patches
- change `orig_net_mode` to `net_mode`
- many fixes and style changes in per-patch change sets (see individual
patches for specific changes)
- optimize `virtio_vsock_skb_cb` layout
- update commit messages with more useful descriptions
- vsock_loopback: use orig_net_mode instead of current net mode
- add tests for edge cases (ns deletion, mode changing, loopback module
load ordering)
- Link to v6: https://lore.kernel.org/r/20250916-vsock-vmtest-v6-0-064d2eb0c89d@meta.com
Changes in v6:
- define behavior when mode changes to local while socket/VM is alive
- af_vsock: clarify description of CID behavior
- af_vsock: use stronger langauge around CID rules (dont use "may")
- af_vsock: improve naming of buf/buffer
- af_vsock: improve string length checking on proc writes
- vsock_loopback: add space in struct to clarify lock protection
- vsock_loopback: do proper cleanup/unregister on vsock_loopback_exit()
- vsock_loopback: use virtio_vsock_skb_net() instead of sock_net()
- vsock_loopback: set loopback to NULL after kfree()
- vsock_loopback: use pernet_operations and remove callback mechanism
- vsock_loopback: add macros for "global" and "local"
- vsock_loopback: fix length checking
- vmtest.sh: check for namespace support in vmtest.sh
- Link to v5: https://lore.kernel.org/r/20250827-vsock-vmtest-v5-0-0ba580bede5b@meta.com
Changes in v5:
- /proc/net/vsock_ns_mode -> /proc/sys/net/vsock/ns_mode
- vsock_global_net -> vsock_global_dummy_net
- fix netns lookup in vhost_vsock to respect pid namespaces
- add callbacks for vsock_loopback to avoid circular dependency
- vmtest.sh loads vsock_loopback module
- remove vsock_net_mode_can_set()
- change vsock_net_write_mode() to return true/false based on success
- make vsock_net_mode enum instead of u8
- Link to v4: https://lore.kernel.org/r/20250805-vsock-vmtest-v4-0-059ec51ab111@meta.com
Changes in v4:
- removed RFC tag
- implemented loopback support
- renamed new tests to better reflect behavior
- completed suite of tests with permutations of ns modes and vsock_test
as guest/host
- simplified socat bridging with unix socket instead of tcp + veth
- only use vsock_test for success case, socat for failure case (context
in commit message)
- lots of cleanup
Changes in v3:
- add notion of "modes"
- add procfs /proc/net/vsock_ns_mode
- local and global modes only
- no /dev/vhost-vsock-netns
- vmtest.sh already merged, so new patch just adds new tests for NS
- Link to v2:
https://lore.kernel.org/kvm/20250312-vsock-netns-v2-0-84bffa1aa97a@gmail.com
Changes in v2:
- only support vhost-vsock namespaces
- all g2h namespaces retain old behavior, only common API changes
impacted by vhost-vsock changes
- add /dev/vhost-vsock-netns for "opt-in"
- leave /dev/vhost-vsock to old behavior
- removed netns module param
- Link to v1:
https://lore.kernel.org/r/20200116172428.311437-1-sgarzare@redhat.com
Changes in v1:
- added 'netns' module param to vsock.ko to enable the
network namespace support (disabled by default)
- added 'vsock_net_eq()' to check the "net" assigned to a socket
only when 'netns' support is enabled
- Link to RFC: https://patchwork.ozlabs.org/cover/1202235/
---
Bobby Eshleman (26):
vsock: a per-net vsock NS mode state
vsock/virtio: pack struct virtio_vsock_skb_cb
vsock: add netns to vsock skb cb
vsock: add netns to vsock core
vsock/loopback: add netns support
vsock/virtio: add netns to virtio transport common
vhost/vsock: add netns support
selftests/vsock: improve logging in vmtest.sh
selftests/vsock: make wait_for_listener() work even if pipefail is on
selftests/vsock: reuse logic for vsock_test through wrapper functions
selftests/vsock: avoid multi-VM pidfile collisions with QEMU
selftests/vsock: do not unconditionally die if qemu fails
selftests/vsock: speed up tests by reducing the QEMU pidfile timeout
selftests/vsock: add check_result() for pass/fail counting
selftests/vsock: identify and execute tests that can re-use VM
selftests/vsock: add namespace initialization function
selftests/vsock: remove namespaces in cleanup()
selftests/vsock: prepare vm management helpers for namespaces
selftests/vsock: add BUILD=0 definition
selftests/vsock: avoid false-positives when checking dmesg
selftests/vsock: add tests for proc sys vsock ns_mode
selftests/vsock: add namespace tests for CID collisions
selftests/vsock: add tests for host <-> vm connectivity with namespaces
selftests/vsock: add tests for namespace deletion and mode changes
selftests/vsock: add tests for module loading order
selftests/vsock: add 1.37 to tested virtme-ng versions
MAINTAINERS | 1 +
drivers/vhost/vsock.c | 48 +-
include/linux/virtio_vsock.h | 47 +-
include/net/af_vsock.h | 78 +-
include/net/net_namespace.h | 4 +
include/net/netns/vsock.h | 22 +
net/vmw_vsock/af_vsock.c | 264 ++++++-
net/vmw_vsock/virtio_transport.c | 7 +-
net/vmw_vsock/virtio_transport_common.c | 21 +-
net/vmw_vsock/vsock_loopback.c | 89 ++-
tools/testing/selftests/vsock/vmtest.sh | 1320 ++++++++++++++++++++++++++++---
11 files changed, 1729 insertions(+), 172 deletions(-)
---
base-commit: 3ff9bcecce83f12169ab3e42671bd76554ca521a
change-id: 20250325-vsock-vmtest-b3a21d2102c2
Best regards,
--
Bobby Eshleman <bobbyeshleman@meta.com>
^ permalink raw reply
* Re: [PATCH v3 0/6] Hyper-V: Implement hypervisor core collection
From: Wei Liu @ 2025-10-20 20:48 UTC (permalink / raw)
To: Mukesh R
Cc: Michael Kelley, Wei Liu, linux-hyperv@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
kys@microsoft.com, haiyangz@microsoft.com, decui@microsoft.com,
tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
arnd@arndb.de
In-Reply-To: <4a4fa302-18fa-ba01-ec06-d4bf0cc84032@linux.microsoft.com>
On Mon, 20 Oct 2025 at 12:05, Mukesh R <mrathor@linux.microsoft.com> wrote:
>
> On 10/17/25 19:54, Michael Kelley wrote:
> > From: Mukesh R <mrathor@linux.microsoft.com> Sent: Friday, October 17, 2025 4:58 PM
> >>
> >> On 10/17/25 15:57, Wei Liu wrote:
> >>> On Fri, Oct 17, 2025 at 10:33:00PM +0000, Wei Liu wrote:
> >>>> On Mon, Oct 06, 2025 at 03:42:02PM -0700, Mukesh Rathor wrote:
> >>>> [...]
> >>>>> Mukesh Rathor (6):
> >>>>> x86/hyperv: Rename guest crash shutdown function
> >>>>> hyperv: Add two new hypercall numbers to guest ABI public header
> >>>>> hyperv: Add definitions for hypervisor crash dump support
> >>>>> x86/hyperv: Add trampoline asm code to transition from hypervisor
> >>>>> x86/hyperv: Implement hypervisor RAM collection into vmcore
> >>>>> x86/hyperv: Enable build of hypervisor crashdump collection files
> >>>>>
> >>>>
> >>>> Applied to hyperv-next. Thanks.
> >>>
> >>> This breaks i386 build.
> >>>
> >>> /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c: In function ?hyperv_init?:
> >>> /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c:557:17: error: implicit declaration of function ?hv_root_crash_init? [-Werror=implicit-function-declaration]
> >>> 557 | hv_root_crash_init();
> >>> | ^~~~~~~~~~~~~~~~~~
> >>>
> >>> That's because CONFIG_MSHV_ROOT is only available on x86_64. And the
> >>> crash feature is guarded by CONFIG_MSHV_ROOT.
> >>>
> >>> Applying the following diff fixes the build.
> >>
> >>
> >> Thanks. A bit surprising tho that CONFIG_MSHV_ROOT doesn't have
> >> hard dependency on x86_64. It should, no?
> >
> > CONFIG_MSHV_ROOT *does* have a hard dependency on X86_64.
> >
> > But the problem is actually more pervasive than just 32-bit builds. Because
> > of the hard dependency, 32-bit builds imply CONFIG_MSHV_ROOT=n, which is
> > the real problem. In arch/x86/include/asm/mshyperv.h the declaration for
> > hv_root_crash_init() is available only when CONFIG_MSHV_ROOT is defined
> > (m or y). There's a stub hv_root_crash_init() if CONFIG_MSHV_ROOT is defined
> > and CONFIG_CRASH_DUMP=n, but not if CONFIG_MSHV_ROOT=n. The solution
> > is to add a stub when CONFIG_MSHV_ROOT=n, as below:
> >
> > diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> > index 76582affefa8..a5b258d268ed 100644
> > --- a/arch/x86/include/asm/mshyperv.h
> > +++ b/arch/x86/include/asm/mshyperv.h
> > @@ -248,6 +248,8 @@ void hv_crash_asm_end(void);
> > static inline void hv_root_crash_init(void) {}
> > #endif /* CONFIG_CRASH_DUMP */
> >
> > +#else /* CONFIG_MSHV_ROOT */
> > +static inline void hv_root_crash_init(void) {}
> > #endif /* CONFIG_MSHV_ROOT */
> >
> > #else /* CONFIG_HYPERV */
> >
> > Annoyingly, this solution duplicates the hv_root_crash_init() stub. So
> > an alternate approach that changes a few more lines of code is this:
> >
> > diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> > index 76582affefa8..1342d55c2545 100644
> > --- a/arch/x86/include/asm/mshyperv.h
> > +++ b/arch/x86/include/asm/mshyperv.h
> > @@ -237,18 +237,14 @@ static __always_inline u64 hv_raw_get_msr(unsigned int reg)
> > }
> > int hv_apicid_to_vp_index(u32 apic_id);
> >
> > -#if IS_ENABLED(CONFIG_MSHV_ROOT)
> > -
> > -#ifdef CONFIG_CRASH_DUMP
> > +#if IS_ENABLED(CONFIG_MSHV_ROOT) && IS_ENABLED(CONFIG_CRASH_DUMP)
> > void hv_root_crash_init(void);
> > void hv_crash_asm32(void);
> > void hv_crash_asm64(void);
> > void hv_crash_asm_end(void);
> > -#else /* CONFIG_CRASH_DUMP */
> > +#else /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
> > static inline void hv_root_crash_init(void) {}
> > -#endif /* CONFIG_CRASH_DUMP */
> > -
> > -#endif /* CONFIG_MSHV_ROOT */
> > +#endif /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
> >
> > #else /* CONFIG_HYPERV */
> > static inline void hyperv_init(void) {}
> >
> > Michael
>
> Thanks. Yeah, either of the above two is ok. The latter does not
> duplicate, so may be tiny bit better. Wei will pick one and apply
> directly.
>
I fixed hyperv-next using the second option.
Wei
^ permalink raw reply
* Re: [PATCH v3 0/6] Hyper-V: Implement hypervisor core collection
From: Mukesh R @ 2025-10-20 19:05 UTC (permalink / raw)
To: Michael Kelley, Wei Liu
Cc: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arch@vger.kernel.org, kys@microsoft.com,
haiyangz@microsoft.com, decui@microsoft.com, tglx@linutronix.de,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
x86@kernel.org, hpa@zytor.com, arnd@arndb.de
In-Reply-To: <SN6PR02MB4157C70EBD25315F098DB3A1D4F7A@SN6PR02MB4157.namprd02.prod.outlook.com>
On 10/17/25 19:54, Michael Kelley wrote:
> From: Mukesh R <mrathor@linux.microsoft.com> Sent: Friday, October 17, 2025 4:58 PM
>>
>> On 10/17/25 15:57, Wei Liu wrote:
>>> On Fri, Oct 17, 2025 at 10:33:00PM +0000, Wei Liu wrote:
>>>> On Mon, Oct 06, 2025 at 03:42:02PM -0700, Mukesh Rathor wrote:
>>>> [...]
>>>>> Mukesh Rathor (6):
>>>>> x86/hyperv: Rename guest crash shutdown function
>>>>> hyperv: Add two new hypercall numbers to guest ABI public header
>>>>> hyperv: Add definitions for hypervisor crash dump support
>>>>> x86/hyperv: Add trampoline asm code to transition from hypervisor
>>>>> x86/hyperv: Implement hypervisor RAM collection into vmcore
>>>>> x86/hyperv: Enable build of hypervisor crashdump collection files
>>>>>
>>>>
>>>> Applied to hyperv-next. Thanks.
>>>
>>> This breaks i386 build.
>>>
>>> /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c: In function ?hyperv_init?:
>>> /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c:557:17: error: implicit declaration of function ?hv_root_crash_init? [-Werror=implicit-function-declaration]
>>> 557 | hv_root_crash_init();
>>> | ^~~~~~~~~~~~~~~~~~
>>>
>>> That's because CONFIG_MSHV_ROOT is only available on x86_64. And the
>>> crash feature is guarded by CONFIG_MSHV_ROOT.
>>>
>>> Applying the following diff fixes the build.
>>
>>
>> Thanks. A bit surprising tho that CONFIG_MSHV_ROOT doesn't have
>> hard dependency on x86_64. It should, no?
>
> CONFIG_MSHV_ROOT *does* have a hard dependency on X86_64.
>
> But the problem is actually more pervasive than just 32-bit builds. Because
> of the hard dependency, 32-bit builds imply CONFIG_MSHV_ROOT=n, which is
> the real problem. In arch/x86/include/asm/mshyperv.h the declaration for
> hv_root_crash_init() is available only when CONFIG_MSHV_ROOT is defined
> (m or y). There's a stub hv_root_crash_init() if CONFIG_MSHV_ROOT is defined
> and CONFIG_CRASH_DUMP=n, but not if CONFIG_MSHV_ROOT=n. The solution
> is to add a stub when CONFIG_MSHV_ROOT=n, as below:
>
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index 76582affefa8..a5b258d268ed 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -248,6 +248,8 @@ void hv_crash_asm_end(void);
> static inline void hv_root_crash_init(void) {}
> #endif /* CONFIG_CRASH_DUMP */
>
> +#else /* CONFIG_MSHV_ROOT */
> +static inline void hv_root_crash_init(void) {}
> #endif /* CONFIG_MSHV_ROOT */
>
> #else /* CONFIG_HYPERV */
>
> Annoyingly, this solution duplicates the hv_root_crash_init() stub. So
> an alternate approach that changes a few more lines of code is this:
>
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index 76582affefa8..1342d55c2545 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -237,18 +237,14 @@ static __always_inline u64 hv_raw_get_msr(unsigned int reg)
> }
> int hv_apicid_to_vp_index(u32 apic_id);
>
> -#if IS_ENABLED(CONFIG_MSHV_ROOT)
> -
> -#ifdef CONFIG_CRASH_DUMP
> +#if IS_ENABLED(CONFIG_MSHV_ROOT) && IS_ENABLED(CONFIG_CRASH_DUMP)
> void hv_root_crash_init(void);
> void hv_crash_asm32(void);
> void hv_crash_asm64(void);
> void hv_crash_asm_end(void);
> -#else /* CONFIG_CRASH_DUMP */
> +#else /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
> static inline void hv_root_crash_init(void) {}
> -#endif /* CONFIG_CRASH_DUMP */
> -
> -#endif /* CONFIG_MSHV_ROOT */
> +#endif /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
>
> #else /* CONFIG_HYPERV */
> static inline void hyperv_init(void) {}
>
> Michael
Thanks. Yeah, either of the above two is ok. The latter does not
duplicate, so may be tiny bit better. Wei will pick one and apply
directly.
Thanks,
-Mukesh
^ permalink raw reply
* Re: [PATCH v5 5/5] Drivers: hv: Add support for movable memory regions
From: Stanislav Kinsburskii @ 2025-10-20 17:35 UTC (permalink / raw)
To: Mukesh R; +Cc: kys, haiyangz, wei.liu, decui, linux-hyperv, linux-kernel
In-Reply-To: <2d5d540c-6ed5-455f-a895-9a3dd12bae2c@linux.microsoft.com>
On Fri, Oct 17, 2025 at 04:55:24PM -0700, Mukesh R wrote:
> On 10/15/25 17:27, Stanislav Kinsburskii wrote:
> > Introduce support for movable memory regions in the Hyper-V root partition
> > driver, thus improving memory management flexibility and preparing the
> > driver for advanced use cases such as dynamic memory remapping.
> >
> > Integrate mmu_interval_notifier for movable regions, implement functions to
> > handle HMM faults and memory invalidation, and update memory region mapping
> > logic to support movable regions.
> >
> > While MMU notifiers are commonly used in virtualization drivers, this
> > implementation leverages HMM (Heterogeneous Memory Management) for its
> > tailored functionality. HMM provides a ready-made framework for mirroring,
> > invalidation, and fault handling, avoiding the need to reimplement these
> > mechanisms for a single callback. Although MMU notifiers are more generic,
> > using HMM reduces boilerplate and ensures maintainability by utilizing a
> > mechanism specifically designed for such use cases.
> >
> > Signed-off-by: Anirudh Rayabharam <anrayabh@linux.microsoft.com>
> > Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> > ---
> > drivers/hv/Kconfig | 1
> > drivers/hv/mshv_root.h | 8 +
> > drivers/hv/mshv_root_main.c | 328 ++++++++++++++++++++++++++++++++++++++++++-
> > 3 files changed, 327 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> > index 0b8c391a0342..5f1637cbb6e3 100644
> > --- a/drivers/hv/Kconfig
> > +++ b/drivers/hv/Kconfig
> > @@ -75,6 +75,7 @@ config MSHV_ROOT
> > depends on PAGE_SIZE_4KB
> > select EVENTFD
> > select VIRT_XFER_TO_GUEST_WORK
> > + select HMM_MIRROR
> > default n
> > help
> > Select this option to enable support for booting and running as root
> > diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
> > index 97e64d5341b6..13367c84497c 100644
> > --- a/drivers/hv/mshv_root.h
> > +++ b/drivers/hv/mshv_root.h
> > @@ -15,6 +15,7 @@
> > #include <linux/hashtable.h>
> > #include <linux/dev_printk.h>
> > #include <linux/build_bug.h>
> > +#include <linux/mmu_notifier.h>
> > #include <uapi/linux/mshv.h>
> >
> > /*
> > @@ -81,9 +82,14 @@ struct mshv_mem_region {
> > struct {
> > u64 large_pages: 1; /* 2MiB */
> > u64 range_pinned: 1;
> > - u64 reserved: 62;
> > + u64 is_ram : 1; /* mem region can be ram or mmio */
>
> In case this gets accepted/merged, this is named
> + u64 memreg_isram: 1; /* mem region can be ram or mmio */
>
The proposed naming scheme doesn't align with the other fields in this structure.
Renaming this one should be probably done along with the other fields in
a separate change.
Thanks,
Stanislav
> Keeping the name same will avoid unnecessary diffs when we try to compare
> files to see what is missing internally or externally.
>
> Thanks,
> -Mukesh
>
> > } flags;
> > struct mshv_partition *partition;
> > +#if defined(CONFIG_MMU_NOTIFIER)
> > + struct mmu_interval_notifier mni;
> > + struct mutex mutex; /* protects region pages remapping */
> > +#endif
> > struct page *pages[];
> > };
> >
> > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
> > index c4f114376435..b2738443ac5d 100644
> > --- a/drivers/hv/mshv_root_main.c
> > +++ b/drivers/hv/mshv_root_main.c
> > @@ -29,6 +29,7 @@
> > #include <linux/crash_dump.h>
> > #include <linux/panic_notifier.h>
> > #include <linux/vmalloc.h>
> > +#include <linux/hmm.h>
> >
> > #include "mshv_eventfd.h"
> > #include "mshv.h"
> > @@ -36,6 +37,8 @@
> >
> > #define VALUE_PMD_ALIGNED(c) (!((c) & (PTRS_PER_PMD - 1)))
> >
> > +#define MSHV_MAP_FAULT_IN_PAGES HPAGE_PMD_NR
> > +
> > MODULE_AUTHOR("Microsoft");
> > MODULE_LICENSE("GPL");
> > MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv");
> > @@ -76,6 +79,11 @@ static int mshv_vp_mmap(struct file *file, struct vm_area_struct *vma);
> > static vm_fault_t mshv_vp_fault(struct vm_fault *vmf);
> > static int mshv_init_async_handler(struct mshv_partition *partition);
> > static void mshv_async_hvcall_handler(void *data, u64 *status);
> > +static struct mshv_mem_region
> > + *mshv_partition_region_by_gfn(struct mshv_partition *pt, u64 gfn);
> > +static int mshv_region_remap_pages(struct mshv_mem_region *region,
> > + u32 map_flags, u64 page_offset,
> > + u64 page_count);
> >
> > static const union hv_input_vtl input_vtl_zero;
> > static const union hv_input_vtl input_vtl_normal = {
> > @@ -602,14 +610,197 @@ static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp)
> > static_assert(sizeof(struct hv_message) <= MSHV_RUN_VP_BUF_SZ,
> > "sizeof(struct hv_message) must not exceed MSHV_RUN_VP_BUF_SZ");
> >
> > +#ifdef CONFIG_X86_64
> > +
> > +#if defined(CONFIG_MMU_NOTIFIER)
> > +/**
> > + * mshv_region_hmm_fault_and_lock - Handle HMM faults and lock the memory region
> > + * @region: Pointer to the memory region structure
> > + * @range: Pointer to the HMM range structure
> > + *
> > + * This function performs the following steps:
> > + * 1. Reads the notifier sequence for the HMM range.
> > + * 2. Acquires a read lock on the memory map.
> > + * 3. Handles HMM faults for the specified range.
> > + * 4. Releases the read lock on the memory map.
> > + * 5. If successful, locks the memory region mutex.
> > + * 6. Verifies if the notifier sequence has changed during the operation.
> > + * If it has, releases the mutex and returns -EBUSY to match with
> > + * hmm_range_fault() return code for repeating.
> > + *
> > + * Return: 0 on success, a negative error code otherwise.
> > + */
> > +static int mshv_region_hmm_fault_and_lock(struct mshv_mem_region *region,
> > + struct hmm_range *range)
> > +{
> > + int ret;
> > +
> > + range->notifier_seq = mmu_interval_read_begin(range->notifier);
> > + mmap_read_lock(region->mni.mm);
> > + ret = hmm_range_fault(range);
> > + mmap_read_unlock(region->mni.mm);
> > + if (ret)
> > + return ret;
> > +
> > + mutex_lock(®ion->mutex);
> > +
> > + if (mmu_interval_read_retry(range->notifier, range->notifier_seq)) {
> > + mutex_unlock(®ion->mutex);
> > + cond_resched();
> > + return -EBUSY;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * mshv_region_range_fault - Handle memory range faults for a given region.
> > + * @region: Pointer to the memory region structure.
> > + * @page_offset: Offset of the page within the region.
> > + * @page_count: Number of pages to handle.
> > + *
> > + * This function resolves memory faults for a specified range of pages
> > + * within a memory region. It uses HMM (Heterogeneous Memory Management)
> > + * to fault in the required pages and updates the region's page array.
> > + *
> > + * Return: 0 on success, negative error code on failure.
> > + */
> > +static int mshv_region_range_fault(struct mshv_mem_region *region,
> > + u64 page_offset, u64 page_count)
> > +{
> > + struct hmm_range range = {
> > + .notifier = ®ion->mni,
> > + .default_flags = HMM_PFN_REQ_FAULT | HMM_PFN_REQ_WRITE,
> > + };
> > + unsigned long *pfns;
> > + int ret;
> > + u64 i;
> > +
> > + pfns = kmalloc_array(page_count, sizeof(unsigned long), GFP_KERNEL);
> > + if (!pfns)
> > + return -ENOMEM;
> > +
> > + range.hmm_pfns = pfns;
> > + range.start = region->start_uaddr + page_offset * HV_HYP_PAGE_SIZE;
> > + range.end = range.start + page_count * HV_HYP_PAGE_SIZE;
> > +
> > + do {
> > + ret = mshv_region_hmm_fault_and_lock(region, &range);
> > + } while (ret == -EBUSY);
> > +
> > + if (ret)
> > + goto out;
> > +
> > + for (i = 0; i < page_count; i++)
> > + region->pages[page_offset + i] = hmm_pfn_to_page(pfns[i]);
> > +
> > + if (PageHuge(region->pages[page_offset]))
> > + region->flags.large_pages = true;
> > +
> > + ret = mshv_region_remap_pages(region, region->hv_map_flags,
> > + page_offset, page_count);
> > +
> > + mutex_unlock(®ion->mutex);
> > +out:
> > + kfree(pfns);
> > + return ret;
> > +}
> > +#else /* CONFIG_MMU_NOTIFIER */
> > +static int mshv_region_range_fault(struct mshv_mem_region *region,
> > + u64 page_offset, u64 page_count)
> > +{
> > + return -ENODEV;
> > +}
> > +#endif /* CONFIG_MMU_NOTIFIER */
> > +
> > +static bool mshv_region_handle_gfn_fault(struct mshv_mem_region *region, u64 gfn)
> > +{
> > + u64 page_offset, page_count;
> > + int ret;
> > +
> > + if (WARN_ON_ONCE(region->flags.range_pinned))
> > + return false;
> > +
> > + /* Align the page offset to the nearest MSHV_MAP_FAULT_IN_PAGES. */
> > + page_offset = ALIGN_DOWN(gfn - region->start_gfn,
> > + MSHV_MAP_FAULT_IN_PAGES);
> > +
> > + /* Map more pages than requested to reduce the number of faults. */
> > + page_count = min(region->nr_pages - page_offset,
> > + MSHV_MAP_FAULT_IN_PAGES);
> > +
> > + ret = mshv_region_range_fault(region, page_offset, page_count);
> > +
> > + WARN_ONCE(ret,
> > + "p%llu: GPA intercept failed: region %#llx-%#llx, gfn %#llx, page_offset %llu, page_count %llu\n",
> > + region->partition->pt_id, region->start_uaddr,
> > + region->start_uaddr + (region->nr_pages << HV_HYP_PAGE_SHIFT),
> > + gfn, page_offset, page_count);
> > +
> > + return !ret;
> > +}
> > +
> > +/**
> > + * mshv_handle_gpa_intercept - Handle GPA (Guest Physical Address) intercepts.
> > + * @vp: Pointer to the virtual processor structure.
> > + *
> > + * This function processes GPA intercepts by identifying the memory region
> > + * corresponding to the intercepted GPA, aligning the page offset, and
> > + * mapping the required pages. It ensures that the region is valid and
> > + * handles faults efficiently by mapping multiple pages at once.
> > + *
> > + * Return: true if the intercept was handled successfully, false otherwise.
> > + */
> > +static bool mshv_handle_gpa_intercept(struct mshv_vp *vp)
> > +{
> > + struct mshv_partition *p = vp->vp_partition;
> > + struct mshv_mem_region *region;
> > + struct hv_x64_memory_intercept_message *msg;
> > + u64 gfn;
> > +
> > + msg = (struct hv_x64_memory_intercept_message *)
> > + vp->vp_intercept_msg_page->u.payload;
> > +
> > + gfn = HVPFN_DOWN(msg->guest_physical_address);
> > +
> > + region = mshv_partition_region_by_gfn(p, gfn);
> > + if (!region)
> > + return false;
> > +
> > + if (WARN_ON_ONCE(!region->flags.is_ram))
> > + return false;
> > +
> > + if (WARN_ON_ONCE(region->flags.range_pinned))
> > + return false;
> > +
> > + return mshv_region_handle_gfn_fault(region, gfn);
> > +}
> > +
> > +#else /* CONFIG_X86_64 */
> > +
> > +static bool mshv_handle_gpa_intercept(struct mshv_vp *vp) { return false; }
> > +
> > +#endif /* CONFIG_X86_64 */
> > +
> > +static bool mshv_vp_handle_intercept(struct mshv_vp *vp)
> > +{
> > + switch (vp->vp_intercept_msg_page->header.message_type) {
> > + case HVMSG_GPA_INTERCEPT:
> > + return mshv_handle_gpa_intercept(vp);
> > + }
> > + return false;
> > +}
> > +
> > static long mshv_vp_ioctl_run_vp(struct mshv_vp *vp, void __user *ret_msg)
> > {
> > long rc;
> >
> > - if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
> > - rc = mshv_run_vp_with_root_scheduler(vp);
> > - else
> > - rc = mshv_run_vp_with_hyp_scheduler(vp);
> > + do {
> > + if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
> > + rc = mshv_run_vp_with_root_scheduler(vp);
> > + else
> > + rc = mshv_run_vp_with_hyp_scheduler(vp);
> > + } while (rc == 0 && mshv_vp_handle_intercept(vp));
> >
> > if (rc)
> > return rc;
> > @@ -1209,6 +1400,110 @@ mshv_partition_region_by_uaddr(struct mshv_partition *partition, u64 uaddr)
> > return NULL;
> > }
> >
> > +#if defined(CONFIG_MMU_NOTIFIER)
> > +static void mshv_region_movable_fini(struct mshv_mem_region *region)
> > +{
> > + if (region->flags.range_pinned)
> > + return;
> > +
> > + mmu_interval_notifier_remove(®ion->mni);
> > +}
> > +
> > +/**
> > + * mshv_region_interval_invalidate - Invalidate a range of memory region
> > + * @mni: Pointer to the mmu_interval_notifier structure
> > + * @range: Pointer to the mmu_notifier_range structure
> > + * @cur_seq: Current sequence number for the interval notifier
> > + *
> > + * This function invalidates a memory region by remapping its pages with
> > + * no access permissions. It locks the region's mutex to ensure thread safety
> > + * and updates the sequence number for the interval notifier. If the range
> > + * is blockable, it uses a blocking lock; otherwise, it attempts a non-blocking
> > + * lock and returns false if unsuccessful.
> > + *
> > + * NOTE: Failure to invalidate a region is a serious error, as the pages will
> > + * be considered freed while they are still mapped by the hypervisor.
> > + * Any attempt to access such pages will likely crash the system.
> > + *
> > + * Return: true if the region was successfully invalidated, false otherwise.
> > + */
> > +static bool
> > +mshv_region_interval_invalidate(struct mmu_interval_notifier *mni,
> > + const struct mmu_notifier_range *range,
> > + unsigned long cur_seq)
> > +{
> > + struct mshv_mem_region *region = container_of(mni,
> > + struct mshv_mem_region,
> > + mni);
> > + u64 page_offset, page_count;
> > + unsigned long mstart, mend;
> > + int ret = -EPERM;
> > +
> > + if (mmu_notifier_range_blockable(range))
> > + mutex_lock(®ion->mutex);
> > + else if (!mutex_trylock(®ion->mutex))
> > + goto out_fail;
> > +
> > + mmu_interval_set_seq(mni, cur_seq);
> > +
> > + mstart = max(range->start, region->start_uaddr);
> > + mend = min(range->end, region->start_uaddr +
> > + (region->nr_pages << HV_HYP_PAGE_SHIFT));
> > +
> > + page_offset = HVPFN_DOWN(mstart - region->start_uaddr);
> > + page_count = HVPFN_DOWN(mend - mstart);
> > +
> > + ret = mshv_region_remap_pages(region, HV_MAP_GPA_NO_ACCESS,
> > + page_offset, page_count);
> > + if (ret)
> > + goto out_fail;
> > +
> > + mshv_region_invalidate_pages(region, page_offset, page_count);
> > +
> > + mutex_unlock(®ion->mutex);
> > +
> > + return true;
> > +
> > +out_fail:
> > + WARN_ONCE(ret,
> > + "Failed to invalidate region %#llx-%#llx (range %#lx-%#lx, event: %u, pages %#llx-%#llx, mm: %#llx): %d\n",
> > + region->start_uaddr,
> > + region->start_uaddr + (region->nr_pages << HV_HYP_PAGE_SHIFT),
> > + range->start, range->end, range->event,
> > + page_offset, page_offset + page_count - 1, (u64)range->mm, ret);
> > + return false;
> > +}
> > +
> > +static const struct mmu_interval_notifier_ops mshv_region_mni_ops = {
> > + .invalidate = mshv_region_interval_invalidate,
> > +};
> > +
> > +static bool mshv_region_movable_init(struct mshv_mem_region *region)
> > +{
> > + int ret;
> > +
> > + ret = mmu_interval_notifier_insert(®ion->mni, current->mm,
> > + region->start_uaddr,
> > + region->nr_pages << HV_HYP_PAGE_SHIFT,
> > + &mshv_region_mni_ops);
> > + if (ret)
> > + return false;
> > +
> > + mutex_init(®ion->mutex);
> > +
> > + return true;
> > +}
> > +#else
> > +static inline void mshv_region_movable_fini(struct mshv_mem_region *region)
> > +{
> > +}
> > +
> > +static inline bool mshv_region_movable_init(struct mshv_mem_region *region)
> > +{
> > + return false;
> > +}
> > +#endif
> > +
> > /*
> > * NB: caller checks and makes sure mem->size is page aligned
> > * Returns: 0 with regionpp updated on success, or -errno
> > @@ -1241,9 +1536,14 @@ static int mshv_partition_create_region(struct mshv_partition *partition,
> > if (mem->flags & BIT(MSHV_SET_MEM_BIT_EXECUTABLE))
> > region->hv_map_flags |= HV_MAP_GPA_EXECUTABLE;
> >
> > - /* Note: large_pages flag populated when we pin the pages */
> > - if (!is_mmio)
> > - region->flags.range_pinned = true;
> > + /* Note: large_pages flag populated when pages are allocated. */
> > + if (!is_mmio) {
> > + region->flags.is_ram = true;
> > +
> > + if (mshv_partition_encrypted(partition) ||
> > + !mshv_region_movable_init(region))
> > + region->flags.range_pinned = true;
> > + }
> >
> > region->partition = partition;
> >
> > @@ -1363,9 +1663,16 @@ mshv_map_user_memory(struct mshv_partition *partition,
> > if (is_mmio)
> > ret = hv_call_map_mmio_pages(partition->pt_id, mem.guest_pfn,
> > mmio_pfn, HVPFN_DOWN(mem.size));
> > - else
> > + else if (region->flags.range_pinned)
> > ret = mshv_prepare_pinned_region(region);
> > -
> > + else
> > + /*
> > + * For non-pinned regions, remap with no access to let the
> > + * hypervisor track dirty pages, enabling pre-copy live
> > + * migration.
> > + */
> > + ret = mshv_region_remap_pages(region, HV_MAP_GPA_NO_ACCESS,
> > + 0, region->nr_pages);
> > if (ret)
> > goto errout;
> >
> > @@ -1388,6 +1695,9 @@ static void mshv_partition_destroy_region(struct mshv_mem_region *region)
> >
> > hlist_del(®ion->hnode);
> >
> > + if (region->flags.is_ram)
> > + mshv_region_movable_fini(region);
> > +
> > if (mshv_partition_encrypted(partition)) {
> > ret = mshv_partition_region_share(region);
> > if (ret) {
> >
> >
^ permalink raw reply
* RE: [PATCH v2 2/2] hyperv: Enable clean shutdown for root partition with MSHV
From: Michael Kelley @ 2025-10-20 17:30 UTC (permalink / raw)
To: Praveen Paladugu
Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
decui@microsoft.com, tglx@linutronix.de, mingo@redhat.com,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org,
hpa@zytor.com, arnd@arndb.de, anbelski@linux.microsoft.com,
easwar.hariharan@linux.microsoft.com,
nunodasneves@linux.microsoft.com,
skinsburskii@linux.microsoft.com
In-Reply-To: <20251020155939.GA17482@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
From: Praveen Paladugu <prapal@linux.microsoft.com> Sent: Monday, October 20, 2025 9:00 AM
>
> On Thu, Oct 16, 2025 at 07:29:06PM +0000, Michael Kelley wrote:
> > From: Praveen K Paladugu <prapal@linux.microsoft.com> Sent: Tuesday, October 14, 2025 9:41 AM
> > >
[snip]
> > > +static int hv_call_enter_sleep_state(u32 sleep_state)
> > > +{
> > > + u64 status;
> > > + int ret;
> > > + unsigned long flags;
> > > + struct hv_input_enter_sleep_state *in;
> > > +
> > > + ret = hv_initialize_sleep_states();
> > > + if (ret)
> > > + return ret;
> > > +
> > > + local_irq_save(flags);
> > > + in = *this_cpu_ptr(hyperv_pcpu_input_arg);
> > > + in->sleep_state = sleep_state;
> > > +
> > > + status = hv_do_hypercall(HVCALL_ENTER_SLEEP_STATE, in, NULL);
> >
> > If this hypercall succeeds, does the root partition (which is the caller) go
> > to sleep in S5, such that the hypercall never returns? If that's not the case,
> > what is the behavior of this hypercall?
> >
> This hypercall returns to the kernel when the CPU wakes up the next
> time.
I must be missing something about the big picture, because "returns to
the kernel when the CPU wakes up" doesn't fit my mental model of what's
going on. I thought this function would be called, and the hypercall made,
when Linux in the root partition is shutting down. So if a CPU makes this
hypercall and goes to sleep, what wakes it up? And when it wakes up, is it
still running the same Linux instance that was shutting down, or has it
rebooted into new Linux instance? In the latter case, returning from
the hypercall doesn't make sense.
Can you explain further how this all works?
Michael
>
> > > + local_irq_restore(flags);
> > > +
> > > + if (!hv_result_success(status)) {
> > > + hv_status_err(status, "\n");
> > > + return hv_result_to_errno(status);
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int hv_reboot_notifier_handler(struct notifier_block *this,
> > > + unsigned long code, void *another)
> > > +{
> > > + int ret = 0;
> > > +
> > > + if (code == SYS_HALT || code == SYS_POWER_OFF)
> > > + ret = hv_call_enter_sleep_state(HV_SLEEP_STATE_S5);
> >
> > If hv_call_enter_sleep_state() never returns, here's an issue. There may be
> > multiple entries on the reboot notifier chain. For example,
> > mshv_root_partition_init() puts an entry on the reboot notifier chain. At
> > reboot time, the entries are executed in some order, with the expectation
> > that all entries will be executed prior to the reboot actually happening. But
> > if this hypercall never returns, some entries may never be executed.
> >
> > Notifier chains support a notion of priority to control the order in
> > which they are executed, but that priority isn't set in hv_reboot_notifier
> > below, or in mshv_reboot_nb. And most other reboot notifiers throughout
> > Linux appear to not set it. So the ordering is unspecified, and having
> > this notifier never return may be problematic.
> >
> Thanks for the detailed explanation Michael!
>
> As I mentioned above, this hypercall returns to the kernel, so the rest
> of the entries in the notifier chain should continue to execute.
>
> > > +
> > > + return ret ? NOTIFY_DONE : NOTIFY_OK;
> > > +}
> > > +
> > > +static struct notifier_block hv_reboot_notifier = {
> > > + .notifier_call = hv_reboot_notifier_handler,
> > > +};
> > > +
> > > +static int hv_acpi_sleep_handler(u8 sleep_state, u32 pm1a_cnt, u32 pm1b_cnt)
> > > +{
> > > + int ret = 0;
> > > +
> > > + if (sleep_state == ACPI_STATE_S5)
> > > + ret = hv_call_enter_sleep_state(HV_SLEEP_STATE_S5);
> > > +
> > > + return ret == 0 ? 1 : -1;
> > > +}
> > > +
> > > +static int hv_acpi_extended_sleep_handler(u8 sleep_state, u32 val_a, u32 val_b)
> > > +{
> > > + return hv_acpi_sleep_handler(sleep_state, val_a, val_b);
> > > +}
> >
> > Is this function needed? The function signature is identical to hv_acpi_sleep_handler().
> > So it seems like acpi_os_set_prepare_extended_sleep() could just use
> > hv_acpi_sleep_handler() directly.
> >
> Upon further investigation, I discovered that extended sleep is only
> supported on platforms with ACPI_REDUCED_HARDWARE.
>
> As these patches are targetted at X86, above does not really apply. I
> will drop this handler in next version.
>
> > > +
> > > +int hv_sleep_notifiers_register(void)
> > > +{
> > > + int ret;
> > > +
> > > + acpi_os_set_prepare_sleep(&hv_acpi_sleep_handler);
> > > + acpi_os_set_prepare_extended_sleep(&hv_acpi_extended_sleep_handler);
> >
> > I'm not clear on why these handlers are set. If the hv_reboot_notifier is
> > called, are these ACPI handlers ever called? Or are these to catch any cases
> > where the hv_reboot_notifier is somehow bypassed? Or maybe I'm just
> > not understanding something .... :-)
> >
>
> I am trying to trace these calls. I will keep you posted with my
> findings.
>
> > > +
> > > + ret = register_reboot_notifier(&hv_reboot_notifier);
> > > + if (ret)
> > > + pr_err("%s: cannot register reboot notifier %d\n",
> > > + __func__, ret);
> > > +
> > > + return ret;
> > > +}
> > > +#endif
> >
> > I'm wondering if all this code belongs in hv_common.c, since it is only needed
> > for Linux in the root partition. Couldn't it go in mshv_common.c? It would still
> > be built-in code (i.e., not in a loadable module), but only if CONFIG_MSHV_ROOT
> > is set.
> >
>
> This sounds reasonable. I will discuss this internally and get back you.
>
> > Michael
> >
> > > --
> > > 2.51.0
> > >
^ permalink raw reply
* Re: [PATCH v2] mshv: Fix deposit memory in MSHV_ROOT_HVCALL
From: Nuno Das Neves @ 2025-10-20 16:02 UTC (permalink / raw)
To: Wei Liu
Cc: linux-hyperv, linux-kernel, mhklinux, kys, haiyangz, decui, arnd,
mrathor, skinsburskii
In-Reply-To: <20251017222633.GA632885@liuwe-devbox-debian-v2.local>
On 10/17/2025 3:26 PM, Wei Liu wrote:
> On Fri, Oct 17, 2025 at 10:06:55PM +0000, Wei Liu wrote:
>> On Fri, Oct 17, 2025 at 11:58:17AM -0700, Nuno Das Neves wrote:
>>> When the MSHV_ROOT_HVCALL ioctl is executing a hypercall, and gets
>>> HV_STATUS_INSUFFICIENT_MEMORY, it deposits memory and then returns
>>> -EAGAIN to userspace. The expectation is that the VMM will retry.
>>>
>>> However, some VMM code in the wild doesn't do this and simply fails.
>>> Rather than force the VMM to retry, change the ioctl to deposit
>>> memory on demand and immediately retry the hypercall as is done with
>>> all the other hypercall helper functions.
>>>
>>> In addition to making the ioctl easier to use, removing the need for
>>> multiple syscalls improves performance.
>>>
>>> There is a complication: unlike the other hypercall helper functions,
>>> in MSHV_ROOT_HVCALL the input is opaque to the kernel. This is
>>> problematic for rep hypercalls, because the next part of the input
>>> list can't be copied on each loop after depositing pages (this was
>>> the original reason for returning -EAGAIN in this case).
>>>
>>> Introduce hv_do_rep_hypercall_ex(), which adds a 'rep_start'
>>> parameter. This solves the issue, allowing the deposit loop in
>>> MSHV_ROOT_HVCALL to restart a rep hypercall after depositing pages
>>> partway through.
>>>
>>> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
>>
>> In v1 you said you will add a "Fixes" tag. Where is it?
>
> I added this:
>
> Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
>
> Let me know if that's not correct.
>
Oops! That's correct, thanks.
> Wei
^ permalink raw reply
* Re: [PATCH v2 2/2] hyperv: Enable clean shutdown for root partition with MSHV
From: Praveen Paladugu @ 2025-10-20 15:59 UTC (permalink / raw)
To: Michael Kelley
Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
decui@microsoft.com, tglx@linutronix.de, mingo@redhat.com,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org,
hpa@zytor.com, arnd@arndb.de, anbelski@linux.microsoft.com,
easwar.hariharan@linux.microsoft.com,
nunodasneves@linux.microsoft.com,
skinsburskii@linux.microsoft.com
In-Reply-To: <SN6PR02MB4157FBBE5B77C65B024D3589D4E9A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Thu, Oct 16, 2025 at 07:29:06PM +0000, Michael Kelley wrote:
> From: Praveen K Paladugu <prapal@linux.microsoft.com> Sent: Tuesday, October 14, 2025 9:41 AM
> >
> > When a shutdown is initiated in the root partition without configuring
> > sleep states, the call to `hv_call_enter_sleep_state` fails. In such cases
> > the root falls back to using legacy ACPI mechanisms to poweroff. This call
> > is intercepted by MSHV and will result in a Machine Check Exception (MCE).
> >
> > Root panics with a trace similar to:
> >
> > [ 81.306348] reboot: Power down
> > [ 81.314709] mce: [Hardware Error]: CPU 0: Machine Check Exception: 4 Bank 0: b2000000c0060001
> > [ 81.314711] mce: [Hardware Error]: TSC 3b8cb60a66 PPIN 11d98332458e4ea9
> > [ 81.314713] mce: [Hardware Error]: PROCESSOR 0:606a6 TIME 1759339405 SOCKET 0 APIC 0 microcode ffffffff
> > [ 81.314715] mce: [Hardware Error]: Run the above through 'mcelog --ascii'
> > [ 81.314716] mce: [Hardware Error]: Machine check: Processor context corrupt
> > [ 81.314717] Kernel panic - not syncing: Fatal machine check
> >
> > To prevent this, properly configure sleep states within MSHV, allowing
> > the root partition to shut down cleanly without triggering a panic.
> >
> > Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
> > Co-developed-by: Anatol Belski <anbelski@linux.microsoft.com>
> > Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
> > ---
> > arch/x86/hyperv/hv_init.c | 7 ++
> > arch/x86/include/asm/mshyperv.h | 1 +
> > drivers/hv/hv_common.c | 119 ++++++++++++++++++++++++++++++++
> > 3 files changed, 127 insertions(+)
> >
> > diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> > index afdbda2dd7b7..57bd96671ead 100644
> > --- a/arch/x86/hyperv/hv_init.c
> > +++ b/arch/x86/hyperv/hv_init.c
> > @@ -510,6 +510,13 @@ void __init hyperv_init(void)
> > memunmap(src);
> >
> > hv_remap_tsc_clocksource();
> > + /*
> > + * The notifier registration might fail at various hops.
> > + * Corresponding error messages will land in dmesg. There is
> > + * otherwise nothing that can be specifically done to handle
> > + * failures here.
> > + */
> > + (void)hv_sleep_notifiers_register();
> > } else {
> > hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
> > wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
> > diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> > index abc4659f5809..fb8d691193df 100644
> > --- a/arch/x86/include/asm/mshyperv.h
> > +++ b/arch/x86/include/asm/mshyperv.h
> > @@ -236,6 +236,7 @@ int hyperv_fill_flush_guest_mapping_list(
> > void hv_apic_init(void);
> > void __init hv_init_spinlocks(void);
> > bool hv_vcpu_is_preempted(int vcpu);
> > +int hv_sleep_notifiers_register(void);
> > #else
> > static inline void hv_apic_init(void) {}
> > #endif
> > diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> > index e109a620c83f..cfba9ded7bcb 100644
> > --- a/drivers/hv/hv_common.c
> > +++ b/drivers/hv/hv_common.c
> > @@ -837,3 +837,122 @@ const char *hv_result_to_string(u64 status)
> > return "Unknown";
> > }
> > EXPORT_SYMBOL_GPL(hv_result_to_string);
> > +
> > +#if IS_ENABLED(CONFIG_ACPI)
> > +/*
> > + * Corresponding sleep states have to be initialized in order for a subsequent
> > + * HVCALL_ENTER_SLEEP_STATE call to succeed. Currently only S5 state as per
> > + * ACPI 6.4 chapter 7.4.2 is relevant, while S1, S2 and S3 can be supported.
> > + *
> > + * ACPI should be initialized and should support S5 sleep state when this method
> > + * is called, so that it can extract correct PM values and pass them to hv.
> > + */
> > +static int hv_initialize_sleep_states(void)
> > +{
> > + u64 status;
> > + unsigned long flags;
> > + struct hv_input_set_system_property *in;
> > + acpi_status acpi_status;
> > + u8 sleep_type_a, sleep_type_b;
> > +
> > + if (!acpi_sleep_state_supported(ACPI_STATE_S5)) {
> > + pr_err("%s: S5 sleep state not supported.\n", __func__);
> > + return -ENODEV;
> > + }
> > +
> > + acpi_status = acpi_get_sleep_type_data(ACPI_STATE_S5,
> > + &sleep_type_a, &sleep_type_b);
> > + if (ACPI_FAILURE(acpi_status))
> > + return -ENODEV;
> > +
> > + local_irq_save(flags);
> > + in = *this_cpu_ptr(hyperv_pcpu_input_arg);
> > + memset(in, 0, sizeof(*in));
> > +
> > + in->property_id = HV_SYSTEM_PROPERTY_SLEEP_STATE;
> > + in->set_sleep_state_info.sleep_state = HV_SLEEP_STATE_S5;
> > + in->set_sleep_state_info.pm1a_slp_typ = sleep_type_a;
> > + in->set_sleep_state_info.pm1b_slp_typ = sleep_type_b;
> > +
> > + status = hv_do_hypercall(HVCALL_SET_SYSTEM_PROPERTY, in, NULL);
> > + local_irq_restore(flags);
> > +
> > + if (!hv_result_success(status)) {
> > + hv_status_err(status, "\n");
> > + return hv_result_to_errno(status);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int hv_call_enter_sleep_state(u32 sleep_state)
> > +{
> > + u64 status;
> > + int ret;
> > + unsigned long flags;
> > + struct hv_input_enter_sleep_state *in;
> > +
> > + ret = hv_initialize_sleep_states();
> > + if (ret)
> > + return ret;
> > +
> > + local_irq_save(flags);
> > + in = *this_cpu_ptr(hyperv_pcpu_input_arg);
> > + in->sleep_state = sleep_state;
> > +
> > + status = hv_do_hypercall(HVCALL_ENTER_SLEEP_STATE, in, NULL);
>
> If this hypercall succeeds, does the root partition (which is the caller) go
> to sleep in S5, such that the hypercall never returns? If that's not the case,
> what is the behavior of this hypercall?
>
This hypercall returns to the kernel when the CPU wakes up the next
time.
> > + local_irq_restore(flags);
> > +
> > + if (!hv_result_success(status)) {
> > + hv_status_err(status, "\n");
> > + return hv_result_to_errno(status);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int hv_reboot_notifier_handler(struct notifier_block *this,
> > + unsigned long code, void *another)
> > +{
> > + int ret = 0;
> > +
> > + if (code == SYS_HALT || code == SYS_POWER_OFF)
> > + ret = hv_call_enter_sleep_state(HV_SLEEP_STATE_S5);
>
> If hv_call_enter_sleep_state() never returns, here's an issue. There may be
> multiple entries on the reboot notifier chain. For example,
> mshv_root_partition_init() puts an entry on the reboot notifier chain. At
> reboot time, the entries are executed in some order, with the expectation
> that all entries will be executed prior to the reboot actually happening. But
> if this hypercall never returns, some entries may never be executed.
>
> Notifier chains support a notion of priority to control the order in
> which they are executed, but that priority isn't set in hv_reboot_notifier
> below, or in mshv_reboot_nb. And most other reboot notifiers throughout
> Linux appear to not set it. So the ordering is unspecified, and having
> this notifier never return may be problematic.
>
Thanks for the detailed explanation Michael!
As I mentioned above, this hypercall returns to the kernel, so the rest
of the entries in the notifier chain should continue to execute.
> > +
> > + return ret ? NOTIFY_DONE : NOTIFY_OK;
> > +}
> > +
> > +static struct notifier_block hv_reboot_notifier = {
> > + .notifier_call = hv_reboot_notifier_handler,
> > +};
> > +
> > +static int hv_acpi_sleep_handler(u8 sleep_state, u32 pm1a_cnt, u32 pm1b_cnt)
> > +{
> > + int ret = 0;
> > +
> > + if (sleep_state == ACPI_STATE_S5)
> > + ret = hv_call_enter_sleep_state(HV_SLEEP_STATE_S5);
> > +
> > + return ret == 0 ? 1 : -1;
> > +}
> > +
> > +static int hv_acpi_extended_sleep_handler(u8 sleep_state, u32 val_a, u32 val_b)
> > +{
> > + return hv_acpi_sleep_handler(sleep_state, val_a, val_b);
> > +}
>
> Is this function needed? The function signature is identical to hv_acpi_sleep_handler().
> So it seems like acpi_os_set_prepare_extended_sleep() could just use
> hv_acpi_sleep_handler() directly.
>
Upon further investigation, I discovered that extended sleep is only
supported on platforms with ACPI_REDUCED_HARDWARE.
As these patches are targetted at X86, above does not really apply. I
will drop this handler in next version.
> > +
> > +int hv_sleep_notifiers_register(void)
> > +{
> > + int ret;
> > +
> > + acpi_os_set_prepare_sleep(&hv_acpi_sleep_handler);
> > + acpi_os_set_prepare_extended_sleep(&hv_acpi_extended_sleep_handler);
>
> I'm not clear on why these handlers are set. If the hv_reboot_notifier is
> called, are these ACPI handlers ever called? Or are these to catch any cases
> where the hv_reboot_notifier is somehow bypassed? Or maybe I'm just
> not understanding something .... :-)
>
I am trying to trace these calls. I will keep you posted with my
findings.
> > +
> > + ret = register_reboot_notifier(&hv_reboot_notifier);
> > + if (ret)
> > + pr_err("%s: cannot register reboot notifier %d\n",
> > + __func__, ret);
> > +
> > + return ret;
> > +}
> > +#endif
>
> I'm wondering if all this code belongs in hv_common.c, since it is only needed
> for Linux in the root partition. Couldn't it go in mshv_common.c? It would still
> be built-in code (i.e., not in a loadable module), but only if CONFIG_MSHV_ROOT
> is set.
>
This sounds reasonable. I will discuss this internally and get back you.
> Michael
>
> > --
> > 2.51.0
> >
^ permalink raw reply
* RE: [EXTERNAL] Re: [PATCH net-next,v2] net: mana: Support HW link state events
From: Haiyang Zhang @ 2025-10-20 14:58 UTC (permalink / raw)
To: Jakub Kicinski, Haiyang Zhang
Cc: linux-hyperv@vger.kernel.org, netdev@vger.kernel.org,
Paul Rosswurm, Dexuan Cui, KY Srinivasan, wei.liu@kernel.org,
edumazet@google.com, davem@davemloft.net, pabeni@redhat.com,
Long Li, ssengar@linux.microsoft.com, ernis@linux.microsoft.com,
dipayanroy@linux.microsoft.com, Konstantin Taranov,
horms@kernel.org, shradhagupta@linux.microsoft.com,
leon@kernel.org, mlevitsk@redhat.com, yury.norov@gmail.com,
Shiraz Saleem, andrew+netdev@lunn.ch, linux-rdma@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20251017160541.4ce65ede@kernel.org>
> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Friday, October 17, 2025 7:06 PM
> To: Haiyang Zhang <haiyangz@linux.microsoft.com>
> Cc: linux-hyperv@vger.kernel.org; netdev@vger.kernel.org; Haiyang Zhang
> <haiyangz@microsoft.com>; Paul Rosswurm <paulros@microsoft.com>; Dexuan
> Cui <DECUI@microsoft.com>; KY Srinivasan <kys@microsoft.com>;
> wei.liu@kernel.org; edumazet@google.com; davem@davemloft.net;
> pabeni@redhat.com; Long Li <longli@microsoft.com>;
> ssengar@linux.microsoft.com; ernis@linux.microsoft.com;
> dipayanroy@linux.microsoft.com; Konstantin Taranov
> <kotaranov@microsoft.com>; horms@kernel.org;
> shradhagupta@linux.microsoft.com; leon@kernel.org; mlevitsk@redhat.com;
> yury.norov@gmail.com; Shiraz Saleem <shirazsaleem@microsoft.com>;
> andrew+netdev@lunn.ch; linux-rdma@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [EXTERNAL] Re: [PATCH net-next,v2] net: mana: Support HW link
> state events
>
> On Tue, 14 Oct 2025 14:26:49 -0700 Haiyang Zhang wrote:
> > From: Haiyang Zhang <haiyangz@microsoft.com>
> >
> > Handle the HW link state events received from HW channel, and
> > set the proper link state, also stop/wake queues accordingly.
>
> Why do you have to stop / start the queues? I think it's unusual.
> Let the packets get dropped, sending out potentially old packets
> when link comes back is not going to make anyone happier.
Will do.
>
> > +static void mana_link_state_handle(struct work_struct *w)
> > +{
> > + struct mana_port_context *apc;
> > + struct mana_context *ac;
> > + struct net_device *ndev;
> > + bool link_up;
> > + int i;
> > +
> > + ac = container_of(w, struct mana_context, link_change_work);
> > +
> > + if (ac->mana_removing)
> > + return;
> > +
> > + rtnl_lock();
> > +
>
> > @@ -3500,6 +3556,10 @@ void mana_remove(struct gdma_dev *gd, bool
> suspending)
> > int err;
> > int i;
> >
> > + ac->mana_removing = true;
> > +
> > + cancel_work_sync(&ac->link_change_work);
>
> Looks racy, the work needs @ac to check the ->mana_removing but
> mana_remove() frees @ac. Just use disable_work_sync() please.
Good idea. Will update the patch.
Thanks,
- Haiyang
^ permalink raw reply
* Family December trip
From: Pina Alvarez @ 2025-10-18 18:27 UTC (permalink / raw)
To: linux-hyperv
Hello,
I was wondering if you received the email I sent last week regarding the
December trip, I would hope you can plan for myself and my family of 14
(10 Adults & 4 Children)
am attaching an itinerary also for you to take a look
thank you
Pina Alvarez
^ permalink raw reply
* Re: [PATCH v6 01/10] x86/acpi: Add helper functions to setup and access the wakeup mailbox
From: Rafael J. Wysocki @ 2025-10-18 13:08 UTC (permalink / raw)
To: Ricardo Neri
Cc: Rafael J. Wysocki, x86, Krzysztof Kozlowski, Conor Dooley,
Rob Herring, K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Michael Kelley, Saurabh Sengar, Chris Oo, Kirill A. Shutemov,
linux-hyperv, devicetree, linux-acpi, linux-kernel, Ricardo Neri,
Rafael J. Wysocki
In-Reply-To: <20251017211015.GA7078@ranerica-svr.sc.intel.com>
On Sat, Oct 18, 2025 at 4:48 AM Ricardo Neri
<ricardo.neri-calderon@linux.intel.com> wrote:
>
> On Fri, Oct 17, 2025 at 11:46:59AM +0200, Rafael J. Wysocki wrote:
> > On Fri, Oct 17, 2025 at 4:48 AM Ricardo Neri
> > <ricardo.neri-calderon@linux.intel.com> wrote:
> > >
> > > In preparation to move the functionality to wake secondary CPUs up from the
> > > ACPI code, add two helper functions.
> > >
> > > The function acpi_setup_mp_wakeup_mailbox() stores the physical address of
> > > the mailbox and updates the wakeup_secondary_cpu_64() APIC callback.
> > >
> > > There is a slight change in behavior: now the APIC callback is updated
> > > before configuring CPU hotplug offline behavior. This is fine as the APIC
> > > callback continues to be updated unconditionally, regardless of the
> > > restriction on CPU offlining.
> > >
> > > The function acpi_madt_multiproc_wakeup_mailbox() returns a pointer to the
> > > mailbox. Use this helper function only in the portions of the code for
> > > which the variable acpi_mp_wake_mailbox will be out of scope once it is
> > > relocated out of the ACPI directory.
> > >
> > > The wakeup mailbox is only supported for CONFIG_X86_64 and needed only with
> > > CONFIG_SMP=y.
> > >
> > > Reviewed-by: Dexuan Cui <decui@microsoft.com>
> > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > This should have been
> >
> > Acked-by: Rafael J. Wysocki (Intel) <rafael.j.wysocki@intel.com>
> >
> > The "(Intel)" part is missing and I omitted it when I sent the tag.
> > Sorry for the confusion.
>
> Thanks for the clarification Rafael. Does this clarification apply also
> patches 2 and 3?
Yes, it does.
> Also, if no further changes are needed in the series, can it be corrected
> when the patches are merged?
I think so.
^ permalink raw reply
* RE: [PATCH v3 0/6] Hyper-V: Implement hypervisor core collection
From: Michael Kelley @ 2025-10-18 2:54 UTC (permalink / raw)
To: Mukesh R, Wei Liu
Cc: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arch@vger.kernel.org, kys@microsoft.com,
haiyangz@microsoft.com, decui@microsoft.com, tglx@linutronix.de,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
x86@kernel.org, hpa@zytor.com, arnd@arndb.de
In-Reply-To: <74e019ac-afc7-3178-0f0a-dc903af5c4ca@linux.microsoft.com>
From: Mukesh R <mrathor@linux.microsoft.com> Sent: Friday, October 17, 2025 4:58 PM
>
> On 10/17/25 15:57, Wei Liu wrote:
> > On Fri, Oct 17, 2025 at 10:33:00PM +0000, Wei Liu wrote:
> >> On Mon, Oct 06, 2025 at 03:42:02PM -0700, Mukesh Rathor wrote:
> >> [...]
> >>> Mukesh Rathor (6):
> >>> x86/hyperv: Rename guest crash shutdown function
> >>> hyperv: Add two new hypercall numbers to guest ABI public header
> >>> hyperv: Add definitions for hypervisor crash dump support
> >>> x86/hyperv: Add trampoline asm code to transition from hypervisor
> >>> x86/hyperv: Implement hypervisor RAM collection into vmcore
> >>> x86/hyperv: Enable build of hypervisor crashdump collection files
> >>>
> >>
> >> Applied to hyperv-next. Thanks.
> >
> > This breaks i386 build.
> >
> > /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c: In function ?hyperv_init?:
> > /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c:557:17: error: implicit declaration of function ?hv_root_crash_init? [-Werror=implicit-function-declaration]
> > 557 | hv_root_crash_init();
> > | ^~~~~~~~~~~~~~~~~~
> >
> > That's because CONFIG_MSHV_ROOT is only available on x86_64. And the
> > crash feature is guarded by CONFIG_MSHV_ROOT.
> >
> > Applying the following diff fixes the build.
>
>
> Thanks. A bit surprising tho that CONFIG_MSHV_ROOT doesn't have
> hard dependency on x86_64. It should, no?
CONFIG_MSHV_ROOT *does* have a hard dependency on X86_64.
But the problem is actually more pervasive than just 32-bit builds. Because
of the hard dependency, 32-bit builds imply CONFIG_MSHV_ROOT=n, which is
the real problem. In arch/x86/include/asm/mshyperv.h the declaration for
hv_root_crash_init() is available only when CONFIG_MSHV_ROOT is defined
(m or y). There's a stub hv_root_crash_init() if CONFIG_MSHV_ROOT is defined
and CONFIG_CRASH_DUMP=n, but not if CONFIG_MSHV_ROOT=n. The solution
is to add a stub when CONFIG_MSHV_ROOT=n, as below:
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 76582affefa8..a5b258d268ed 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -248,6 +248,8 @@ void hv_crash_asm_end(void);
static inline void hv_root_crash_init(void) {}
#endif /* CONFIG_CRASH_DUMP */
+#else /* CONFIG_MSHV_ROOT */
+static inline void hv_root_crash_init(void) {}
#endif /* CONFIG_MSHV_ROOT */
#else /* CONFIG_HYPERV */
Annoyingly, this solution duplicates the hv_root_crash_init() stub. So
an alternate approach that changes a few more lines of code is this:
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 76582affefa8..1342d55c2545 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -237,18 +237,14 @@ static __always_inline u64 hv_raw_get_msr(unsigned int reg)
}
int hv_apicid_to_vp_index(u32 apic_id);
-#if IS_ENABLED(CONFIG_MSHV_ROOT)
-
-#ifdef CONFIG_CRASH_DUMP
+#if IS_ENABLED(CONFIG_MSHV_ROOT) && IS_ENABLED(CONFIG_CRASH_DUMP)
void hv_root_crash_init(void);
void hv_crash_asm32(void);
void hv_crash_asm64(void);
void hv_crash_asm_end(void);
-#else /* CONFIG_CRASH_DUMP */
+#else /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
static inline void hv_root_crash_init(void) {}
-#endif /* CONFIG_CRASH_DUMP */
-
-#endif /* CONFIG_MSHV_ROOT */
+#endif /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
#else /* CONFIG_HYPERV */
static inline void hyperv_init(void) {}
Michael
^ permalink raw reply related
* Re: [PATCH v6 01/10] x86/acpi: Add helper functions to setup and access the wakeup mailbox
From: Ricardo Neri @ 2025-10-17 21:10 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: x86, Krzysztof Kozlowski, Conor Dooley, Rob Herring,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Michael Kelley, Saurabh Sengar, Chris Oo, Kirill A. Shutemov,
linux-hyperv, devicetree, linux-acpi, linux-kernel, Ricardo Neri,
Rafael J. Wysocki
In-Reply-To: <CAJZ5v0iB4iZFs8C6EZayLVPbLz50MJ9GEniSHfbP31-yHRg1Bw@mail.gmail.com>
On Fri, Oct 17, 2025 at 11:46:59AM +0200, Rafael J. Wysocki wrote:
> On Fri, Oct 17, 2025 at 4:48 AM Ricardo Neri
> <ricardo.neri-calderon@linux.intel.com> wrote:
> >
> > In preparation to move the functionality to wake secondary CPUs up from the
> > ACPI code, add two helper functions.
> >
> > The function acpi_setup_mp_wakeup_mailbox() stores the physical address of
> > the mailbox and updates the wakeup_secondary_cpu_64() APIC callback.
> >
> > There is a slight change in behavior: now the APIC callback is updated
> > before configuring CPU hotplug offline behavior. This is fine as the APIC
> > callback continues to be updated unconditionally, regardless of the
> > restriction on CPU offlining.
> >
> > The function acpi_madt_multiproc_wakeup_mailbox() returns a pointer to the
> > mailbox. Use this helper function only in the portions of the code for
> > which the variable acpi_mp_wake_mailbox will be out of scope once it is
> > relocated out of the ACPI directory.
> >
> > The wakeup mailbox is only supported for CONFIG_X86_64 and needed only with
> > CONFIG_SMP=y.
> >
> > Reviewed-by: Dexuan Cui <decui@microsoft.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> This should have been
>
> Acked-by: Rafael J. Wysocki (Intel) <rafael.j.wysocki@intel.com>
>
> The "(Intel)" part is missing and I omitted it when I sent the tag.
> Sorry for the confusion.
Thanks for the clarification Rafael. Does this clarification apply also
patches 2 and 3?
Also, if no further changes are needed in the series, can it be corrected
when the patches are merged?
^ permalink raw reply
* Re: [PATCH v3 0/6] Hyper-V: Implement hypervisor core collection
From: Mukesh R @ 2025-10-17 23:58 UTC (permalink / raw)
To: Wei Liu
Cc: linux-hyperv, linux-kernel, linux-arch, kys, haiyangz, decui,
tglx, mingo, bp, dave.hansen, x86, hpa, arnd
In-Reply-To: <20251017225732.GC632885@liuwe-devbox-debian-v2.local>
On 10/17/25 15:57, Wei Liu wrote:
> On Fri, Oct 17, 2025 at 10:33:00PM +0000, Wei Liu wrote:
>> On Mon, Oct 06, 2025 at 03:42:02PM -0700, Mukesh Rathor wrote:
>> [...]
>>> Mukesh Rathor (6):
>>> x86/hyperv: Rename guest crash shutdown function
>>> hyperv: Add two new hypercall numbers to guest ABI public header
>>> hyperv: Add definitions for hypervisor crash dump support
>>> x86/hyperv: Add trampoline asm code to transition from hypervisor
>>> x86/hyperv: Implement hypervisor RAM collection into vmcore
>>> x86/hyperv: Enable build of hypervisor crashdump collection files
>>>
>>
>> Applied to hyperv-next. Thanks.
>
> This breaks i386 build.
>
> /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c: In function ?hyperv_init?:
> /work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c:557:17: error: implicit declaration of function ?hv_root_crash_init? [-Werror=implicit-function-declaration]
> 557 | hv_root_crash_init();
> | ^~~~~~~~~~~~~~~~~~
>
> That's because CONFIG_MSHV_ROOT is only available on x86_64. And the
> crash feature is guarded by CONFIG_MSHV_ROOT.
>
> Applying the following diff fixes the build.
Thanks. A bit surprising tho that CONFIG_MSHV_ROOT doesn't have
hard dependency on x86_64. It should, no?
Thanks,
-Mukesh
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index e28737ec7054..c1300339d2eb 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -554,7 +554,9 @@ void __init hyperv_init(void)
> memunmap(src);
>
> hv_remap_tsc_clocksource();
> +#ifdef CONFIG_X86_64
> hv_root_crash_init();
> +#endif
> } else {
> hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
> wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>
>>
>>> arch/x86/hyperv/Makefile | 6 +
>>> arch/x86/hyperv/hv_crash.c | 642 ++++++++++++++++++++++++++++++++
>>> arch/x86/hyperv/hv_init.c | 1 +
>>> arch/x86/hyperv/hv_trampoline.S | 101 +++++
>>> arch/x86/include/asm/mshyperv.h | 13 +
>>> arch/x86/kernel/cpu/mshyperv.c | 5 +-
>>> include/hyperv/hvgdk_mini.h | 2 +
>>> include/hyperv/hvhdk_mini.h | 55 +++
>>> 8 files changed, 823 insertions(+), 2 deletions(-)
>>> create mode 100644 arch/x86/hyperv/hv_crash.c
>>> create mode 100644 arch/x86/hyperv/hv_trampoline.S
>>>
>>> --
>>> 2.36.1.vfs.0.0
>>>
^ permalink raw reply
* Re: [PATCH v5 5/5] Drivers: hv: Add support for movable memory regions
From: Mukesh R @ 2025-10-17 23:55 UTC (permalink / raw)
To: Stanislav Kinsburskii, kys, haiyangz, wei.liu, decui
Cc: linux-hyperv, linux-kernel
In-Reply-To: <176057443695.74314.10584965103467299030.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>
On 10/15/25 17:27, Stanislav Kinsburskii wrote:
> Introduce support for movable memory regions in the Hyper-V root partition
> driver, thus improving memory management flexibility and preparing the
> driver for advanced use cases such as dynamic memory remapping.
>
> Integrate mmu_interval_notifier for movable regions, implement functions to
> handle HMM faults and memory invalidation, and update memory region mapping
> logic to support movable regions.
>
> While MMU notifiers are commonly used in virtualization drivers, this
> implementation leverages HMM (Heterogeneous Memory Management) for its
> tailored functionality. HMM provides a ready-made framework for mirroring,
> invalidation, and fault handling, avoiding the need to reimplement these
> mechanisms for a single callback. Although MMU notifiers are more generic,
> using HMM reduces boilerplate and ensures maintainability by utilizing a
> mechanism specifically designed for such use cases.
>
> Signed-off-by: Anirudh Rayabharam <anrayabh@linux.microsoft.com>
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> ---
> drivers/hv/Kconfig | 1
> drivers/hv/mshv_root.h | 8 +
> drivers/hv/mshv_root_main.c | 328 ++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 327 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> index 0b8c391a0342..5f1637cbb6e3 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -75,6 +75,7 @@ config MSHV_ROOT
> depends on PAGE_SIZE_4KB
> select EVENTFD
> select VIRT_XFER_TO_GUEST_WORK
> + select HMM_MIRROR
> default n
> help
> Select this option to enable support for booting and running as root
> diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
> index 97e64d5341b6..13367c84497c 100644
> --- a/drivers/hv/mshv_root.h
> +++ b/drivers/hv/mshv_root.h
> @@ -15,6 +15,7 @@
> #include <linux/hashtable.h>
> #include <linux/dev_printk.h>
> #include <linux/build_bug.h>
> +#include <linux/mmu_notifier.h>
> #include <uapi/linux/mshv.h>
>
> /*
> @@ -81,9 +82,14 @@ struct mshv_mem_region {
> struct {
> u64 large_pages: 1; /* 2MiB */
> u64 range_pinned: 1;
> - u64 reserved: 62;
> + u64 is_ram : 1; /* mem region can be ram or mmio */
In case this gets accepted/merged, this is named
+ u64 memreg_isram: 1; /* mem region can be ram or mmio */
Keeping the name same will avoid unnecessary diffs when we try to compare
files to see what is missing internally or externally.
Thanks,
-Mukesh
> } flags;
> struct mshv_partition *partition;
> +#if defined(CONFIG_MMU_NOTIFIER)
> + struct mmu_interval_notifier mni;
> + struct mutex mutex; /* protects region pages remapping */
> +#endif
> struct page *pages[];
> };
>
> diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
> index c4f114376435..b2738443ac5d 100644
> --- a/drivers/hv/mshv_root_main.c
> +++ b/drivers/hv/mshv_root_main.c
> @@ -29,6 +29,7 @@
> #include <linux/crash_dump.h>
> #include <linux/panic_notifier.h>
> #include <linux/vmalloc.h>
> +#include <linux/hmm.h>
>
> #include "mshv_eventfd.h"
> #include "mshv.h"
> @@ -36,6 +37,8 @@
>
> #define VALUE_PMD_ALIGNED(c) (!((c) & (PTRS_PER_PMD - 1)))
>
> +#define MSHV_MAP_FAULT_IN_PAGES HPAGE_PMD_NR
> +
> MODULE_AUTHOR("Microsoft");
> MODULE_LICENSE("GPL");
> MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv");
> @@ -76,6 +79,11 @@ static int mshv_vp_mmap(struct file *file, struct vm_area_struct *vma);
> static vm_fault_t mshv_vp_fault(struct vm_fault *vmf);
> static int mshv_init_async_handler(struct mshv_partition *partition);
> static void mshv_async_hvcall_handler(void *data, u64 *status);
> +static struct mshv_mem_region
> + *mshv_partition_region_by_gfn(struct mshv_partition *pt, u64 gfn);
> +static int mshv_region_remap_pages(struct mshv_mem_region *region,
> + u32 map_flags, u64 page_offset,
> + u64 page_count);
>
> static const union hv_input_vtl input_vtl_zero;
> static const union hv_input_vtl input_vtl_normal = {
> @@ -602,14 +610,197 @@ static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp)
> static_assert(sizeof(struct hv_message) <= MSHV_RUN_VP_BUF_SZ,
> "sizeof(struct hv_message) must not exceed MSHV_RUN_VP_BUF_SZ");
>
> +#ifdef CONFIG_X86_64
> +
> +#if defined(CONFIG_MMU_NOTIFIER)
> +/**
> + * mshv_region_hmm_fault_and_lock - Handle HMM faults and lock the memory region
> + * @region: Pointer to the memory region structure
> + * @range: Pointer to the HMM range structure
> + *
> + * This function performs the following steps:
> + * 1. Reads the notifier sequence for the HMM range.
> + * 2. Acquires a read lock on the memory map.
> + * 3. Handles HMM faults for the specified range.
> + * 4. Releases the read lock on the memory map.
> + * 5. If successful, locks the memory region mutex.
> + * 6. Verifies if the notifier sequence has changed during the operation.
> + * If it has, releases the mutex and returns -EBUSY to match with
> + * hmm_range_fault() return code for repeating.
> + *
> + * Return: 0 on success, a negative error code otherwise.
> + */
> +static int mshv_region_hmm_fault_and_lock(struct mshv_mem_region *region,
> + struct hmm_range *range)
> +{
> + int ret;
> +
> + range->notifier_seq = mmu_interval_read_begin(range->notifier);
> + mmap_read_lock(region->mni.mm);
> + ret = hmm_range_fault(range);
> + mmap_read_unlock(region->mni.mm);
> + if (ret)
> + return ret;
> +
> + mutex_lock(®ion->mutex);
> +
> + if (mmu_interval_read_retry(range->notifier, range->notifier_seq)) {
> + mutex_unlock(®ion->mutex);
> + cond_resched();
> + return -EBUSY;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * mshv_region_range_fault - Handle memory range faults for a given region.
> + * @region: Pointer to the memory region structure.
> + * @page_offset: Offset of the page within the region.
> + * @page_count: Number of pages to handle.
> + *
> + * This function resolves memory faults for a specified range of pages
> + * within a memory region. It uses HMM (Heterogeneous Memory Management)
> + * to fault in the required pages and updates the region's page array.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +static int mshv_region_range_fault(struct mshv_mem_region *region,
> + u64 page_offset, u64 page_count)
> +{
> + struct hmm_range range = {
> + .notifier = ®ion->mni,
> + .default_flags = HMM_PFN_REQ_FAULT | HMM_PFN_REQ_WRITE,
> + };
> + unsigned long *pfns;
> + int ret;
> + u64 i;
> +
> + pfns = kmalloc_array(page_count, sizeof(unsigned long), GFP_KERNEL);
> + if (!pfns)
> + return -ENOMEM;
> +
> + range.hmm_pfns = pfns;
> + range.start = region->start_uaddr + page_offset * HV_HYP_PAGE_SIZE;
> + range.end = range.start + page_count * HV_HYP_PAGE_SIZE;
> +
> + do {
> + ret = mshv_region_hmm_fault_and_lock(region, &range);
> + } while (ret == -EBUSY);
> +
> + if (ret)
> + goto out;
> +
> + for (i = 0; i < page_count; i++)
> + region->pages[page_offset + i] = hmm_pfn_to_page(pfns[i]);
> +
> + if (PageHuge(region->pages[page_offset]))
> + region->flags.large_pages = true;
> +
> + ret = mshv_region_remap_pages(region, region->hv_map_flags,
> + page_offset, page_count);
> +
> + mutex_unlock(®ion->mutex);
> +out:
> + kfree(pfns);
> + return ret;
> +}
> +#else /* CONFIG_MMU_NOTIFIER */
> +static int mshv_region_range_fault(struct mshv_mem_region *region,
> + u64 page_offset, u64 page_count)
> +{
> + return -ENODEV;
> +}
> +#endif /* CONFIG_MMU_NOTIFIER */
> +
> +static bool mshv_region_handle_gfn_fault(struct mshv_mem_region *region, u64 gfn)
> +{
> + u64 page_offset, page_count;
> + int ret;
> +
> + if (WARN_ON_ONCE(region->flags.range_pinned))
> + return false;
> +
> + /* Align the page offset to the nearest MSHV_MAP_FAULT_IN_PAGES. */
> + page_offset = ALIGN_DOWN(gfn - region->start_gfn,
> + MSHV_MAP_FAULT_IN_PAGES);
> +
> + /* Map more pages than requested to reduce the number of faults. */
> + page_count = min(region->nr_pages - page_offset,
> + MSHV_MAP_FAULT_IN_PAGES);
> +
> + ret = mshv_region_range_fault(region, page_offset, page_count);
> +
> + WARN_ONCE(ret,
> + "p%llu: GPA intercept failed: region %#llx-%#llx, gfn %#llx, page_offset %llu, page_count %llu\n",
> + region->partition->pt_id, region->start_uaddr,
> + region->start_uaddr + (region->nr_pages << HV_HYP_PAGE_SHIFT),
> + gfn, page_offset, page_count);
> +
> + return !ret;
> +}
> +
> +/**
> + * mshv_handle_gpa_intercept - Handle GPA (Guest Physical Address) intercepts.
> + * @vp: Pointer to the virtual processor structure.
> + *
> + * This function processes GPA intercepts by identifying the memory region
> + * corresponding to the intercepted GPA, aligning the page offset, and
> + * mapping the required pages. It ensures that the region is valid and
> + * handles faults efficiently by mapping multiple pages at once.
> + *
> + * Return: true if the intercept was handled successfully, false otherwise.
> + */
> +static bool mshv_handle_gpa_intercept(struct mshv_vp *vp)
> +{
> + struct mshv_partition *p = vp->vp_partition;
> + struct mshv_mem_region *region;
> + struct hv_x64_memory_intercept_message *msg;
> + u64 gfn;
> +
> + msg = (struct hv_x64_memory_intercept_message *)
> + vp->vp_intercept_msg_page->u.payload;
> +
> + gfn = HVPFN_DOWN(msg->guest_physical_address);
> +
> + region = mshv_partition_region_by_gfn(p, gfn);
> + if (!region)
> + return false;
> +
> + if (WARN_ON_ONCE(!region->flags.is_ram))
> + return false;
> +
> + if (WARN_ON_ONCE(region->flags.range_pinned))
> + return false;
> +
> + return mshv_region_handle_gfn_fault(region, gfn);
> +}
> +
> +#else /* CONFIG_X86_64 */
> +
> +static bool mshv_handle_gpa_intercept(struct mshv_vp *vp) { return false; }
> +
> +#endif /* CONFIG_X86_64 */
> +
> +static bool mshv_vp_handle_intercept(struct mshv_vp *vp)
> +{
> + switch (vp->vp_intercept_msg_page->header.message_type) {
> + case HVMSG_GPA_INTERCEPT:
> + return mshv_handle_gpa_intercept(vp);
> + }
> + return false;
> +}
> +
> static long mshv_vp_ioctl_run_vp(struct mshv_vp *vp, void __user *ret_msg)
> {
> long rc;
>
> - if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
> - rc = mshv_run_vp_with_root_scheduler(vp);
> - else
> - rc = mshv_run_vp_with_hyp_scheduler(vp);
> + do {
> + if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
> + rc = mshv_run_vp_with_root_scheduler(vp);
> + else
> + rc = mshv_run_vp_with_hyp_scheduler(vp);
> + } while (rc == 0 && mshv_vp_handle_intercept(vp));
>
> if (rc)
> return rc;
> @@ -1209,6 +1400,110 @@ mshv_partition_region_by_uaddr(struct mshv_partition *partition, u64 uaddr)
> return NULL;
> }
>
> +#if defined(CONFIG_MMU_NOTIFIER)
> +static void mshv_region_movable_fini(struct mshv_mem_region *region)
> +{
> + if (region->flags.range_pinned)
> + return;
> +
> + mmu_interval_notifier_remove(®ion->mni);
> +}
> +
> +/**
> + * mshv_region_interval_invalidate - Invalidate a range of memory region
> + * @mni: Pointer to the mmu_interval_notifier structure
> + * @range: Pointer to the mmu_notifier_range structure
> + * @cur_seq: Current sequence number for the interval notifier
> + *
> + * This function invalidates a memory region by remapping its pages with
> + * no access permissions. It locks the region's mutex to ensure thread safety
> + * and updates the sequence number for the interval notifier. If the range
> + * is blockable, it uses a blocking lock; otherwise, it attempts a non-blocking
> + * lock and returns false if unsuccessful.
> + *
> + * NOTE: Failure to invalidate a region is a serious error, as the pages will
> + * be considered freed while they are still mapped by the hypervisor.
> + * Any attempt to access such pages will likely crash the system.
> + *
> + * Return: true if the region was successfully invalidated, false otherwise.
> + */
> +static bool
> +mshv_region_interval_invalidate(struct mmu_interval_notifier *mni,
> + const struct mmu_notifier_range *range,
> + unsigned long cur_seq)
> +{
> + struct mshv_mem_region *region = container_of(mni,
> + struct mshv_mem_region,
> + mni);
> + u64 page_offset, page_count;
> + unsigned long mstart, mend;
> + int ret = -EPERM;
> +
> + if (mmu_notifier_range_blockable(range))
> + mutex_lock(®ion->mutex);
> + else if (!mutex_trylock(®ion->mutex))
> + goto out_fail;
> +
> + mmu_interval_set_seq(mni, cur_seq);
> +
> + mstart = max(range->start, region->start_uaddr);
> + mend = min(range->end, region->start_uaddr +
> + (region->nr_pages << HV_HYP_PAGE_SHIFT));
> +
> + page_offset = HVPFN_DOWN(mstart - region->start_uaddr);
> + page_count = HVPFN_DOWN(mend - mstart);
> +
> + ret = mshv_region_remap_pages(region, HV_MAP_GPA_NO_ACCESS,
> + page_offset, page_count);
> + if (ret)
> + goto out_fail;
> +
> + mshv_region_invalidate_pages(region, page_offset, page_count);
> +
> + mutex_unlock(®ion->mutex);
> +
> + return true;
> +
> +out_fail:
> + WARN_ONCE(ret,
> + "Failed to invalidate region %#llx-%#llx (range %#lx-%#lx, event: %u, pages %#llx-%#llx, mm: %#llx): %d\n",
> + region->start_uaddr,
> + region->start_uaddr + (region->nr_pages << HV_HYP_PAGE_SHIFT),
> + range->start, range->end, range->event,
> + page_offset, page_offset + page_count - 1, (u64)range->mm, ret);
> + return false;
> +}
> +
> +static const struct mmu_interval_notifier_ops mshv_region_mni_ops = {
> + .invalidate = mshv_region_interval_invalidate,
> +};
> +
> +static bool mshv_region_movable_init(struct mshv_mem_region *region)
> +{
> + int ret;
> +
> + ret = mmu_interval_notifier_insert(®ion->mni, current->mm,
> + region->start_uaddr,
> + region->nr_pages << HV_HYP_PAGE_SHIFT,
> + &mshv_region_mni_ops);
> + if (ret)
> + return false;
> +
> + mutex_init(®ion->mutex);
> +
> + return true;
> +}
> +#else
> +static inline void mshv_region_movable_fini(struct mshv_mem_region *region)
> +{
> +}
> +
> +static inline bool mshv_region_movable_init(struct mshv_mem_region *region)
> +{
> + return false;
> +}
> +#endif
> +
> /*
> * NB: caller checks and makes sure mem->size is page aligned
> * Returns: 0 with regionpp updated on success, or -errno
> @@ -1241,9 +1536,14 @@ static int mshv_partition_create_region(struct mshv_partition *partition,
> if (mem->flags & BIT(MSHV_SET_MEM_BIT_EXECUTABLE))
> region->hv_map_flags |= HV_MAP_GPA_EXECUTABLE;
>
> - /* Note: large_pages flag populated when we pin the pages */
> - if (!is_mmio)
> - region->flags.range_pinned = true;
> + /* Note: large_pages flag populated when pages are allocated. */
> + if (!is_mmio) {
> + region->flags.is_ram = true;
> +
> + if (mshv_partition_encrypted(partition) ||
> + !mshv_region_movable_init(region))
> + region->flags.range_pinned = true;
> + }
>
> region->partition = partition;
>
> @@ -1363,9 +1663,16 @@ mshv_map_user_memory(struct mshv_partition *partition,
> if (is_mmio)
> ret = hv_call_map_mmio_pages(partition->pt_id, mem.guest_pfn,
> mmio_pfn, HVPFN_DOWN(mem.size));
> - else
> + else if (region->flags.range_pinned)
> ret = mshv_prepare_pinned_region(region);
> -
> + else
> + /*
> + * For non-pinned regions, remap with no access to let the
> + * hypervisor track dirty pages, enabling pre-copy live
> + * migration.
> + */
> + ret = mshv_region_remap_pages(region, HV_MAP_GPA_NO_ACCESS,
> + 0, region->nr_pages);
> if (ret)
> goto errout;
>
> @@ -1388,6 +1695,9 @@ static void mshv_partition_destroy_region(struct mshv_mem_region *region)
>
> hlist_del(®ion->hnode);
>
> + if (region->flags.is_ram)
> + mshv_region_movable_fini(region);
> +
> if (mshv_partition_encrypted(partition)) {
> ret = mshv_partition_region_share(region);
> if (ret) {
>
>
^ permalink raw reply
* Re: [PATCH net-next,v2] net: mana: Support HW link state events
From: Jakub Kicinski @ 2025-10-17 23:05 UTC (permalink / raw)
To: Haiyang Zhang
Cc: linux-hyperv, netdev, haiyangz, paulros, decui, kys, wei.liu,
edumazet, davem, pabeni, longli, ssengar, ernis, dipayanroy,
kotaranov, horms, shradhagupta, leon, mlevitsk, yury.norov,
shirazsaleem, andrew+netdev, linux-rdma, linux-kernel
In-Reply-To: <1760477209-9026-1-git-send-email-haiyangz@linux.microsoft.com>
On Tue, 14 Oct 2025 14:26:49 -0700 Haiyang Zhang wrote:
> From: Haiyang Zhang <haiyangz@microsoft.com>
>
> Handle the HW link state events received from HW channel, and
> set the proper link state, also stop/wake queues accordingly.
Why do you have to stop / start the queues? I think it's unusual.
Let the packets get dropped, sending out potentially old packets
when link comes back is not going to make anyone happier.
> +static void mana_link_state_handle(struct work_struct *w)
> +{
> + struct mana_port_context *apc;
> + struct mana_context *ac;
> + struct net_device *ndev;
> + bool link_up;
> + int i;
> +
> + ac = container_of(w, struct mana_context, link_change_work);
> +
> + if (ac->mana_removing)
> + return;
> +
> + rtnl_lock();
> +
> @@ -3500,6 +3556,10 @@ void mana_remove(struct gdma_dev *gd, bool suspending)
> int err;
> int i;
>
> + ac->mana_removing = true;
> +
> + cancel_work_sync(&ac->link_change_work);
Looks racy, the work needs @ac to check the ->mana_removing but
mana_remove() frees @ac. Just use disable_work_sync() please.
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH v3 0/6] Hyper-V: Implement hypervisor core collection
From: Wei Liu @ 2025-10-17 22:57 UTC (permalink / raw)
To: Mukesh Rathor
Cc: linux-hyperv, linux-kernel, linux-arch, kys, haiyangz, wei.liu,
decui, tglx, mingo, bp, dave.hansen, x86, hpa, arnd
In-Reply-To: <20251017223300.GB632885@liuwe-devbox-debian-v2.local>
On Fri, Oct 17, 2025 at 10:33:00PM +0000, Wei Liu wrote:
> On Mon, Oct 06, 2025 at 03:42:02PM -0700, Mukesh Rathor wrote:
> [...]
> > Mukesh Rathor (6):
> > x86/hyperv: Rename guest crash shutdown function
> > hyperv: Add two new hypercall numbers to guest ABI public header
> > hyperv: Add definitions for hypervisor crash dump support
> > x86/hyperv: Add trampoline asm code to transition from hypervisor
> > x86/hyperv: Implement hypervisor RAM collection into vmcore
> > x86/hyperv: Enable build of hypervisor crashdump collection files
> >
>
> Applied to hyperv-next. Thanks.
This breaks i386 build.
/work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c: In function ‘hyperv_init’:
/work/linux-on-hyperv/linux.git/arch/x86/hyperv/hv_init.c:557:17: error: implicit declaration of function ‘hv_root_crash_init’ [-Werror=implicit-function-declaration]
557 | hv_root_crash_init();
| ^~~~~~~~~~~~~~~~~~
That's because CONFIG_MSHV_ROOT is only available on x86_64. And the
crash feature is guarded by CONFIG_MSHV_ROOT.
Applying the following diff fixes the build.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index e28737ec7054..c1300339d2eb 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -554,7 +554,9 @@ void __init hyperv_init(void)
memunmap(src);
hv_remap_tsc_clocksource();
+#ifdef CONFIG_X86_64
hv_root_crash_init();
+#endif
} else {
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
>
> > arch/x86/hyperv/Makefile | 6 +
> > arch/x86/hyperv/hv_crash.c | 642 ++++++++++++++++++++++++++++++++
> > arch/x86/hyperv/hv_init.c | 1 +
> > arch/x86/hyperv/hv_trampoline.S | 101 +++++
> > arch/x86/include/asm/mshyperv.h | 13 +
> > arch/x86/kernel/cpu/mshyperv.c | 5 +-
> > include/hyperv/hvgdk_mini.h | 2 +
> > include/hyperv/hvhdk_mini.h | 55 +++
> > 8 files changed, 823 insertions(+), 2 deletions(-)
> > create mode 100644 arch/x86/hyperv/hv_crash.c
> > create mode 100644 arch/x86/hyperv/hv_trampoline.S
> >
> > --
> > 2.36.1.vfs.0.0
> >
^ permalink raw reply related
* Re: [PATCH v3 0/6] Hyper-V: Implement hypervisor core collection
From: Wei Liu @ 2025-10-17 22:33 UTC (permalink / raw)
To: Mukesh Rathor
Cc: linux-hyperv, linux-kernel, linux-arch, kys, haiyangz, wei.liu,
decui, tglx, mingo, bp, dave.hansen, x86, hpa, arnd
In-Reply-To: <20251006224208.1060990-1-mrathor@linux.microsoft.com>
On Mon, Oct 06, 2025 at 03:42:02PM -0700, Mukesh Rathor wrote:
[...]
> Mukesh Rathor (6):
> x86/hyperv: Rename guest crash shutdown function
> hyperv: Add two new hypercall numbers to guest ABI public header
> hyperv: Add definitions for hypervisor crash dump support
> x86/hyperv: Add trampoline asm code to transition from hypervisor
> x86/hyperv: Implement hypervisor RAM collection into vmcore
> x86/hyperv: Enable build of hypervisor crashdump collection files
>
Applied to hyperv-next. Thanks.
> arch/x86/hyperv/Makefile | 6 +
> arch/x86/hyperv/hv_crash.c | 642 ++++++++++++++++++++++++++++++++
> arch/x86/hyperv/hv_init.c | 1 +
> arch/x86/hyperv/hv_trampoline.S | 101 +++++
> arch/x86/include/asm/mshyperv.h | 13 +
> arch/x86/kernel/cpu/mshyperv.c | 5 +-
> include/hyperv/hvgdk_mini.h | 2 +
> include/hyperv/hvhdk_mini.h | 55 +++
> 8 files changed, 823 insertions(+), 2 deletions(-)
> create mode 100644 arch/x86/hyperv/hv_crash.c
> create mode 100644 arch/x86/hyperv/hv_trampoline.S
>
> --
> 2.36.1.vfs.0.0
>
^ permalink raw reply
* Re: [PATCH v2] mshv: Fix deposit memory in MSHV_ROOT_HVCALL
From: Wei Liu @ 2025-10-17 22:26 UTC (permalink / raw)
To: Nuno Das Neves
Cc: linux-hyperv, linux-kernel, mhklinux, kys, haiyangz, wei.liu,
decui, arnd, mrathor, skinsburskii
In-Reply-To: <20251017220655.GA614927@liuwe-devbox-debian-v2.local>
On Fri, Oct 17, 2025 at 10:06:55PM +0000, Wei Liu wrote:
> On Fri, Oct 17, 2025 at 11:58:17AM -0700, Nuno Das Neves wrote:
> > When the MSHV_ROOT_HVCALL ioctl is executing a hypercall, and gets
> > HV_STATUS_INSUFFICIENT_MEMORY, it deposits memory and then returns
> > -EAGAIN to userspace. The expectation is that the VMM will retry.
> >
> > However, some VMM code in the wild doesn't do this and simply fails.
> > Rather than force the VMM to retry, change the ioctl to deposit
> > memory on demand and immediately retry the hypercall as is done with
> > all the other hypercall helper functions.
> >
> > In addition to making the ioctl easier to use, removing the need for
> > multiple syscalls improves performance.
> >
> > There is a complication: unlike the other hypercall helper functions,
> > in MSHV_ROOT_HVCALL the input is opaque to the kernel. This is
> > problematic for rep hypercalls, because the next part of the input
> > list can't be copied on each loop after depositing pages (this was
> > the original reason for returning -EAGAIN in this case).
> >
> > Introduce hv_do_rep_hypercall_ex(), which adds a 'rep_start'
> > parameter. This solves the issue, allowing the deposit loop in
> > MSHV_ROOT_HVCALL to restart a rep hypercall after depositing pages
> > partway through.
> >
> > Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
>
> In v1 you said you will add a "Fixes" tag. Where is it?
I added this:
Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
Let me know if that's not correct.
Wei
^ permalink raw reply
* Re: [PATCH v6 04/10] x86/dt: Parse the Wakeup Mailbox for Intel processors
From: Wei Liu @ 2025-10-17 22:17 UTC (permalink / raw)
To: Ricardo Neri
Cc: x86, Krzysztof Kozlowski, Conor Dooley, Rob Herring,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Michael Kelley, Rafael J. Wysocki, Saurabh Sengar, Chris Oo,
Kirill A. Shutemov, linux-hyperv, devicetree, linux-acpi,
linux-kernel, Ricardo Neri, Yunhong Jiang
In-Reply-To: <20251016-rneri-wakeup-mailbox-v6-4-40435fb9305e@linux.intel.com>
On Thu, Oct 16, 2025 at 07:57:26PM -0700, Ricardo Neri wrote:
> The Wakeup Mailbox is a mechanism to boot secondary CPUs on systems that do
> not want or cannot use the INIT + StartUp IPI messages.
>
> The platform firmware is expected to implement the mailbox as described in
> the Multiprocessor Wakeup Structure of the ACPI specification. It is also
> expected to publish the mailbox to the operating system as described in the
> corresponding DeviceTree schema that accompanies the documentation of the
> Linux kernel.
>
> Reuse the existing functionality to set the memory location of the mailbox
> and update the wakeup_secondary_cpu_64() APIC callback. Make this
> functionality available to DeviceTree-based systems by making CONFIG_X86_
> MAILBOX_WAKEUP depend on either CONFIG_OF or CONFIG_ACPI_MADT_WAKEUP.
>
> do_boot_cpu() uses wakeup_secondary_cpu_64() when set. It will be set if a
> wakeup mailbox is enumerated via an ACPI table or a DeviceTree node. For
> cases in which this behavior is not desired, this APIC callback can be
> updated later during boot using platform-specific hooks.
>
> Reviewed-by: Dexuan Cui <decui@microsoft.com>
> Co-developed-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
> Signed-off-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Can I get an ack from x86 maintainers?
Wei
^ permalink raw reply
* Re: [PATCH v6 08/10] x86/smpwakeup: Add a helper get the address of the wakeup mailbox
From: Wei Liu @ 2025-10-17 22:16 UTC (permalink / raw)
To: Ricardo Neri
Cc: x86, Krzysztof Kozlowski, Conor Dooley, Rob Herring,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Michael Kelley, Rafael J. Wysocki, Saurabh Sengar, Chris Oo,
Kirill A. Shutemov, linux-hyperv, devicetree, linux-acpi,
linux-kernel, Ricardo Neri
In-Reply-To: <20251016-rneri-wakeup-mailbox-v6-8-40435fb9305e@linux.intel.com>
On Thu, Oct 16, 2025 at 07:57:30PM -0700, Ricardo Neri wrote:
> A Hyper-V VTL level 2 guest in a TDX environment needs to map the physical
> page of the ACPI Multiprocessor Wakeup Structure as private (encrypted). It
> needs to know the physical address of this structure. Add a helper function
> to retrieve the address.
>
> Reviewed-by: Dexuan Cui <decui@microsoft.com>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> Suggested-by: Michael Kelley <mhklinux@outlook.com>
> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Can I get an Ack from x86 maintainers?
> ---
> Changes since v5:
> - Added Reviewed-by tag from Dexuan. Thanks!
>
> Changes since v4:
> - None
>
> Changes since v3:
> - Renamed function to acpi_get_mp_wakeup_mailbox_paddr().
> - Added Reviewed-by tag from Michael. Thanks!
>
> Changes since v2:
> - Introduced this patch
>
> Changes since v1:
> - N/A
> ---
> arch/x86/include/asm/smp.h | 1 +
> arch/x86/kernel/smpwakeup.c | 5 +++++
> 2 files changed, 6 insertions(+)
>
> diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
> index 47ac4381a805..71de1963f984 100644
> --- a/arch/x86/include/asm/smp.h
> +++ b/arch/x86/include/asm/smp.h
> @@ -151,6 +151,7 @@ static inline struct cpumask *cpu_l2c_shared_mask(int cpu)
>
> void acpi_setup_mp_wakeup_mailbox(u64 addr);
> struct acpi_madt_multiproc_wakeup_mailbox *acpi_get_mp_wakeup_mailbox(void);
> +u64 acpi_get_mp_wakeup_mailbox_paddr(void);
>
> #else /* !CONFIG_SMP */
> #define wbinvd_on_cpu(cpu) wbinvd()
> diff --git a/arch/x86/kernel/smpwakeup.c b/arch/x86/kernel/smpwakeup.c
> index 5089bcda615d..f730a66b6fc8 100644
> --- a/arch/x86/kernel/smpwakeup.c
> +++ b/arch/x86/kernel/smpwakeup.c
> @@ -81,3 +81,8 @@ struct acpi_madt_multiproc_wakeup_mailbox *acpi_get_mp_wakeup_mailbox(void)
> {
> return acpi_mp_wake_mailbox;
> }
> +
> +u64 acpi_get_mp_wakeup_mailbox_paddr(void)
> +{
> + return acpi_mp_wake_mailbox_paddr;
> +}
>
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH -next] arch/x86: mshyperv: Remove duplicate asm/msr.h header
From: Wei Liu @ 2025-10-17 22:11 UTC (permalink / raw)
To: Jiapeng Chong
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, linux-hyperv, linux-kernel, Abaci Robot
In-Reply-To: <20251015015014.3636204-1-jiapeng.chong@linux.alibaba.com>
On Wed, Oct 15, 2025 at 09:50:14AM +0800, Jiapeng Chong wrote:
> ./arch/x86/kernel/cpu/mshyperv.c: asm/msr.h is included more than once.
>
> Reported-by: Abaci Robot <abaci@linux.alibaba.com>
> Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=26164
> Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Applied to hyperv-next. Thanks.
^ permalink raw reply
* Re: [PATCH] Hyper-V: add myself as maintainer
From: Wei Liu @ 2025-10-17 22:10 UTC (permalink / raw)
To: longli
Cc: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
linux-hyperv, linux-kernel, Long Li
In-Reply-To: <1760738294-32142-1-git-send-email-longli@linux.microsoft.com>
On Fri, Oct 17, 2025 at 02:58:14PM -0700, longli@linux.microsoft.com wrote:
> From: Long Li <longli@microsoft.com>
>
> Also include MANA RDMA driver in the Hyper-V maintained list.
>
> Signed-off-by: Long Li <longli@microsoft.com>
I changed the subject to "MAINTAINERS: Add Long Li as a Hyper-V maintainer".
Applied to hyperv-next.
Wei
^ permalink raw reply
* Re: [PATCH v2] mshv: Fix deposit memory in MSHV_ROOT_HVCALL
From: Wei Liu @ 2025-10-17 22:06 UTC (permalink / raw)
To: Nuno Das Neves
Cc: linux-hyperv, linux-kernel, mhklinux, kys, haiyangz, wei.liu,
decui, arnd, mrathor, skinsburskii
In-Reply-To: <1760727497-21158-1-git-send-email-nunodasneves@linux.microsoft.com>
On Fri, Oct 17, 2025 at 11:58:17AM -0700, Nuno Das Neves wrote:
> When the MSHV_ROOT_HVCALL ioctl is executing a hypercall, and gets
> HV_STATUS_INSUFFICIENT_MEMORY, it deposits memory and then returns
> -EAGAIN to userspace. The expectation is that the VMM will retry.
>
> However, some VMM code in the wild doesn't do this and simply fails.
> Rather than force the VMM to retry, change the ioctl to deposit
> memory on demand and immediately retry the hypercall as is done with
> all the other hypercall helper functions.
>
> In addition to making the ioctl easier to use, removing the need for
> multiple syscalls improves performance.
>
> There is a complication: unlike the other hypercall helper functions,
> in MSHV_ROOT_HVCALL the input is opaque to the kernel. This is
> problematic for rep hypercalls, because the next part of the input
> list can't be copied on each loop after depositing pages (this was
> the original reason for returning -EAGAIN in this case).
>
> Introduce hv_do_rep_hypercall_ex(), which adds a 'rep_start'
> parameter. This solves the issue, allowing the deposit loop in
> MSHV_ROOT_HVCALL to restart a rep hypercall after depositing pages
> partway through.
>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
In v1 you said you will add a "Fixes" tag. Where is it?
Wei
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox