* Re: [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions
From: Easwar Hariharan @ 2025-09-11 16:32 UTC (permalink / raw)
To: Nuno Das Neves
Cc: linux-hyperv, linux-kernel, prapal, tiala, anirudh, paekkaladevi,
easwar.hariharan, kys, haiyangz, wei.liu, decui, Jinank Jain
In-Reply-To: <1757546089-2002-6-git-send-email-nunodasneves@linux.microsoft.com>
On 9/10/2025 4:14 PM, Nuno Das Neves wrote:
> From: Jinank Jain <jinankjain@linux.microsoft.com>
>
> Introduce HVCALL_MAP_STATS_PAGE2 which provides a map location (GPFN)
> to map the stats to. This hypercall is required for L1VH partitions,
> depending on the hypervisor version. This uses the same check as the
> state page map location; mshv_use_overlay_gpfn().
>
> Add mshv_map_vp_state_page() helpers to use this new hypercall or the
> old one depending on availability.
>
> For unmapping, the original HVCALL_UNMAP_STATS_PAGE works for both
> cases.
>
> Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
> drivers/hv/mshv_root.h | 10 ++--
> drivers/hv/mshv_root_hv_call.c | 89 ++++++++++++++++++++++++++++++++--
> drivers/hv/mshv_root_main.c | 25 ++++++----
> include/hyperv/hvgdk_mini.h | 1 +
> include/hyperv/hvhdk_mini.h | 7 +++
> 5 files changed, 112 insertions(+), 20 deletions(-)
>
<snip>
> @@ -849,10 +850,13 @@ static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
> };
>
> identity.vp.stats_area_type = HV_STATS_AREA_SELF;
> - hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
> + hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
> +
> + if (stats_pages[HV_STATS_AREA_PARENT] == stats_pages[HV_STATS_AREA_SELF])
> + return;
Nit, without patch 2, this hunk is a no-op. Despite that, looks good to me.
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
>
> identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
> - hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
> + hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
> }
<snip>
^ permalink raw reply
* Re: [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall
From: Easwar Hariharan @ 2025-09-11 16:21 UTC (permalink / raw)
To: Nuno Das Neves
Cc: linux-hyperv, linux-kernel, prapal, tiala, anirudh, paekkaladevi,
easwar.hariharan, kys, haiyangz, wei.liu, decui
In-Reply-To: <1757546089-2002-3-git-send-email-nunodasneves@linux.microsoft.com>
On 9/10/2025 4:14 PM, Nuno Das Neves wrote:
> From: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
>
> This hypercall can be used to fetch extended properties of a
> partition. Extended properties are properties with values larger than
> a u64. Some of these also need additional input arguments.
>
> Add helper function for using the hypercall in the mshv_root driver.
>
> Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
> Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
> ---
> drivers/hv/mshv_root.h | 2 ++
> drivers/hv/mshv_root_hv_call.c | 31 ++++++++++++++++++++++++++
> include/hyperv/hvgdk_mini.h | 1 +
> include/hyperv/hvhdk.h | 40 ++++++++++++++++++++++++++++++++++
> include/hyperv/hvhdk_mini.h | 26 ++++++++++++++++++++++
> 5 files changed, 100 insertions(+)
<snip>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
^ permalink raw reply
* Re: [PATCH 00/14] paravirt: cleanup and reorg
From: Jürgen Groß @ 2025-09-11 8:00 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linux-kernel, x86, linux-hyperv, virtualization, loongarch,
linuxppc-dev, linux-riscv, kvm, Andy Lutomirski, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Will Deacon,
Boqun Feng, Waiman Long, Jiri Kosina, Josh Poimboeuf, Pawan Gupta,
Boris Ostrovsky, xen-devel, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, Russell King,
Catalin Marinas, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Valentin Schneider, linux-arm-kernel,
Paolo Bonzini, Vitaly Kuznetsov, Stefano Stabellini,
Oleksandr Tyshchenko, Daniel Lezcano
In-Reply-To: <20250911074817.GX3245006@noisy.programming.kicks-ass.net>
[-- Attachment #1.1.1: Type: text/plain, Size: 3443 bytes --]
On 11.09.25 09:48, Peter Zijlstra wrote:
> On Thu, Sep 11, 2025 at 08:34:19AM +0200, Juergen Gross wrote:
>> Some cleanups and reorg of paravirt code and headers:
>>
>> - The first 2 patches should be not controversial at all, as they
>> remove just some no longer needed #include and struct forward
>> declarations.
>>
>> - The 3rd patch is removing CONFIG_PARAVIRT_DEBUG, which IMO has
>> no real value, as it just changes a crash to a BUG() (the stack
>> trace will basically be the same). As the maintainer of the main
>> paravirt user (Xen) I have never seen this crash/BUG() to happen.
>>
>> - The 4th patch is just a movement of code.
>>
>> - I don't know for what reason asm/paravirt_api_clock.h was added,
>> as all archs supporting it do it exactly in the same way. Patch
>> 5 is removing it.
>>
>> - Patches 6-12 are streamlining the paravirt clock interfaces by
>> using a common implementation across architectures where possible
>> and by moving the related code into common sched code, as this is
>> where it should live.
>>
>> - Patches 13+14 are more like RFC material: patch 13 is doing some
>> preparation work to enable patch 14 to move all spinlock related
>> paravirt functions into qspinlock.h. If this approach is accepted,
>> I'd like to continue with this work by moving most (or all?)
>> paravirt functions from paravirt.h into the headers where their
>> native counterparts are defined. This is meant to keep the native
>> and paravirt function definitions together in one place and
>> hopefully to be able to reduce the include hell with paravirt.
>>
>> Juergen Gross (14):
>> x86/paravirt: remove not needed includes of paravirt.h
>> x86/paravirt: remove some unneeded struct declarations
>> x86/paravirt: remove PARAVIRT_DEBUG config option
>> x86/paravirt: move thunk macros to paravirt_types.h
>> paravirt: remove asm/paravirt_api_clock.h
>> sched: move clock related paravirt code to kernel/sched
>> arm/paravirt: use common code for paravirt_steal_clock()
>> arm64/paravirt: use common code for paravirt_steal_clock()
>> loongarch/paravirt: use common code for paravirt_steal_clock()
>> riscv/paravirt: use common code for paravirt_steal_clock()
>> x86/paravirt: use common code for paravirt_steal_clock()
>> x86/paravirt: move paravirt_sched_clock() related code into tsc.c
>> x86/paravirt: allow pv-calls outside paravirt.h
>> x86/pvlocks: move paravirt spinlock functions into qspinlock.h
>
> With the note that tip typically likes a capital after the prefix, like:
>
> x86/paravirt: Remove unneeded includes of paravirt.h
Noted, thanks.
>
> For 1-12:
>
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>
>
> Now, as to the last two, I'm not sure. Leaking those macros out of PV
> isn't particularly nice, then again, not the end of the world either.
> Just not sure.
Yes, that's why I didn't continue with all of the other potential movement of
paravirt functions. I want some feedback first. :-)
Its a tradeoff between having functions with / without paravirt in one file
against hiding the paravirt stuff from "normal" readers (not writers, as those
probably need to touch the paravirt variant, too).
BTW, I think the macro leaking isn't the main problem. There are other macros
leaking already.
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply
* Re: [PATCH 00/14] paravirt: cleanup and reorg
From: Peter Zijlstra @ 2025-09-11 7:48 UTC (permalink / raw)
To: Juergen Gross
Cc: linux-kernel, x86, linux-hyperv, virtualization, loongarch,
linuxppc-dev, linux-riscv, kvm, Andy Lutomirski, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Will Deacon,
Boqun Feng, Waiman Long, Jiri Kosina, Josh Poimboeuf, Pawan Gupta,
Boris Ostrovsky, xen-devel, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, Russell King,
Catalin Marinas, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Valentin Schneider, linux-arm-kernel,
Paolo Bonzini, Vitaly Kuznetsov, Stefano Stabellini,
Oleksandr Tyshchenko, Daniel Lezcano
In-Reply-To: <20250911063433.13783-1-jgross@suse.com>
On Thu, Sep 11, 2025 at 08:34:19AM +0200, Juergen Gross wrote:
> Some cleanups and reorg of paravirt code and headers:
>
> - The first 2 patches should be not controversial at all, as they
> remove just some no longer needed #include and struct forward
> declarations.
>
> - The 3rd patch is removing CONFIG_PARAVIRT_DEBUG, which IMO has
> no real value, as it just changes a crash to a BUG() (the stack
> trace will basically be the same). As the maintainer of the main
> paravirt user (Xen) I have never seen this crash/BUG() to happen.
>
> - The 4th patch is just a movement of code.
>
> - I don't know for what reason asm/paravirt_api_clock.h was added,
> as all archs supporting it do it exactly in the same way. Patch
> 5 is removing it.
>
> - Patches 6-12 are streamlining the paravirt clock interfaces by
> using a common implementation across architectures where possible
> and by moving the related code into common sched code, as this is
> where it should live.
>
> - Patches 13+14 are more like RFC material: patch 13 is doing some
> preparation work to enable patch 14 to move all spinlock related
> paravirt functions into qspinlock.h. If this approach is accepted,
> I'd like to continue with this work by moving most (or all?)
> paravirt functions from paravirt.h into the headers where their
> native counterparts are defined. This is meant to keep the native
> and paravirt function definitions together in one place and
> hopefully to be able to reduce the include hell with paravirt.
>
> Juergen Gross (14):
> x86/paravirt: remove not needed includes of paravirt.h
> x86/paravirt: remove some unneeded struct declarations
> x86/paravirt: remove PARAVIRT_DEBUG config option
> x86/paravirt: move thunk macros to paravirt_types.h
> paravirt: remove asm/paravirt_api_clock.h
> sched: move clock related paravirt code to kernel/sched
> arm/paravirt: use common code for paravirt_steal_clock()
> arm64/paravirt: use common code for paravirt_steal_clock()
> loongarch/paravirt: use common code for paravirt_steal_clock()
> riscv/paravirt: use common code for paravirt_steal_clock()
> x86/paravirt: use common code for paravirt_steal_clock()
> x86/paravirt: move paravirt_sched_clock() related code into tsc.c
> x86/paravirt: allow pv-calls outside paravirt.h
> x86/pvlocks: move paravirt spinlock functions into qspinlock.h
With the note that tip typically likes a capital after the prefix, like:
x86/paravirt: Remove unneeded includes of paravirt.h
For 1-12:
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Now, as to the last two, I'm not sure. Leaking those macros out of PV
isn't particularly nice, then again, not the end of the world either.
Just not sure.
^ permalink raw reply
* [PATCH 12/14] x86/paravirt: move paravirt_sched_clock() related code into tsc.c
From: Juergen Gross @ 2025-09-11 6:34 UTC (permalink / raw)
To: linux-kernel, x86, virtualization, kvm, linux-hyperv
Cc: Juergen Gross, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
Paolo Bonzini, Vitaly Kuznetsov, Boris Ostrovsky,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Daniel Lezcano, xen-devel
In-Reply-To: <20250911063433.13783-1-jgross@suse.com>
The only user of paravirt_sched_clock() is in tsc.c, so move the code
from paravirt.c and paravirt.h to tsc.c.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
arch/x86/include/asm/paravirt.h | 12 ------------
arch/x86/include/asm/timer.h | 1 +
arch/x86/kernel/kvmclock.c | 1 +
arch/x86/kernel/paravirt.c | 7 -------
arch/x86/kernel/tsc.c | 10 +++++++++-
arch/x86/xen/time.c | 1 +
drivers/clocksource/hyperv_timer.c | 2 ++
7 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 37d7494ce146..bd050ceaae00 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -18,20 +18,8 @@ struct mm_struct;
#ifndef __ASSEMBLER__
#include <linux/types.h>
#include <linux/cpumask.h>
-#include <linux/static_call_types.h>
#include <asm/frame.h>
-u64 dummy_sched_clock(void);
-
-DECLARE_STATIC_CALL(pv_sched_clock, dummy_sched_clock);
-
-void paravirt_set_sched_clock(u64 (*func)(void));
-
-static __always_inline u64 paravirt_sched_clock(void)
-{
- return static_call(pv_sched_clock)();
-}
-
__visible void __native_queued_spin_unlock(struct qspinlock *lock);
bool pv_is_native_spin_unlock(void);
__visible bool __native_vcpu_is_preempted(long cpu);
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h
index 23baf8c9b34c..fda18bcb19b4 100644
--- a/arch/x86/include/asm/timer.h
+++ b/arch/x86/include/asm/timer.h
@@ -12,6 +12,7 @@ extern void recalibrate_cpu_khz(void);
extern int no_timer_check;
extern bool using_native_sched_clock(void);
+void paravirt_set_sched_clock(u64 (*func)(void));
/*
* We use the full linear equation: f(x) = a + b*x, in order to allow
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index ca0a49eeac4a..b5991d53fc0e 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -19,6 +19,7 @@
#include <linux/cc_platform.h>
#include <asm/hypervisor.h>
+#include <asm/timer.h>
#include <asm/x86_init.h>
#include <asm/kvmclock.h>
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 42991d471bf3..4e37db8073f9 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -60,13 +60,6 @@ void __init native_pv_lock_init(void)
static_branch_enable(&virt_spin_lock_key);
}
-DEFINE_STATIC_CALL(pv_sched_clock, native_sched_clock);
-
-void paravirt_set_sched_clock(u64 (*func)(void))
-{
- static_call_update(pv_sched_clock, func);
-}
-
static noinstr void pv_native_safe_halt(void)
{
native_safe_halt();
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 87e749106dda..554b54783a04 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -266,19 +266,27 @@ u64 native_sched_clock_from_tsc(u64 tsc)
/* We need to define a real function for sched_clock, to override the
weak default version */
#ifdef CONFIG_PARAVIRT
+DEFINE_STATIC_CALL(pv_sched_clock, native_sched_clock);
+
noinstr u64 sched_clock_noinstr(void)
{
- return paravirt_sched_clock();
+ return static_call(pv_sched_clock)();
}
bool using_native_sched_clock(void)
{
return static_call_query(pv_sched_clock) == native_sched_clock;
}
+
+void paravirt_set_sched_clock(u64 (*func)(void))
+{
+ static_call_update(pv_sched_clock, func);
+}
#else
u64 sched_clock_noinstr(void) __attribute__((alias("native_sched_clock")));
bool using_native_sched_clock(void) { return true; }
+void paravirt_set_sched_clock(u64 (*func)(void)) { }
#endif
notrace u64 sched_clock(void)
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index e4754b2fa900..6f9f665bb7ae 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -19,6 +19,7 @@
#include <linux/sched/cputime.h>
#include <asm/pvclock.h>
+#include <asm/timer.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/cpuid.h>
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 2edc13ca184e..6397a7ba4a98 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -535,6 +535,8 @@ static __always_inline void hv_setup_sched_clock(void *sched_clock)
sched_clock_register(sched_clock, 64, NSEC_PER_SEC);
}
#elif defined CONFIG_PARAVIRT
+#include <asm/timer.h>
+
static __always_inline void hv_setup_sched_clock(void *sched_clock)
{
/* We're on x86/x64 *and* using PV ops */
--
2.51.0
^ permalink raw reply related
* [PATCH 01/14] x86/paravirt: remove not needed includes of paravirt.h
From: Juergen Gross @ 2025-09-11 6:34 UTC (permalink / raw)
To: linux-kernel, x86, linux-hyperv
Cc: Juergen Gross, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Peter Zijlstra, Will Deacon,
Boqun Feng, Waiman Long, Jiri Kosina, Josh Poimboeuf, Pawan Gupta,
Boris Ostrovsky, xen-devel
In-Reply-To: <20250911063433.13783-1-jgross@suse.com>
In some places asm/paravirt.h is included without really being needed.
Remove the related #include statements.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
arch/x86/entry/entry_64.S | 1 -
arch/x86/entry/vsyscall/vsyscall_64.c | 1 -
arch/x86/hyperv/hv_spinlock.c | 1 -
arch/x86/include/asm/apic.h | 4 ----
arch/x86/include/asm/highmem.h | 1 -
arch/x86/include/asm/mmu_context.h | 1 -
arch/x86/include/asm/mshyperv.h | 1 -
arch/x86/include/asm/pgtable_32.h | 1 -
arch/x86/include/asm/spinlock.h | 1 -
arch/x86/include/asm/tlbflush.h | 4 ----
arch/x86/kernel/apm_32.c | 1 -
arch/x86/kernel/callthunks.c | 1 -
arch/x86/kernel/cpu/bugs.c | 1 -
arch/x86/kernel/vsmp_64.c | 1 -
arch/x86/kernel/x86_init.c | 1 -
arch/x86/lib/cache-smp.c | 1 -
arch/x86/mm/init.c | 1 -
arch/x86/xen/spinlock.c | 1 -
18 files changed, 24 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index ed04a968cc7d..7a82305405af 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -30,7 +30,6 @@
#include <asm/hw_irq.h>
#include <asm/page_types.h>
#include <asm/irqflags.h>
-#include <asm/paravirt.h>
#include <asm/percpu.h>
#include <asm/asm.h>
#include <asm/smap.h>
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index c9103a6fa06e..53e50b506471 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -37,7 +37,6 @@
#include <asm/unistd.h>
#include <asm/fixmap.h>
#include <asm/traps.h>
-#include <asm/paravirt.h>
#define CREATE_TRACE_POINTS
#include "vsyscall_trace.h"
diff --git a/arch/x86/hyperv/hv_spinlock.c b/arch/x86/hyperv/hv_spinlock.c
index 81b006601370..2a3c2afb0154 100644
--- a/arch/x86/hyperv/hv_spinlock.c
+++ b/arch/x86/hyperv/hv_spinlock.c
@@ -13,7 +13,6 @@
#include <linux/spinlock.h>
#include <asm/mshyperv.h>
-#include <asm/paravirt.h>
#include <asm/apic.h>
#include <asm/msr.h>
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 07ba4935e873..e1de090e51dd 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -90,10 +90,6 @@ static inline bool apic_from_smp_config(void)
/*
* Basic functions accessing APICs.
*/
-#ifdef CONFIG_PARAVIRT
-#include <asm/paravirt.h>
-#endif
-
static inline void native_apic_mem_write(u32 reg, u32 v)
{
volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h
index 585bdadba47d..decfaaf52326 100644
--- a/arch/x86/include/asm/highmem.h
+++ b/arch/x86/include/asm/highmem.h
@@ -24,7 +24,6 @@
#include <linux/interrupt.h>
#include <linux/threads.h>
#include <asm/tlbflush.h>
-#include <asm/paravirt.h>
#include <asm/fixmap.h>
#include <asm/pgtable_areas.h>
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 73bf3b1b44e8..ee15657d25b3 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -9,7 +9,6 @@
#include <trace/events/tlb.h>
#include <asm/tlbflush.h>
-#include <asm/paravirt.h>
#include <asm/debugreg.h>
#include <asm/gsseg.h>
#include <asm/desc.h>
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index abc4659f5809..a9ab46fcb6a1 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -7,7 +7,6 @@
#include <linux/msi.h>
#include <linux/io.h>
#include <asm/nospec-branch.h>
-#include <asm/paravirt.h>
#include <asm/msr.h>
#include <hyperv/hvhdk.h>
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index b612cc57a4d3..acea0cfa2460 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -16,7 +16,6 @@
#ifndef __ASSEMBLER__
#include <asm/processor.h>
#include <linux/threads.h>
-#include <asm/paravirt.h>
#include <linux/bitops.h>
#include <linux/list.h>
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index 5b6bc7016c22..934632b78d09 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -7,7 +7,6 @@
#include <asm/page.h>
#include <asm/processor.h>
#include <linux/compiler.h>
-#include <asm/paravirt.h>
#include <asm/bitops.h>
/*
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 00daedfefc1b..238a6b807da5 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -300,10 +300,6 @@ static inline void mm_clear_asid_transition(struct mm_struct *mm) { }
static inline bool mm_in_asid_transition(struct mm_struct *mm) { return false; }
#endif /* CONFIG_BROADCAST_TLB_FLUSH */
-#ifdef CONFIG_PARAVIRT
-#include <asm/paravirt.h>
-#endif
-
#define flush_tlb_mm(mm) \
flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL, true)
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index b37ab1095707..3175d7c134e9 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -229,7 +229,6 @@
#include <linux/uaccess.h>
#include <asm/desc.h>
#include <asm/olpc.h>
-#include <asm/paravirt.h>
#include <asm/reboot.h>
#include <asm/nospec-branch.h>
#include <asm/ibt.h>
diff --git a/arch/x86/kernel/callthunks.c b/arch/x86/kernel/callthunks.c
index a951333c5995..e37728f70322 100644
--- a/arch/x86/kernel/callthunks.c
+++ b/arch/x86/kernel/callthunks.c
@@ -15,7 +15,6 @@
#include <asm/insn.h>
#include <asm/kexec.h>
#include <asm/nospec-branch.h>
-#include <asm/paravirt.h>
#include <asm/sections.h>
#include <asm/switch_to.h>
#include <asm/sync_core.h>
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index af838b8d845c..00ac4a58542a 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -25,7 +25,6 @@
#include <asm/fpu/api.h>
#include <asm/msr.h>
#include <asm/vmx.h>
-#include <asm/paravirt.h>
#include <asm/cpu_device_id.h>
#include <asm/e820/api.h>
#include <asm/hypervisor.h>
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index 73511332bb67..25625e3fc183 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -18,7 +18,6 @@
#include <asm/apic.h>
#include <asm/pci-direct.h>
#include <asm/io.h>
-#include <asm/paravirt.h>
#include <asm/setup.h>
#define TOPOLOGY_REGISTER_OFFSET 0x10
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 0a2bbd674a6d..02ca90378bf9 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -12,7 +12,6 @@
#include <asm/acpi.h>
#include <asm/bios_ebda.h>
-#include <asm/paravirt.h>
#include <asm/pci_x86.h>
#include <asm/mpspec.h>
#include <asm/setup.h>
diff --git a/arch/x86/lib/cache-smp.c b/arch/x86/lib/cache-smp.c
index c5c60d07308c..ae5a5dfd33c7 100644
--- a/arch/x86/lib/cache-smp.c
+++ b/arch/x86/lib/cache-smp.c
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-#include <asm/paravirt.h>
#include <linux/smp.h>
#include <linux/export.h>
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index bb57e93b4caf..f52ebcac50d9 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -27,7 +27,6 @@
#include <asm/pti.h>
#include <asm/text-patching.h>
#include <asm/memtype.h>
-#include <asm/paravirt.h>
#include <asm/mmu_context.h>
/*
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 8e4efe0fb6f9..fe56646d6919 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -8,7 +8,6 @@
#include <linux/slab.h>
#include <linux/atomic.h>
-#include <asm/paravirt.h>
#include <asm/qspinlock.h>
#include <xen/events.h>
--
2.51.0
^ permalink raw reply related
* [PATCH 00/14] paravirt: cleanup and reorg
From: Juergen Gross @ 2025-09-11 6:34 UTC (permalink / raw)
To: linux-kernel, x86, linux-hyperv, virtualization, loongarch,
linuxppc-dev, linux-riscv, kvm
Cc: Juergen Gross, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Peter Zijlstra, Will Deacon,
Boqun Feng, Waiman Long, Jiri Kosina, Josh Poimboeuf, Pawan Gupta,
Boris Ostrovsky, xen-devel, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, Russell King,
Catalin Marinas, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt,
Ben Segall, Mel Gorman, Valentin Schneider, linux-arm-kernel,
Paolo Bonzini, Vitaly Kuznetsov, Stefano Stabellini,
Oleksandr Tyshchenko, Daniel Lezcano
Some cleanups and reorg of paravirt code and headers:
- The first 2 patches should be not controversial at all, as they
remove just some no longer needed #include and struct forward
declarations.
- The 3rd patch is removing CONFIG_PARAVIRT_DEBUG, which IMO has
no real value, as it just changes a crash to a BUG() (the stack
trace will basically be the same). As the maintainer of the main
paravirt user (Xen) I have never seen this crash/BUG() to happen.
- The 4th patch is just a movement of code.
- I don't know for what reason asm/paravirt_api_clock.h was added,
as all archs supporting it do it exactly in the same way. Patch
5 is removing it.
- Patches 6-12 are streamlining the paravirt clock interfaces by
using a common implementation across architectures where possible
and by moving the related code into common sched code, as this is
where it should live.
- Patches 13+14 are more like RFC material: patch 13 is doing some
preparation work to enable patch 14 to move all spinlock related
paravirt functions into qspinlock.h. If this approach is accepted,
I'd like to continue with this work by moving most (or all?)
paravirt functions from paravirt.h into the headers where their
native counterparts are defined. This is meant to keep the native
and paravirt function definitions together in one place and
hopefully to be able to reduce the include hell with paravirt.
Juergen Gross (14):
x86/paravirt: remove not needed includes of paravirt.h
x86/paravirt: remove some unneeded struct declarations
x86/paravirt: remove PARAVIRT_DEBUG config option
x86/paravirt: move thunk macros to paravirt_types.h
paravirt: remove asm/paravirt_api_clock.h
sched: move clock related paravirt code to kernel/sched
arm/paravirt: use common code for paravirt_steal_clock()
arm64/paravirt: use common code for paravirt_steal_clock()
loongarch/paravirt: use common code for paravirt_steal_clock()
riscv/paravirt: use common code for paravirt_steal_clock()
x86/paravirt: use common code for paravirt_steal_clock()
x86/paravirt: move paravirt_sched_clock() related code into tsc.c
x86/paravirt: allow pv-calls outside paravirt.h
x86/pvlocks: move paravirt spinlock functions into qspinlock.h
arch/Kconfig | 3 +
arch/arm/Kconfig | 1 +
arch/arm/include/asm/paravirt.h | 22 ---
arch/arm/include/asm/paravirt_api_clock.h | 1 -
arch/arm/kernel/Makefile | 1 -
arch/arm/kernel/paravirt.c | 23 ---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/paravirt.h | 14 --
arch/arm64/include/asm/paravirt_api_clock.h | 1 -
arch/arm64/kernel/paravirt.c | 11 +-
arch/loongarch/Kconfig | 1 +
arch/loongarch/include/asm/paravirt.h | 13 --
.../include/asm/paravirt_api_clock.h | 1 -
arch/loongarch/kernel/paravirt.c | 10 +-
arch/powerpc/include/asm/paravirt.h | 3 -
arch/powerpc/include/asm/paravirt_api_clock.h | 2 -
arch/powerpc/platforms/pseries/setup.c | 4 +-
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/paravirt.h | 14 --
arch/riscv/include/asm/paravirt_api_clock.h | 1 -
arch/riscv/kernel/paravirt.c | 11 +-
arch/x86/Kconfig | 8 +-
arch/x86/entry/entry_64.S | 1 -
arch/x86/entry/vsyscall/vsyscall_64.c | 1 -
arch/x86/hyperv/hv_spinlock.c | 1 -
arch/x86/include/asm/apic.h | 4 -
arch/x86/include/asm/highmem.h | 1 -
arch/x86/include/asm/mmu_context.h | 1 -
arch/x86/include/asm/mshyperv.h | 1 -
arch/x86/include/asm/paravirt.h | 166 ------------------
arch/x86/include/asm/paravirt_api_clock.h | 1 -
arch/x86/include/asm/paravirt_types.h | 82 +++++++--
arch/x86/include/asm/pgtable_32.h | 1 -
arch/x86/include/asm/qspinlock.h | 49 +++++-
arch/x86/include/asm/spinlock.h | 1 -
arch/x86/include/asm/timer.h | 1 +
arch/x86/include/asm/tlbflush.h | 4 -
arch/x86/kernel/apm_32.c | 1 -
arch/x86/kernel/callthunks.c | 1 -
arch/x86/kernel/cpu/bugs.c | 1 -
arch/x86/kernel/cpu/vmware.c | 1 +
arch/x86/kernel/kvm.c | 1 +
arch/x86/kernel/kvmclock.c | 1 +
arch/x86/kernel/paravirt.c | 16 --
arch/x86/kernel/tsc.c | 10 +-
arch/x86/kernel/vsmp_64.c | 1 -
arch/x86/kernel/x86_init.c | 1 -
arch/x86/lib/cache-smp.c | 1 -
arch/x86/mm/init.c | 1 -
arch/x86/xen/spinlock.c | 1 -
arch/x86/xen/time.c | 2 +
drivers/clocksource/hyperv_timer.c | 2 +
drivers/xen/time.c | 2 +-
include/linux/sched/cputime.h | 18 ++
kernel/sched/core.c | 5 +
kernel/sched/cputime.c | 13 ++
kernel/sched/sched.h | 3 +-
57 files changed, 182 insertions(+), 362 deletions(-)
delete mode 100644 arch/arm/include/asm/paravirt.h
delete mode 100644 arch/arm/include/asm/paravirt_api_clock.h
delete mode 100644 arch/arm/kernel/paravirt.c
delete mode 100644 arch/arm64/include/asm/paravirt_api_clock.h
delete mode 100644 arch/loongarch/include/asm/paravirt_api_clock.h
delete mode 100644 arch/powerpc/include/asm/paravirt_api_clock.h
delete mode 100644 arch/riscv/include/asm/paravirt_api_clock.h
delete mode 100644 arch/x86/include/asm/paravirt_api_clock.h
--
2.51.0
^ permalink raw reply
* Re: [PATCH net v2] net/mlx5: Not returning mlx5_link_info table when speed is unknown
From: Tariq Toukan @ 2025-09-11 6:22 UTC (permalink / raw)
To: Li Tian, netdev, linux-hyperv
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Haiyang Zhang, Benjamin Poirier, Vitaly Kuznetsov,
Carolina Jubran, Shahar Shitrit
In-Reply-To: <20250910003732.5973-1-litian@redhat.com>
On 10/09/2025 3:37, Li Tian wrote:
> Because mlx5e_link_info and mlx5e_ext_link_info have holes
> e.g. Azure mlx5 reports PTYS 19. Do not return it unless speed
> is retrieved successfully.
>
> Fixes: 65a5d35571849 ("net/mlx5: Refactor link speed handling with mlx5_link_info struct")
> Suggested-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> Signed-off-by: Li Tian <litian@redhat.com>
> ---
> v2:
> - Fix indentation and spacing only.
> v1: https://lore.kernel.org/netdev/20250908085313.18768-1-litian@redhat.com
> ---
> drivers/net/ethernet/mellanox/mlx5/core/port.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
> index 2d7adf7444ba..aa9f2b0a77d3 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
> @@ -1170,7 +1170,11 @@ const struct mlx5_link_info *mlx5_port_ptys2info(struct mlx5_core_dev *mdev,
> mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size,
> force_legacy);
> i = find_first_bit(&temp, max_size);
> - if (i < max_size)
> +
> + /* mlx5e_link_info has holes. Check speed
> + * is not zero as indication of one.
> + */
> + if (i < max_size && table[i].speed)
> return &table[i];
>
> return NULL;
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Thanks.
^ permalink raw reply
* Re: [PATCH v3] net: mana: Remove redundant netdev_lock_ops_to_full() calls
From: patchwork-bot+netdevbpf @ 2025-09-11 1:10 UTC (permalink / raw)
To: Saurabh Sengar
Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
kuba, pabeni, shradhagupta, ernis, dipayanroy, shirazsaleem,
linux-hyperv, netdev, linux-kernel, ssengar
In-Reply-To: <1757393830-20837-1-git-send-email-ssengar@linux.microsoft.com>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 8 Sep 2025 21:57:10 -0700 you wrote:
> NET_SHAPER is always selected for MANA driver. When NET_SHAPER is enabled,
> netdev_lock_ops_to_full() reduces effectively to only an assert for lock,
> which is always held in the path when NET_SHAPER is enabled.
>
> Remove the redundant netdev_lock_ops_to_full() call.
>
> Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
>
> [...]
Here is the summary with links:
- [v3] net: mana: Remove redundant netdev_lock_ops_to_full() calls
https://git.kernel.org/netdev/net-next/c/38611e5adae3
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
anirudh, paekkaladevi
Cc: kys, haiyangz, wei.liu, decui, Jinank Jain, Nuno Das Neves
In-Reply-To: <1757546089-2002-1-git-send-email-nunodasneves@linux.microsoft.com>
From: Jinank Jain <jinankjain@linux.microsoft.com>
Introduce HVCALL_MAP_STATS_PAGE2 which provides a map location (GPFN)
to map the stats to. This hypercall is required for L1VH partitions,
depending on the hypervisor version. This uses the same check as the
state page map location; mshv_use_overlay_gpfn().
Add mshv_map_vp_state_page() helpers to use this new hypercall or the
old one depending on availability.
For unmapping, the original HVCALL_UNMAP_STATS_PAGE works for both
cases.
Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
---
drivers/hv/mshv_root.h | 10 ++--
drivers/hv/mshv_root_hv_call.c | 89 ++++++++++++++++++++++++++++++++--
drivers/hv/mshv_root_main.c | 25 ++++++----
include/hyperv/hvgdk_mini.h | 1 +
include/hyperv/hvhdk_mini.h | 7 +++
5 files changed, 112 insertions(+), 20 deletions(-)
diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index d7c9520ef788..d16a020ae0ee 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -297,11 +297,11 @@ int hv_call_connect_port(u64 port_partition_id, union hv_port_id port_id,
int hv_call_disconnect_port(u64 connection_partition_id,
union hv_connection_id connection_id);
int hv_call_notify_port_ring_empty(u32 sint_index);
-int hv_call_map_stat_page(enum hv_stats_object_type type,
- const union hv_stats_object_identity *identity,
- void **addr);
-int hv_call_unmap_stat_page(enum hv_stats_object_type type,
- const union hv_stats_object_identity *identity);
+int hv_map_stats_page(enum hv_stats_object_type type,
+ const union hv_stats_object_identity *identity,
+ void **addr);
+int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr,
+ const union hv_stats_object_identity *identity);
int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
u64 page_struct_count, u32 host_access,
u32 flags, u8 acquire);
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index 1132ba7b2399..a8cb91ce11cc 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -804,9 +804,47 @@ hv_call_notify_port_ring_empty(u32 sint_index)
return hv_result_to_errno(status);
}
-int hv_call_map_stat_page(enum hv_stats_object_type type,
- const union hv_stats_object_identity *identity,
- void **addr)
+static int hv_call_map_stats_page2(enum hv_stats_object_type type,
+ const union hv_stats_object_identity *identity,
+ u64 map_location)
+{
+ unsigned long flags;
+ struct hv_input_map_stats_page2 *input;
+ u64 status;
+ int ret;
+
+ if (!map_location || !mshv_use_overlay_gpfn())
+ return -EINVAL;
+
+ do {
+ local_irq_save(flags);
+ input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
+ memset(input, 0, sizeof(*input));
+ input->type = type;
+ input->identity = *identity;
+ input->map_location = map_location;
+
+ status = hv_do_hypercall(HVCALL_MAP_STATS_PAGE2, input, NULL);
+
+ local_irq_restore(flags);
+ if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
+ if (hv_result_success(status))
+ break;
+ hv_status_debug(status, "\n");
+ return hv_result_to_errno(status);
+ }
+
+ ret = hv_call_deposit_pages(NUMA_NO_NODE,
+ hv_current_partition_id, 1);
+ } while (!ret);
+
+ return ret;
+}
+
+static int hv_call_map_stats_page(enum hv_stats_object_type type,
+ const union hv_stats_object_identity *identity,
+ void **addr)
{
unsigned long flags;
struct hv_input_map_stats_page *input;
@@ -845,8 +883,36 @@ int hv_call_map_stat_page(enum hv_stats_object_type type,
return ret;
}
-int hv_call_unmap_stat_page(enum hv_stats_object_type type,
- const union hv_stats_object_identity *identity)
+int hv_map_stats_page(enum hv_stats_object_type type,
+ const union hv_stats_object_identity *identity,
+ void **addr)
+{
+ int ret;
+ struct page *allocated_page = NULL;
+
+ if (!addr)
+ return -EINVAL;
+
+ if (mshv_use_overlay_gpfn()) {
+ allocated_page = alloc_page(GFP_KERNEL);
+ if (!allocated_page)
+ return -ENOMEM;
+
+ ret = hv_call_map_stats_page2(type, identity,
+ page_to_pfn(allocated_page));
+ *addr = page_address(allocated_page);
+ } else {
+ ret = hv_call_map_stats_page(type, identity, addr);
+ }
+
+ if (ret && allocated_page)
+ __free_page(allocated_page);
+
+ return ret;
+}
+
+static int hv_call_unmap_stats_page(enum hv_stats_object_type type,
+ const union hv_stats_object_identity *identity)
{
unsigned long flags;
struct hv_input_unmap_stats_page *input;
@@ -865,6 +931,19 @@ int hv_call_unmap_stat_page(enum hv_stats_object_type type,
return hv_result_to_errno(status);
}
+int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr,
+ const union hv_stats_object_identity *identity)
+{
+ int ret;
+
+ ret = hv_call_unmap_stats_page(type, identity);
+
+ if (mshv_use_overlay_gpfn() && page_addr)
+ __free_page(virt_to_page(page_addr));
+
+ return ret;
+}
+
int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
u64 page_struct_count, u32 host_access,
u32 flags, u8 acquire)
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 7352c4f9652e..27fcf8a13faa 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -841,7 +841,8 @@ mshv_vp_release(struct inode *inode, struct file *filp)
return 0;
}
-static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
+static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index,
+ void *stats_pages[])
{
union hv_stats_object_identity identity = {
.vp.partition_id = partition_id,
@@ -849,10 +850,13 @@ static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
};
identity.vp.stats_area_type = HV_STATS_AREA_SELF;
- hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
+ hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
+
+ if (stats_pages[HV_STATS_AREA_PARENT] == stats_pages[HV_STATS_AREA_SELF])
+ return;
identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
- hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
+ hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
}
static int mshv_vp_stats_map(u64 partition_id, u32 vp_index,
@@ -865,14 +869,14 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp_index,
int err;
identity.vp.stats_area_type = HV_STATS_AREA_SELF;
- err = hv_call_map_stat_page(HV_STATS_OBJECT_VP, &identity,
- &stats_pages[HV_STATS_AREA_SELF]);
+ err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity,
+ &stats_pages[HV_STATS_AREA_SELF]);
if (err)
return err;
identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
- err = hv_call_map_stat_page(HV_STATS_OBJECT_VP, &identity,
- &stats_pages[HV_STATS_AREA_PARENT]);
+ err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity,
+ &stats_pages[HV_STATS_AREA_PARENT]);
if (err)
goto unmap_self;
@@ -880,7 +884,7 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp_index,
unmap_self:
identity.vp.stats_area_type = HV_STATS_AREA_SELF;
- hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
+ hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
return err;
}
@@ -988,7 +992,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
kfree(vp);
unmap_stats_pages:
if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
- mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
+ mshv_vp_stats_unmap(partition->pt_id, args.vp_index, stats_pages);
unmap_ghcb_page:
if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
@@ -1740,7 +1744,8 @@ static void destroy_partition(struct mshv_partition *partition)
continue;
if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
- mshv_vp_stats_unmap(partition->pt_id, vp->vp_index);
+ mshv_vp_stats_unmap(partition->pt_id, vp->vp_index,
+ (void **)vp->vp_stats_pages);
if (vp->vp_register_page) {
(void)hv_unmap_vp_state_page(partition->pt_id,
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index ff4325fb623a..f66565106d21 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -493,6 +493,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_PARTITION_PROPERTY_EX 0x0101
#define HVCALL_MMIO_READ 0x0106
#define HVCALL_MMIO_WRITE 0x0107
+#define HVCALL_MAP_STATS_PAGE2 0x0131
/* HV_HYPERCALL_INPUT */
#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index bf2ce27dfcc5..064bf735cab6 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -177,6 +177,13 @@ struct hv_input_map_stats_page {
union hv_stats_object_identity identity;
} __packed;
+struct hv_input_map_stats_page2 {
+ u32 type; /* enum hv_stats_object_type */
+ u32 padding;
+ union hv_stats_object_identity identity;
+ u64 map_location;
+} __packed;
+
struct hv_output_map_stats_page {
u64 map_location;
} __packed;
--
2.34.1
^ permalink raw reply related
* [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
anirudh, paekkaladevi
Cc: kys, haiyangz, wei.liu, decui, Jinank Jain, Nuno Das Neves
In-Reply-To: <1757546089-2002-1-git-send-email-nunodasneves@linux.microsoft.com>
From: Jinank Jain <jinankjain@linux.microsoft.com>
Introduce mshv_use_overlay_gpfn() to check if a page needs to be
allocated and passed to the hypervisor to map VP state pages. This is
only needed on L1VH, and only on some (newer) versions of the
hypervisor, hence the need to check vmm_capabilities.
Introduce functions hv_map/unmap_vp_state_page() to handle the
allocation and freeing.
Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
---
drivers/hv/mshv_root.h | 11 +++---
drivers/hv/mshv_root_hv_call.c | 61 +++++++++++++++++++++++++---
drivers/hv/mshv_root_main.c | 72 +++++++++++++++++-----------------
3 files changed, 96 insertions(+), 48 deletions(-)
diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index 0cb1e2589fe1..d7c9520ef788 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -279,11 +279,12 @@ int hv_call_set_vp_state(u32 vp_index, u64 partition_id,
/* Choose between pages and bytes */
struct hv_vp_state_data state_data, u64 page_count,
struct page **pages, u32 num_bytes, u8 *bytes);
-int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
- union hv_input_vtl input_vtl,
- struct page **state_page);
-int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
- union hv_input_vtl input_vtl);
+int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+ union hv_input_vtl input_vtl,
+ struct page **state_page);
+int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+ void *page_addr,
+ union hv_input_vtl input_vtl);
int hv_call_create_port(u64 port_partition_id, union hv_port_id port_id,
u64 connection_partition_id, struct hv_port_info *port_info,
u8 port_vtl, u8 min_connection_vtl, int node);
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index 3fd3cce23f69..1132ba7b2399 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -526,9 +526,9 @@ int hv_call_set_vp_state(u32 vp_index, u64 partition_id,
return ret;
}
-int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
- union hv_input_vtl input_vtl,
- struct page **state_page)
+static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+ union hv_input_vtl input_vtl,
+ struct page **state_page)
{
struct hv_input_map_vp_state_page *input;
struct hv_output_map_vp_state_page *output;
@@ -547,7 +547,14 @@ int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
input->type = type;
input->input_vtl = input_vtl;
- status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, output);
+ if (*state_page) {
+ input->flags.map_location_provided = 1;
+ input->requested_map_location =
+ page_to_pfn(*state_page);
+ }
+
+ status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input,
+ output);
if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
if (hv_result_success(status))
@@ -565,8 +572,39 @@ int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
return ret;
}
-int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
- union hv_input_vtl input_vtl)
+static bool mshv_use_overlay_gpfn(void)
+{
+ return hv_l1vh_partition() &&
+ mshv_root.vmm_caps.vmm_can_provide_overlay_gpfn;
+}
+
+int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+ union hv_input_vtl input_vtl,
+ struct page **state_page)
+{
+ int ret = 0;
+ struct page *allocated_page = NULL;
+
+ if (mshv_use_overlay_gpfn()) {
+ allocated_page = alloc_page(GFP_KERNEL);
+ if (!allocated_page)
+ return -ENOMEM;
+ *state_page = allocated_page;
+ } else {
+ *state_page = NULL;
+ }
+
+ ret = hv_call_map_vp_state_page(partition_id, vp_index, type, input_vtl,
+ state_page);
+
+ if (ret && allocated_page)
+ __free_page(allocated_page);
+
+ return ret;
+}
+
+static int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+ union hv_input_vtl input_vtl)
{
unsigned long flags;
u64 status;
@@ -590,6 +628,17 @@ int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
return hv_result_to_errno(status);
}
+int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+ void *page_addr, union hv_input_vtl input_vtl)
+{
+ int ret = hv_call_unmap_vp_state_page(partition_id, vp_index, type, input_vtl);
+
+ if (mshv_use_overlay_gpfn() && page_addr)
+ __free_page(virt_to_page(page_addr));
+
+ return ret;
+}
+
int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code,
u64 arg, void *property_value,
size_t property_value_sz)
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index f7738cefbdf3..7352c4f9652e 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -908,28 +908,25 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
if (ret)
return ret;
- ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index,
- HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
- input_vtl_zero,
- &intercept_message_page);
+ ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
+ HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
+ input_vtl_zero, &intercept_message_page);
if (ret)
goto destroy_vp;
if (!mshv_partition_encrypted(partition)) {
- ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index,
- HV_VP_STATE_PAGE_REGISTERS,
- input_vtl_zero,
- ®ister_page);
+ ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
+ HV_VP_STATE_PAGE_REGISTERS,
+ input_vtl_zero, ®ister_page);
if (ret)
goto unmap_intercept_message_page;
}
if (mshv_partition_encrypted(partition) &&
is_ghcb_mapping_available()) {
- ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index,
- HV_VP_STATE_PAGE_GHCB,
- input_vtl_normal,
- &ghcb_page);
+ ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
+ HV_VP_STATE_PAGE_GHCB,
+ input_vtl_normal, &ghcb_page);
if (ret)
goto unmap_register_page;
}
@@ -993,21 +990,19 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
unmap_ghcb_page:
- if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) {
- hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index,
- HV_VP_STATE_PAGE_GHCB,
- input_vtl_normal);
- }
+ if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
+ hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
+ HV_VP_STATE_PAGE_GHCB, vp->vp_ghcb_page,
+ input_vtl_normal);
unmap_register_page:
- if (!mshv_partition_encrypted(partition)) {
- hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index,
- HV_VP_STATE_PAGE_REGISTERS,
- input_vtl_zero);
- }
+ if (!mshv_partition_encrypted(partition))
+ hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
+ HV_VP_STATE_PAGE_REGISTERS,
+ vp->vp_register_page, input_vtl_zero);
unmap_intercept_message_page:
- hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index,
- HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
- input_vtl_zero);
+ hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
+ HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
+ vp->vp_intercept_msg_page, input_vtl_zero);
destroy_vp:
hv_call_delete_vp(partition->pt_id, args.vp_index);
return ret;
@@ -1748,24 +1743,27 @@ static void destroy_partition(struct mshv_partition *partition)
mshv_vp_stats_unmap(partition->pt_id, vp->vp_index);
if (vp->vp_register_page) {
- (void)hv_call_unmap_vp_state_page(partition->pt_id,
- vp->vp_index,
- HV_VP_STATE_PAGE_REGISTERS,
- input_vtl_zero);
+ (void)hv_unmap_vp_state_page(partition->pt_id,
+ vp->vp_index,
+ HV_VP_STATE_PAGE_REGISTERS,
+ vp->vp_register_page,
+ input_vtl_zero);
vp->vp_register_page = NULL;
}
- (void)hv_call_unmap_vp_state_page(partition->pt_id,
- vp->vp_index,
- HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
- input_vtl_zero);
+ (void)hv_unmap_vp_state_page(partition->pt_id,
+ vp->vp_index,
+ HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
+ vp->vp_intercept_msg_page,
+ input_vtl_zero);
vp->vp_intercept_msg_page = NULL;
if (vp->vp_ghcb_page) {
- (void)hv_call_unmap_vp_state_page(partition->pt_id,
- vp->vp_index,
- HV_VP_STATE_PAGE_GHCB,
- input_vtl_normal);
+ (void)hv_unmap_vp_state_page(partition->pt_id,
+ vp->vp_index,
+ HV_VP_STATE_PAGE_GHCB,
+ vp->vp_ghcb_page,
+ input_vtl_normal);
vp->vp_ghcb_page = NULL;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v2 3/5] mshv: Get the vmm capabilities offered by the hypervisor
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
anirudh, paekkaladevi
Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves
In-Reply-To: <1757546089-2002-1-git-send-email-nunodasneves@linux.microsoft.com>
From: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
Some hypervisor APIs are gated by feature bits in the
"vmm capabilities" partition property. Store the capabilities on
mshv_root module init, using HVCALL_GET_PARTITION_PROPERTY_EX.
This is not supported on all hypervisors. In that case, just set the
capabilities to 0 and proceed as normal.
Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
---
drivers/hv/mshv_root.h | 1 +
drivers/hv/mshv_root_main.c | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index 4aeb03bea6b6..0cb1e2589fe1 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -178,6 +178,7 @@ struct mshv_root {
struct hv_synic_pages __percpu *synic_pages;
spinlock_t pt_ht_lock;
DECLARE_HASHTABLE(pt_htable, MSHV_PARTITIONS_HASH_BITS);
+ struct hv_partition_property_vmm_capabilities vmm_caps;
};
/*
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 24df47726363..f7738cefbdf3 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -2201,6 +2201,26 @@ static int __init mshv_root_partition_init(struct device *dev)
return err;
}
+static void mshv_init_vmm_caps(struct device *dev)
+{
+ int ret;
+
+ memset(&mshv_root.vmm_caps, 0, sizeof(mshv_root.vmm_caps));
+ ret = hv_call_get_partition_property_ex(HV_PARTITION_ID_SELF,
+ HV_PARTITION_PROPERTY_VMM_CAPABILITIES,
+ 0, &mshv_root.vmm_caps,
+ sizeof(mshv_root.vmm_caps));
+
+ /*
+ * HVCALL_GET_PARTITION_PROPERTY_EX or HV_PARTITION_PROPERTY_VMM_CAPABILITIES
+ * may not be supported. Leave them as 0 in that case.
+ */
+ if (ret)
+ dev_warn(dev, "Unable to get VMM capabilities\n");
+
+ dev_dbg(dev, "vmm_caps=0x%llx\n", mshv_root.vmm_caps.as_uint64[0]);
+}
+
static int __init mshv_parent_partition_init(void)
{
int ret;
@@ -2253,6 +2273,8 @@ static int __init mshv_parent_partition_init(void)
if (ret)
goto remove_cpu_state;
+ mshv_init_vmm_caps(dev);
+
ret = mshv_irqfd_wq_init();
if (ret)
goto exit_partition;
--
2.34.1
^ permalink raw reply related
* [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
anirudh, paekkaladevi
Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves
In-Reply-To: <1757546089-2002-1-git-send-email-nunodasneves@linux.microsoft.com>
From: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
This hypercall can be used to fetch extended properties of a
partition. Extended properties are properties with values larger than
a u64. Some of these also need additional input arguments.
Add helper function for using the hypercall in the mshv_root driver.
Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
---
drivers/hv/mshv_root.h | 2 ++
drivers/hv/mshv_root_hv_call.c | 31 ++++++++++++++++++++++++++
include/hyperv/hvgdk_mini.h | 1 +
include/hyperv/hvhdk.h | 40 ++++++++++++++++++++++++++++++++++
include/hyperv/hvhdk_mini.h | 26 ++++++++++++++++++++++
5 files changed, 100 insertions(+)
diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index e3931b0f1269..4aeb03bea6b6 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -303,6 +303,8 @@ int hv_call_unmap_stat_page(enum hv_stats_object_type type,
int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
u64 page_struct_count, u32 host_access,
u32 flags, u8 acquire);
+int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code, u64 arg,
+ void *property_value, size_t property_value_sz);
extern struct mshv_root mshv_root;
extern enum hv_scheduler_type hv_scheduler_type;
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index c9c274f29c3c..3fd3cce23f69 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -590,6 +590,37 @@ int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
return hv_result_to_errno(status);
}
+int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code,
+ u64 arg, void *property_value,
+ size_t property_value_sz)
+{
+ u64 status;
+ unsigned long flags;
+ struct hv_input_get_partition_property_ex *input;
+ struct hv_output_get_partition_property_ex *output;
+
+ local_irq_save(flags);
+ input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+ output = *this_cpu_ptr(hyperv_pcpu_output_arg);
+
+ memset(input, 0, sizeof(*input));
+ input->partition_id = partition_id;
+ input->property_code = property_code;
+ input->arg = arg;
+ status = hv_do_hypercall(HVCALL_GET_PARTITION_PROPERTY_EX, input, output);
+
+ if (!hv_result_success(status)) {
+ hv_status_debug(status, "\n");
+ local_irq_restore(flags);
+ return hv_result_to_errno(status);
+ }
+ memcpy(property_value, &output->property_value, property_value_sz);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
int
hv_call_clear_virtual_interrupt(u64 partition_id)
{
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 1be7f6a02304..ff4325fb623a 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -490,6 +490,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_VP_STATE 0x00e3
#define HVCALL_SET_VP_STATE 0x00e4
#define HVCALL_GET_VP_CPUID_VALUES 0x00f4
+#define HVCALL_GET_PARTITION_PROPERTY_EX 0x0101
#define HVCALL_MMIO_READ 0x0106
#define HVCALL_MMIO_WRITE 0x0107
diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
index b4067ada02cf..b91358b9c929 100644
--- a/include/hyperv/hvhdk.h
+++ b/include/hyperv/hvhdk.h
@@ -376,6 +376,46 @@ struct hv_input_set_partition_property {
u64 property_value;
} __packed;
+union hv_partition_property_arg {
+ u64 as_uint64;
+ struct {
+ union {
+ u32 arg;
+ u32 vp_index;
+ };
+ u16 reserved0;
+ u8 reserved1;
+ u8 object_type;
+ };
+} __packed;
+
+struct hv_input_get_partition_property_ex {
+ u64 partition_id;
+ u32 property_code; /* enum hv_partition_property_code */
+ u32 padding;
+ union {
+ union hv_partition_property_arg arg_data;
+ u64 arg;
+ };
+} __packed;
+
+/*
+ * NOTE: Should use hv_input_set_partition_property_ex_header to compute this
+ * size, but hv_input_get_partition_property_ex is identical so it suffices
+ */
+#define HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE \
+ (HV_HYP_PAGE_SIZE - sizeof(struct hv_input_get_partition_property_ex))
+
+union hv_partition_property_ex {
+ u8 buffer[HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE];
+ struct hv_partition_property_vmm_capabilities vmm_capabilities;
+ /* More fields to be filled in when needed */
+} __packed;
+
+struct hv_output_get_partition_property_ex {
+ union hv_partition_property_ex property_value;
+} __packed;
+
enum hv_vp_state_page_type {
HV_VP_STATE_PAGE_REGISTERS = 0,
HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index 858f6a3925b3..bf2ce27dfcc5 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -96,8 +96,34 @@ enum hv_partition_property_code {
HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007,
HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008,
HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009,
+
+ /* Extended properties with larger property values */
+ HV_PARTITION_PROPERTY_VMM_CAPABILITIES = 0x00090007,
};
+#define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT 1
+#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT 59
+
+struct hv_partition_property_vmm_capabilities {
+ u16 bank_count;
+ u16 reserved[3];
+ union {
+ u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
+ struct {
+ u64 map_gpa_preserve_adjustable: 1;
+ u64 vmm_can_provide_overlay_gpfn: 1;
+ u64 vp_affinity_property: 1;
+#if IS_ENABLED(CONFIG_ARM64)
+ u64 vmm_can_provide_gic_overlay_locations: 1;
+#else
+ u64 reservedbit3: 1;
+#endif
+ u64 assignable_synthetic_proc_features: 1;
+ u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
+ } __packed;
+ };
+} __packed;
+
enum hv_snp_status {
HV_SNP_STATUS_NONE = 0,
HV_SNP_STATUS_AVAILABLE = 1,
--
2.34.1
^ permalink raw reply related
* [PATCH v2 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
anirudh, paekkaladevi
Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves
In-Reply-To: <1757546089-2002-1-git-send-email-nunodasneves@linux.microsoft.com>
This mapping is only used for checking if the dispatch thread is
blocked. This is only relevant for the root scheduler, so check the
scheduler type to determine whether to map/unmap these pages, instead of
the current check, which is incorrect.
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
---
drivers/hv/mshv_root_main.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index e3b2bd417c46..24df47726363 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -934,7 +934,11 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
goto unmap_register_page;
}
- if (hv_parent_partition()) {
+ /*
+ * This mapping of the stats page is for detecting if dispatch thread
+ * is blocked - only relevant for root scheduler
+ */
+ if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) {
ret = mshv_vp_stats_map(partition->pt_id, args.vp_index,
stats_pages);
if (ret)
@@ -963,7 +967,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
vp->vp_ghcb_page = page_to_virt(ghcb_page);
- if (hv_parent_partition())
+ if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages));
/*
@@ -986,7 +990,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
free_vp:
kfree(vp);
unmap_stats_pages:
- if (hv_parent_partition())
+ if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
unmap_ghcb_page:
if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) {
@@ -1740,7 +1744,7 @@ static void destroy_partition(struct mshv_partition *partition)
if (!vp)
continue;
- if (hv_parent_partition())
+ if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
mshv_vp_stats_unmap(partition->pt_id, vp->vp_index);
if (vp->vp_register_page) {
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
anirudh, paekkaladevi
Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves
There are some differences in how L1VH partitions must map stats and vp
state pages, some of which are due to differences across hypervisor
versions. Detect and handle these cases.
Patch 1:
Fix for the logic of when to map the vp stats page for the root scheduler.
Patch 2-3:
Add HVCALL_GET_PARTITION_PROPERTY_EX and use it to query "vmm capabilities" on
module init.
Patches 4-5:
Check a feature bit in vmm capabilities, to take a new code path for mapping
stats and vp state pages. In this case, the stats and vp state pages must be
allocated by Linux, and a new hypercall HVCALL_MAP_VP_STATS_PAGE2 must be used
to map the stats page.
---
v2:
- Removed patch falling back to SELF page if PARENT mapping fails [Easwar]
(To be included in a future series)
- Fix formatting of function definitions [Easwar]
- Fix some wording in commit messages [Praveen]
- Proceed with driver init even if getting vmm capabilities fails [Anirudh]
v1:
https://lore.kernel.org/linux-hyperv/1756428230-3599-1-git-send-email-nunodasneves@linux.microsoft.com/T/#t
---
Jinank Jain (2):
mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH
mshv: Introduce new hypercall to map stats page for L1VH partitions
Nuno Das Neves (1):
mshv: Only map vp->vp_stats_pages if on root scheduler
Purna Pavan Chandra Aekkaladevi (2):
mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall
mshv: Get the vmm capabilities offered by the hypervisor
drivers/hv/mshv_root.h | 24 +++--
drivers/hv/mshv_root_hv_call.c | 181 +++++++++++++++++++++++++++++++--
drivers/hv/mshv_root_main.c | 131 ++++++++++++++----------
include/hyperv/hvgdk_mini.h | 2 +
include/hyperv/hvhdk.h | 40 ++++++++
include/hyperv/hvhdk_mini.h | 33 ++++++
6 files changed, 339 insertions(+), 72 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH net-next] net: mana: Reduce waiting time if HWC not responding
From: Haiyang Zhang @ 2025-09-10 20:57 UTC (permalink / raw)
To: linux-hyperv, netdev
Cc: haiyangz, decui, kys, wei.liu, edumazet, davem, kuba, pabeni,
longli, ssengar, ernis, dipayanroy, kotaranov, shirazsaleem,
andrew+netdev, linux-kernel
From: Haiyang Zhang <haiyangz@microsoft.com>
If HW Channel (HWC) is not responding, reduce the waiting time, so further
steps will fail quickly.
This will prevent getting stuck for a long time (30 minutes or more), for
example, during unloading while HWC is not responding.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/net/ethernet/microsoft/mana/hw_channel.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index ef072e24c46d..ada6c78a2bef 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -881,7 +881,12 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,
if (!wait_for_completion_timeout(&ctx->comp_event,
(msecs_to_jiffies(hwc->hwc_timeout)))) {
if (hwc->hwc_timeout != 0)
- dev_err(hwc->dev, "HWC: Request timed out!\n");
+ dev_err(hwc->dev, "HWC: Request timed out: %u ms\n",
+ hwc->hwc_timeout);
+
+ /* Reduce further waiting if HWC no response */
+ if (hwc->hwc_timeout > 1)
+ hwc->hwc_timeout = 1;
err = -ETIMEDOUT;
goto out;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2 5/7] entry: Rename "kvm" entry code assets to "virt" to genericize APIs
From: Joel Fernandes @ 2025-09-10 14:45 UTC (permalink / raw)
To: Sean Christopherson
Cc: Marc Zyngier, Oliver Upton, Catalin Marinas, Will Deacon,
Tianrui Zhao, Bibo Mao, Huacai Chen, Anup Patel, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Paolo Bonzini, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Peter Zijlstra,
Andy Lutomirski, Paul E. McKenney, Frederic Weisbecker,
Neeraj Upadhyay, Josh Triplett, Boqun Feng, Uladzislau Rezki,
linux-kernel, linux-arm-kernel, kvmarm, kvm, loongarch, kvm-riscv,
linux-riscv, linux-hyperv, rcu, Nuno Das Neves, Mukesh R
In-Reply-To: <20250828000156.23389-6-seanjc@google.com>
On Wed, Aug 27, 2025 at 05:01:54PM -0700, Sean Christopherson wrote:
> Rename the "kvm" entry code files and Kconfigs to use generic "virt"
> nomenclature so that the code can be reused by other hypervisors (or
> rather, their root/dom0 partition drivers), without incorrectly suggesting
> the code somehow relies on and/or involves KVM.
>
> No functional change intended.
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> MAINTAINERS | 2 +-
> arch/arm64/kvm/Kconfig | 2 +-
> arch/loongarch/kvm/Kconfig | 2 +-
> arch/riscv/kvm/Kconfig | 2 +-
> arch/x86/kvm/Kconfig | 2 +-
> include/linux/{entry-kvm.h => entry-virt.h} | 8 ++++----
> include/linux/kvm_host.h | 6 +++---
> include/linux/rcupdate.h | 2 +-
> kernel/entry/Makefile | 2 +-
> kernel/entry/{kvm.c => virt.c} | 2 +-
> kernel/rcu/tree.c | 6 +++---
For RCU part,
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
thanks,
- Joel
> virt/kvm/Kconfig | 2 +-
> 12 files changed, 19 insertions(+), 19 deletions(-)
> rename include/linux/{entry-kvm.h => entry-virt.h} (94%)
> rename kernel/entry/{kvm.c => virt.c} (97%)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe168477caa4..c255048333f0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10200,7 +10200,7 @@ L: linux-kernel@vger.kernel.org
> S: Maintained
> T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/entry
> F: include/linux/entry-common.h
> -F: include/linux/entry-kvm.h
> +F: include/linux/entry-virt.h
> F: include/linux/irq-entry-common.h
> F: kernel/entry/
>
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 713248f240e0..6f4fc3caa31a 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -25,7 +25,7 @@ menuconfig KVM
> select HAVE_KVM_CPU_RELAX_INTERCEPT
> select KVM_MMIO
> select KVM_GENERIC_DIRTYLOG_READ_PROTECT
> - select KVM_XFER_TO_GUEST_WORK
> + select VIRT_XFER_TO_GUEST_WORK
> select KVM_VFIO
> select HAVE_KVM_DIRTY_RING_ACQ_REL
> select NEED_KVM_DIRTY_RING_WITH_BITMAP
> diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig
> index 40eea6da7c25..ae64bbdf83a7 100644
> --- a/arch/loongarch/kvm/Kconfig
> +++ b/arch/loongarch/kvm/Kconfig
> @@ -31,7 +31,7 @@ config KVM
> select KVM_GENERIC_HARDWARE_ENABLING
> select KVM_GENERIC_MMU_NOTIFIER
> select KVM_MMIO
> - select KVM_XFER_TO_GUEST_WORK
> + select VIRT_XFER_TO_GUEST_WORK
> select SCHED_INFO
> select GUEST_PERF_EVENTS if PERF_EVENTS
> help
> diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
> index 5a62091b0809..c50328212917 100644
> --- a/arch/riscv/kvm/Kconfig
> +++ b/arch/riscv/kvm/Kconfig
> @@ -30,7 +30,7 @@ config KVM
> select KVM_GENERIC_DIRTYLOG_READ_PROTECT
> select KVM_GENERIC_HARDWARE_ENABLING
> select KVM_MMIO
> - select KVM_XFER_TO_GUEST_WORK
> + select VIRT_XFER_TO_GUEST_WORK
> select KVM_GENERIC_MMU_NOTIFIER
> select SCHED_INFO
> select GUEST_PERF_EVENTS if PERF_EVENTS
> diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
> index 2c86673155c9..f81074b0c0a8 100644
> --- a/arch/x86/kvm/Kconfig
> +++ b/arch/x86/kvm/Kconfig
> @@ -40,7 +40,7 @@ config KVM_X86
> select HAVE_KVM_MSI
> select HAVE_KVM_CPU_RELAX_INTERCEPT
> select HAVE_KVM_NO_POLL
> - select KVM_XFER_TO_GUEST_WORK
> + select VIRT_XFER_TO_GUEST_WORK
> select KVM_GENERIC_DIRTYLOG_READ_PROTECT
> select KVM_VFIO
> select HAVE_KVM_PM_NOTIFIER if PM
> diff --git a/include/linux/entry-kvm.h b/include/linux/entry-virt.h
> similarity index 94%
> rename from include/linux/entry-kvm.h
> rename to include/linux/entry-virt.h
> index 3644de7e6019..42c89e3e5ca7 100644
> --- a/include/linux/entry-kvm.h
> +++ b/include/linux/entry-virt.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef __LINUX_ENTRYKVM_H
> -#define __LINUX_ENTRYKVM_H
> +#ifndef __LINUX_ENTRYVIRT_H
> +#define __LINUX_ENTRYVIRT_H
>
> #include <linux/static_call_types.h>
> #include <linux/resume_user_mode.h>
> @@ -10,7 +10,7 @@
> #include <linux/tick.h>
>
> /* Transfer to guest mode work */
> -#ifdef CONFIG_KVM_XFER_TO_GUEST_WORK
> +#ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK
>
> #ifndef ARCH_XFER_TO_GUEST_MODE_WORK
> # define ARCH_XFER_TO_GUEST_MODE_WORK (0)
> @@ -90,6 +90,6 @@ static inline bool xfer_to_guest_mode_work_pending(void)
> lockdep_assert_irqs_disabled();
> return __xfer_to_guest_mode_work_pending();
> }
> -#endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */
> +#endif /* CONFIG_VIRT_XFER_TO_GUEST_WORK */
>
> #endif
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 598b9473e46d..70ac2267d5d0 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -2,7 +2,7 @@
> #ifndef __KVM_HOST_H
> #define __KVM_HOST_H
>
> -#include <linux/entry-kvm.h>
> +#include <linux/entry-virt.h>
> #include <linux/types.h>
> #include <linux/hardirq.h>
> #include <linux/list.h>
> @@ -2444,7 +2444,7 @@ static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> }
> #endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */
>
> -#ifdef CONFIG_KVM_XFER_TO_GUEST_WORK
> +#ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK
> static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
> {
> vcpu->run->exit_reason = KVM_EXIT_INTR;
> @@ -2461,7 +2461,7 @@ static inline int kvm_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
> }
> return r;
> }
> -#endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */
> +#endif /* CONFIG_VIRT_XFER_TO_GUEST_WORK */
>
> /*
> * If more than one page is being (un)accounted, @virt must be the address of
> diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> index 120536f4c6eb..1e1f3aa375d9 100644
> --- a/include/linux/rcupdate.h
> +++ b/include/linux/rcupdate.h
> @@ -129,7 +129,7 @@ static inline void rcu_sysrq_start(void) { }
> static inline void rcu_sysrq_end(void) { }
> #endif /* #else #ifdef CONFIG_RCU_STALL_COMMON */
>
> -#if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK))
> +#if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_VIRT_XFER_TO_GUEST_WORK))
> void rcu_irq_work_resched(void);
> #else
> static __always_inline void rcu_irq_work_resched(void) { }
> diff --git a/kernel/entry/Makefile b/kernel/entry/Makefile
> index 77fcd83dd663..2333d70802e4 100644
> --- a/kernel/entry/Makefile
> +++ b/kernel/entry/Makefile
> @@ -14,4 +14,4 @@ CFLAGS_common.o += -fno-stack-protector
>
> obj-$(CONFIG_GENERIC_IRQ_ENTRY) += common.o
> obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o syscall_user_dispatch.o
> -obj-$(CONFIG_KVM_XFER_TO_GUEST_WORK) += kvm.o
> +obj-$(CONFIG_VIRT_XFER_TO_GUEST_WORK) += virt.o
> diff --git a/kernel/entry/kvm.c b/kernel/entry/virt.c
> similarity index 97%
> rename from kernel/entry/kvm.c
> rename to kernel/entry/virt.c
> index 6fc762eaacca..c52f99249763 100644
> --- a/kernel/entry/kvm.c
> +++ b/kernel/entry/virt.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0
>
> -#include <linux/entry-kvm.h>
> +#include <linux/entry-virt.h>
>
> static int xfer_to_guest_mode_work(unsigned long ti_work)
> {
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 174ee243b349..995489b72535 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -573,7 +573,7 @@ void rcutorture_format_gp_seqs(unsigned long long seqs, char *cp, size_t len)
> }
> EXPORT_SYMBOL_GPL(rcutorture_format_gp_seqs);
>
> -#if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK))
> +#if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_VIRT_XFER_TO_GUEST_WORK))
> /*
> * An empty function that will trigger a reschedule on
> * IRQ tail once IRQs get re-enabled on userspace/guest resume.
> @@ -602,7 +602,7 @@ noinstr void rcu_irq_work_resched(void)
> if (IS_ENABLED(CONFIG_GENERIC_ENTRY) && !(current->flags & PF_VCPU))
> return;
>
> - if (IS_ENABLED(CONFIG_KVM_XFER_TO_GUEST_WORK) && (current->flags & PF_VCPU))
> + if (IS_ENABLED(CONFIG_VIRT_XFER_TO_GUEST_WORK) && (current->flags & PF_VCPU))
> return;
>
> instrumentation_begin();
> @@ -611,7 +611,7 @@ noinstr void rcu_irq_work_resched(void)
> }
> instrumentation_end();
> }
> -#endif /* #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK)) */
> +#endif /* #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_VIRT_XFER_TO_GUEST_WORK)) */
>
> #ifdef CONFIG_PROVE_RCU
> /**
> diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
> index 727b542074e7..ce843db53831 100644
> --- a/virt/kvm/Kconfig
> +++ b/virt/kvm/Kconfig
> @@ -87,7 +87,7 @@ config HAVE_KVM_VCPU_RUN_PID_CHANGE
> config HAVE_KVM_NO_POLL
> bool
>
> -config KVM_XFER_TO_GUEST_WORK
> +config VIRT_XFER_TO_GUEST_WORK
> bool
>
> config HAVE_KVM_PM_NOTIFIER
> --
> 2.51.0.268.g9569e192d0-goog
>
^ permalink raw reply
* [PATCH net v2] net/mlx5: Not returning mlx5_link_info table when speed is unknown
From: Li Tian @ 2025-09-10 0:37 UTC (permalink / raw)
To: netdev, linux-hyperv
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Haiyang Zhang, Benjamin Poirier, Vitaly Kuznetsov,
Carolina Jubran, Shahar Shitrit
Because mlx5e_link_info and mlx5e_ext_link_info have holes
e.g. Azure mlx5 reports PTYS 19. Do not return it unless speed
is retrieved successfully.
Fixes: 65a5d35571849 ("net/mlx5: Refactor link speed handling with mlx5_link_info struct")
Suggested-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Li Tian <litian@redhat.com>
---
v2:
- Fix indentation and spacing only.
v1: https://lore.kernel.org/netdev/20250908085313.18768-1-litian@redhat.com
---
drivers/net/ethernet/mellanox/mlx5/core/port.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 2d7adf7444ba..aa9f2b0a77d3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -1170,7 +1170,11 @@ const struct mlx5_link_info *mlx5_port_ptys2info(struct mlx5_core_dev *mdev,
mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size,
force_legacy);
i = find_first_bit(&temp, max_size);
- if (i < max_size)
+
+ /* mlx5e_link_info has holes. Check speed
+ * is not zero as indication of one.
+ */
+ if (i < max_size && table[i].speed)
return &table[i];
return NULL;
--
2.50.0
^ permalink raw reply related
* [PATCH v1 5/6] x86/hyperv: Implement hypervisor ram collection into vmcore
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
In-Reply-To: <20250910001009.2651481-1-mrathor@linux.microsoft.com>
Introduce a new file to implement collection of hypervisor ram into the
vmcore collected by linux. By default, the hypervisor ram is locked, ie,
protected via hw page table. Hyper-V implements a disable hypercall which
essentially devirtualizes the system on the fly. This mechanism makes the
hypervisor ram accessible to linux. Because the hypervisor ram is already
mapped into linux address space (as reserved ram), it is automatically
collected into the vmcore without extra work. More details of the
implementation are available in the file prologue.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
---
arch/x86/hyperv/hv_crash.c | 622 +++++++++++++++++++++++++++++++++++++
1 file changed, 622 insertions(+)
create mode 100644 arch/x86/hyperv/hv_crash.c
diff --git a/arch/x86/hyperv/hv_crash.c b/arch/x86/hyperv/hv_crash.c
new file mode 100644
index 000000000000..531bac79d598
--- /dev/null
+++ b/arch/x86/hyperv/hv_crash.c
@@ -0,0 +1,622 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * X86 specific Hyper-V kdump/crash support module
+ *
+ * Copyright (C) 2025, Microsoft, Inc.
+ *
+ * This module implements hypervisor ram collection into vmcore for both
+ * cases of the hypervisor crash and linux dom0/root crash. Hyper-V implements
+ * a devirtualization hypercall with a 32bit protected mode ABI callback. This
+ * mechanism must be used to unlock hypervisor ram. Since the hypervisor ram
+ * is already mapped in linux, it is automatically collected into linux vmcore,
+ * and can be examined by the crash command (raw ram dump) or windbg.
+ *
+ * At a high level:
+ *
+ * Hypervisor Crash:
+ * Upon crash, hypervisor goes into an emergency minimal dispatch loop, a
+ * restrictive mode with very limited hypercall and msr support. Each cpu
+ * then injects NMIs into dom0/root vcpus. A shared page is used to check
+ * by linux in the nmi handler if the hypervisor has crashed. This shared
+ * page is setup in hv_root_crash_init during boot.
+ *
+ * Linux Crash:
+ * In case of linux crash, the callback hv_crash_stop_other_cpus will send
+ * NMIs to all cpus, then proceed to the crash_nmi_callback where it waits
+ * for all cpus to be in NMI.
+ *
+ * NMI Handler (upon quorum):
+ * Eventually, in both cases, all cpus wil end up in the nmi hanlder.
+ * Hyper-V requires the disable hypervisor must be done from the bsp. So
+ * the bsp nmi handler saves current context, does some fixups and makes
+ * the hypercall to disable the hypervisor, ie, devirtualize. Hypervisor
+ * at that point will suspend all vcpus (except the bsp), unlock all its
+ * ram, and return to linux at the 32bit mode entry RIP.
+ *
+ * Linux 32bit entry trampoline will then restore long mode and call C
+ * function here to restore context and continue execution to crash kexec.
+ */
+
+#include <linux/delay.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
+#include <linux/panic.h>
+#include <asm/apic.h>
+#include <asm/desc.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/mshyperv.h>
+#include <asm/nmi.h>
+#include <asm/idtentry.h>
+#include <asm/reboot.h>
+#include <asm/intel_pt.h>
+
+int hv_crash_enabled;
+EXPORT_SYMBOL_GPL(hv_crash_enabled);
+
+struct hv_crash_ctxt {
+ ulong rsp;
+ ulong cr0;
+ ulong cr2;
+ ulong cr4;
+ ulong cr8;
+
+ u16 cs;
+ u16 ss;
+ u16 ds;
+ u16 es;
+ u16 fs;
+ u16 gs;
+
+ u16 gdt_fill;
+ struct desc_ptr gdtr;
+ char idt_fill[6];
+ struct desc_ptr idtr;
+
+ u64 gsbase;
+ u64 efer;
+ u64 pat;
+};
+static struct hv_crash_ctxt hv_crash_ctxt;
+
+/* Shared hypervisor page that contains crash dump area we peek into.
+ * NB: windbg looks for "hv_cda" symbol so don't change it.
+ */
+static struct hv_crashdump_area *hv_cda;
+
+static u32 trampoline_pa, devirt_cr3arg;
+static atomic_t crash_cpus_wait;
+static void *hv_crash_ptpgs[4];
+static int hv_has_crashed, lx_has_crashed;
+
+/* This cannot be inlined as it needs stack */
+static noinline __noclone void hv_crash_restore_tss(void)
+{
+ load_TR_desc();
+}
+
+/* This cannot be inlined as it needs stack */
+static noinline void hv_crash_clear_kernpt(void)
+{
+ pgd_t *pgd;
+ p4d_t *p4d;
+
+ /* Clear entry so it's not confusing to someone looking at the core */
+ pgd = pgd_offset_k(trampoline_pa);
+ p4d = p4d_offset(pgd, trampoline_pa);
+ native_p4d_clear(p4d);
+}
+
+/*
+ * This is the C entry point from the asm glue code after the devirt hypercall.
+ * We enter here in IA32-e long mode, ie, full 64bit mode running on kernel
+ * page tables with our below 4G page identity mapped, but using a temporary
+ * GDT. ds/fs/gs/es are null. ss is not usable. bp is null. stack is not
+ * available. We restore kernel GDT, and rest of the context, and continue
+ * to kexec.
+ */
+static asmlinkage void __noreturn hv_crash_c_entry(void)
+{
+ struct hv_crash_ctxt *ctxt = &hv_crash_ctxt;
+
+ /* first thing, restore kernel gdt */
+ native_load_gdt(&ctxt->gdtr);
+
+ asm volatile("movw %%ax, %%ss" : : "a"(ctxt->ss));
+ asm volatile("movq %0, %%rsp" : : "m"(ctxt->rsp));
+
+ asm volatile("movw %%ax, %%ds" : : "a"(ctxt->ds));
+ asm volatile("movw %%ax, %%es" : : "a"(ctxt->es));
+ asm volatile("movw %%ax, %%fs" : : "a"(ctxt->fs));
+ asm volatile("movw %%ax, %%gs" : : "a"(ctxt->gs));
+
+ native_wrmsrq(MSR_IA32_CR_PAT, ctxt->pat);
+ asm volatile("movq %0, %%cr0" : : "r"(ctxt->cr0));
+
+ asm volatile("movq %0, %%cr8" : : "r"(ctxt->cr8));
+ asm volatile("movq %0, %%cr4" : : "r"(ctxt->cr4));
+ asm volatile("movq %0, %%cr2" : : "r"(ctxt->cr4));
+
+ native_load_idt(&ctxt->idtr);
+ native_wrmsrq(MSR_GS_BASE, ctxt->gsbase);
+ native_wrmsrq(MSR_EFER, ctxt->efer);
+
+ /* restore the original kernel CS now via far return */
+ asm volatile("movzwq %0, %%rax\n\t"
+ "pushq %%rax\n\t"
+ "pushq $1f\n\t"
+ "lretq\n\t"
+ "1:nop\n\t" : : "m"(ctxt->cs) : "rax");
+
+ /* We are in asmlinkage without stack frame, hence make a C function
+ * call which will buy stack frame to restore the tss or clear PT entry.
+ */
+ hv_crash_restore_tss();
+ hv_crash_clear_kernpt();
+
+ /* we are now fully in devirtualized normal kernel mode */
+ __crash_kexec(NULL);
+
+ for (;;)
+ cpu_relax();
+}
+/* Tell gcc we are using lretq long jump in the above function intentionally */
+STACK_FRAME_NON_STANDARD(hv_crash_c_entry);
+
+static void hv_mark_tss_not_busy(void)
+{
+ struct desc_struct *desc = get_current_gdt_rw();
+ tss_desc tss;
+
+ memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc));
+ tss.type = 0x9; /* available 64-bit TSS. 0xB is busy TSS */
+ write_gdt_entry(desc, GDT_ENTRY_TSS, &tss, DESC_TSS);
+}
+
+/* Save essential context */
+static void hv_hvcrash_ctxt_save(void)
+{
+ struct hv_crash_ctxt *ctxt = &hv_crash_ctxt;
+
+ asm volatile("movq %%rsp,%0" : "=m"(ctxt->rsp));
+
+ ctxt->cr0 = native_read_cr0();
+ ctxt->cr4 = native_read_cr4();
+
+ asm volatile("movq %%cr2, %0" : "=a"(ctxt->cr2));
+ asm volatile("movq %%cr8, %0" : "=a"(ctxt->cr8));
+
+ asm volatile("movl %%cs, %%eax" : "=a"(ctxt->cs));
+ asm volatile("movl %%ss, %%eax" : "=a"(ctxt->ss));
+ asm volatile("movl %%ds, %%eax" : "=a"(ctxt->ds));
+ asm volatile("movl %%es, %%eax" : "=a"(ctxt->es));
+ asm volatile("movl %%fs, %%eax" : "=a"(ctxt->fs));
+ asm volatile("movl %%gs, %%eax" : "=a"(ctxt->gs));
+
+ native_store_gdt(&ctxt->gdtr);
+ store_idt(&ctxt->idtr);
+
+ ctxt->gsbase = __rdmsr(MSR_GS_BASE);
+ ctxt->efer = __rdmsr(MSR_EFER);
+ ctxt->pat = __rdmsr(MSR_IA32_CR_PAT);
+}
+
+/* Add trampoline page to the kernel pagetable for transition to kernel PT */
+static void hv_crash_fixup_kernpt(void)
+{
+ pgd_t *pgd;
+ p4d_t *p4d;
+
+ pgd = pgd_offset_k(trampoline_pa);
+ p4d = p4d_offset(pgd, trampoline_pa);
+
+ /* trampoline_pa is below 4G, so no pre-existing entry to clobber */
+ p4d_populate(&init_mm, p4d, (pud_t *)hv_crash_ptpgs[1]);
+ p4d->p4d = p4d->p4d & ~(_PAGE_NX); /* enable execute */
+}
+
+/*
+ * Now that all cpus are in nmi and spinning, we notify the hyp that linux has
+ * crashed and will collect core. This will cause the hyp to quiesce and
+ * suspend all VPs except the bsp. Called if linux crashed and not the hyp.
+ */
+static void hv_notify_prepare_hyp(void)
+{
+ u64 status;
+ struct hv_input_notify_partition_event *input;
+ struct hv_partition_event_root_crashdump_input *cda;
+
+ input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+ cda = &input->input.crashdump_input;
+ memset(input, 0, sizeof(*input));
+ input->event = HV_PARTITION_EVENT_ROOT_CRASHDUMP;
+
+ cda->crashdump_action = HV_CRASHDUMP_ENTRY;
+ status = hv_do_hypercall(HVCALL_NOTIFY_PARTITION_EVENT, input, NULL);
+ if (!hv_result_success(status))
+ return;
+
+ cda->crashdump_action = HV_CRASHDUMP_SUSPEND_ALL_VPS;
+ hv_do_hypercall(HVCALL_NOTIFY_PARTITION_EVENT, input, NULL);
+}
+
+/*
+ * Common function for all cpus before devirtualization.
+ *
+ * Hypervisor crash: all cpus get here in nmi context.
+ * Linux crash: the panicing cpu gets here at base level, all others in nmi
+ * context. Note, panicing cpu may not be the bsp.
+ *
+ * The function is not inlined so it will show on the stack. It is named so
+ * because the crash cmd looks for certain well known function names on the
+ * stack before looking into the cpu saved note in the elf section, and
+ * that work is currently incomplete.
+ *
+ * Notes:
+ * Hypervisor crash:
+ * - the hypervisor is in a very restrictive mode at this point and any
+ * vmexit it cannot handle would result in reboot. For example, console
+ * output from here would result in synic ipi hcall, which would result
+ * in reboot. So, no mumbo jumbo, just get to kexec as quickly as possible.
+ *
+ * Devirtualization is supported from the bsp only.
+ */
+static noinline __noclone void crash_nmi_callback(struct pt_regs *regs)
+{
+ struct hv_input_disable_hyp_ex *input;
+ u64 status;
+ int msecs = 1000, ccpu = smp_processor_id();
+
+ if (ccpu == 0) {
+ /* crash_save_cpu() will be done in the kexec path */
+ cpu_emergency_stop_pt(); /* disable performance trace */
+ atomic_inc(&crash_cpus_wait);
+ } else {
+ crash_save_cpu(regs, ccpu);
+ cpu_emergency_stop_pt(); /* disable performance trace */
+ atomic_inc(&crash_cpus_wait);
+ for (;;); /* cause no vmexits */
+ }
+
+ while (atomic_read(&crash_cpus_wait) < num_online_cpus() && msecs--)
+ mdelay(1);
+
+ stop_nmi();
+ if (!hv_has_crashed)
+ hv_notify_prepare_hyp();
+
+ if (crashing_cpu == -1)
+ crashing_cpu = ccpu; /* crash cmd uses this */
+
+ hv_hvcrash_ctxt_save();
+ hv_mark_tss_not_busy();
+ hv_crash_fixup_kernpt();
+
+ input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+ memset(input, 0, sizeof(*input));
+ input->rip = trampoline_pa; /* PA of hv_crash_asm32 */
+ input->arg = devirt_cr3arg; /* PA of trampoline page table L4 */
+
+ status = hv_do_hypercall(HVCALL_DISABLE_HYP_EX, input, NULL);
+
+ /* Devirt failed, just reboot as things are in very bad state now */
+ native_wrmsrq(HV_X64_MSR_RESET, 1); /* get hv to reboot */
+}
+
+/*
+ * Generic nmi callback handler: could be called without any crash also.
+ * hv crash: hypervisor injects nmi's into all cpus
+ * lx crash: panicing cpu sends nmi to all but self via crash_stop_other_cpus
+ */
+static int hv_crash_nmi_local(unsigned int cmd, struct pt_regs *regs)
+{
+ int ccpu = smp_processor_id();
+
+ if (!hv_has_crashed && hv_cda && hv_cda->cda_valid)
+ hv_has_crashed = 1;
+
+ if (!hv_has_crashed && !lx_has_crashed)
+ return NMI_DONE; /* ignore the nmi */
+
+ if (hv_has_crashed) {
+ if (!kexec_crash_loaded() || !hv_crash_enabled) {
+ if (ccpu == 0) {
+ native_wrmsrq(HV_X64_MSR_RESET, 1); /* reboot */
+ } else
+ for (;;); /* cause no vmexits */
+ }
+ }
+
+ crash_nmi_callback(regs);
+
+ return NMI_DONE;
+}
+
+/*
+ * hv_crash_stop_other_cpus() == smp_ops.crash_stop_other_cpus
+ *
+ * On normal linux panic, this is called twice: first from panic and then again
+ * from native_machine_crash_shutdown.
+ *
+ * In case of mshv, 3 ways to get here:
+ * 1. hv crash (only bsp will get here):
+ * BSP : nmi callback -> DisableHv -> hv_crash_asm32 -> hv_crash_c_entry
+ * -> __crash_kexec -> native_machine_crash_shutdown
+ * -> crash_smp_send_stop -> smp_ops.crash_stop_other_cpus
+ * linux panic:
+ * 2. panic cpu x: panic() -> crash_smp_send_stop
+ * -> smp_ops.crash_stop_other_cpus
+ * 3. bsp: native_machine_crash_shutdown -> crash_smp_send_stop
+ *
+ * NB: noclone and non standard stack because of call to crash_setup_regs().
+ */
+static void __noclone hv_crash_stop_other_cpus(void)
+{
+ static int crash_stop_done;
+ struct pt_regs lregs;
+ int ccpu = smp_processor_id();
+
+ if (hv_has_crashed)
+ return; /* all cpus already in nmi handler path */
+
+ if (!kexec_crash_loaded())
+ return;
+
+ if (crash_stop_done)
+ return;
+ crash_stop_done = 1;
+
+ /* linux has crashed: hv is healthy, we can ipi safely */
+ lx_has_crashed = 1;
+ wmb(); /* nmi handlers look at lx_has_crashed */
+
+ apic->send_IPI_allbutself(NMI_VECTOR);
+
+ if (crashing_cpu == -1)
+ crashing_cpu = ccpu; /* crash cmd uses this */
+
+ /* crash_setup_regs() happens in kexec also, but for the kexec cpu which
+ * is the bsp. We could be here on non-bsp cpu, collect regs if so.
+ */
+ if (ccpu)
+ crash_setup_regs(&lregs, NULL);
+
+ crash_nmi_callback(&lregs);
+}
+STACK_FRAME_NON_STANDARD(hv_crash_stop_other_cpus);
+
+/* This GDT is accessed in IA32-e compat mode which uses 32bits addresses */
+struct hv_gdtreg_32 {
+ u16 fill;
+ u16 limit;
+ u32 address;
+} __packed;
+
+/* We need a CS with L bit to goto IA32-e long mode from 32bit compat mode */
+struct hv_crash_tramp_gdt {
+ u64 null; /* index 0, selector 0, null selector */
+ u64 cs64; /* index 1, selector 8, cs64 selector */
+} __packed;
+
+/* No stack, so jump via far ptr in memory to load the 64bit CS */
+struct hv_cs_jmptgt {
+ u32 address;
+ u16 csval;
+ u16 fill;
+} __packed;
+
+/* This trampoline data is copied onto the trampoline page after the asm code */
+struct hv_crash_tramp_data {
+ u64 tramp32_cr3;
+ u64 kernel_cr3;
+ struct hv_gdtreg_32 gdtr32;
+ struct hv_crash_tramp_gdt tramp_gdt;
+ struct hv_cs_jmptgt cs_jmptgt;
+ u64 c_entry_addr;
+} __packed;
+
+/*
+ * Setup a temporary gdt to allow the asm code to switch to the long mode.
+ * Since the asm code is relocated/copied to a below 4G page, it cannot use rip
+ * relative addressing, hence we must use trampoline_pa here. Also, save other
+ * info like jmp and C entry targets for same reasons.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int hv_crash_setup_trampdata(u64 trampoline_va)
+{
+ int size, offs;
+ void *dest;
+ struct hv_crash_tramp_data *tramp;
+
+ /* These must match exactly the ones in the corresponding asm file */
+ BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, tramp32_cr3) != 0);
+ BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, kernel_cr3) != 8);
+ BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data, gdtr32.limit) != 18);
+ BUILD_BUG_ON(offsetof(struct hv_crash_tramp_data,
+ cs_jmptgt.address) != 40);
+
+ /* hv_crash_asm_end is beyond last byte by 1 */
+ size = &hv_crash_asm_end - &hv_crash_asm32;
+ if (size + sizeof(struct hv_crash_tramp_data) > PAGE_SIZE) {
+ pr_err("%s: trampoline page overflow\n", __func__);
+ return -1;
+ }
+
+ dest = (void *)trampoline_va;
+ memcpy(dest, &hv_crash_asm32, size);
+
+ dest += size;
+ dest = (void *)round_up((ulong)dest, 16);
+ tramp = (struct hv_crash_tramp_data *)dest;
+
+ /* see MAX_ASID_AVAILABLE in tlb.c: "PCID 0 is reserved for use by
+ * non-PCID-aware users". Build cr3 with pcid 0
+ */
+ tramp->tramp32_cr3 = __sme_pa(hv_crash_ptpgs[0]);
+
+ /* Note, when restoring X86_CR4_PCIDE, cr3[11:0] must be zero */
+ tramp->kernel_cr3 = __sme_pa(init_mm.pgd);
+
+ tramp->gdtr32.limit = sizeof(struct hv_crash_tramp_gdt);
+ tramp->gdtr32.address = trampoline_pa +
+ (ulong)&tramp->tramp_gdt - trampoline_va;
+
+ /* base:0 limit:0xfffff type:b dpl:0 P:1 L:1 D:0 avl:0 G:1 */
+ tramp->tramp_gdt.cs64 = 0x00af9a000000ffff;
+
+ tramp->cs_jmptgt.csval = 0x8;
+ offs = (ulong)&hv_crash_asm64_lbl - (ulong)&hv_crash_asm32;
+ tramp->cs_jmptgt.address = trampoline_pa + offs;
+
+ tramp->c_entry_addr = (u64)&hv_crash_c_entry;
+
+ devirt_cr3arg = trampoline_pa + (ulong)dest - trampoline_va;
+
+ return 0;
+}
+
+/*
+ * Build 32bit trampoline page table for transition from protected mode
+ * non-paging to long-mode paging. This transition needs pagetables below 4G.
+ */
+static void hv_crash_build_tramp_pt(void)
+{
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ u64 pa, addr = trampoline_pa;
+
+ p4d = hv_crash_ptpgs[0] + pgd_index(addr) * sizeof(p4d);
+ pa = virt_to_phys(hv_crash_ptpgs[1]);
+ set_p4d(p4d, __p4d(_PAGE_TABLE | pa));
+ p4d->p4d &= ~(_PAGE_NX); /* disable no execute */
+
+ pud = hv_crash_ptpgs[1] + pud_index(addr) * sizeof(pud);
+ pa = virt_to_phys(hv_crash_ptpgs[2]);
+ set_pud(pud, __pud(_PAGE_TABLE | pa));
+
+ pmd = hv_crash_ptpgs[2] + pmd_index(addr) * sizeof(pmd);
+ pa = virt_to_phys(hv_crash_ptpgs[3]);
+ set_pmd(pmd, __pmd(_PAGE_TABLE | pa));
+
+ pte = hv_crash_ptpgs[3] + pte_index(addr) * sizeof(pte);
+ set_pte(pte, pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
+}
+
+/*
+ * Setup trampoline for devirtualization:
+ * - a page below 4G, ie 32bit addr containing asm glue code that mshv jmps to
+ * in protected mode.
+ * - 4 pages for a temporary page table that asm code uses to turn paging on
+ * - a temporary gdt to use in the compat mode.
+ *
+ * Returns: 0 on success
+ */
+static int hv_crash_trampoline_setup(void)
+{
+ int i, rc, order;
+ struct page *page;
+ u64 trampoline_va;
+ gfp_t flags32 = GFP_KERNEL | GFP_DMA32 | __GFP_ZERO;
+
+ /* page for 32bit trampoline assembly code + hv_crash_tramp_data */
+ page = alloc_page(flags32);
+ if (page == NULL) {
+ pr_err("%s: failed to alloc asm stub page\n", __func__);
+ return -1;
+ }
+
+ trampoline_va = (u64)page_to_virt(page);
+ trampoline_pa = (u32)page_to_phys(page);
+
+ order = 2; /* alloc 2^2 pages */
+ page = alloc_pages(flags32, order);
+ if (page == NULL) {
+ pr_err("%s: failed to alloc pt pages\n", __func__);
+ free_page(trampoline_va);
+ return -1;
+ }
+
+ for (i = 0; i < 4; i++, page++)
+ hv_crash_ptpgs[i] = page_to_virt(page);
+
+ hv_crash_build_tramp_pt();
+
+ rc = hv_crash_setup_trampdata(trampoline_va);
+ if (rc)
+ goto errout;
+
+ return 0;
+
+errout:
+ free_page(trampoline_va);
+ free_pages((ulong)hv_crash_ptpgs[0], order);
+
+ return rc;
+}
+
+/* Setup for kdump kexec to collect hypervisor ram when running as mshv root */
+void hv_root_crash_init(void)
+{
+ int rc;
+ struct hv_input_get_system_property *input;
+ struct hv_output_get_system_property *output;
+ unsigned long flags;
+ u64 status;
+ union hv_pfn_range cda_info;
+
+ if (pgtable_l5_enabled()) {
+ pr_err("Hyper-V: crash dump not yet supported on 5level PTs\n");
+ return;
+ }
+
+ rc = register_nmi_handler(NMI_LOCAL, hv_crash_nmi_local, NMI_FLAG_FIRST,
+ "hv_crash_nmi");
+ if (rc) {
+ pr_err("Hyper-V: failed to register crash nmi handler\n");
+ return;
+ }
+
+ local_irq_save(flags);
+ input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+ output = *this_cpu_ptr(hyperv_pcpu_output_arg);
+
+ memset(input, 0, sizeof(*input));
+ memset(output, 0, sizeof(*output));
+ input->property_id = HV_SYSTEM_PROPERTY_CRASHDUMPAREA;
+
+ status = hv_do_hypercall(HVCALL_GET_SYSTEM_PROPERTY, input, output);
+ cda_info.as_uint64 = output->hv_cda_info.as_uint64;
+ local_irq_restore(flags);
+
+ if (!hv_result_success(status)) {
+ pr_err("Hyper-V: %s: property:%d %s\n", __func__,
+ input->property_id, hv_result_to_string(status));
+ goto err_out;
+ }
+
+ if (cda_info.base_pfn == 0) {
+ pr_err("Hyper-V: hypervisor crash dump area pfn is 0\n");
+ goto err_out;
+ }
+
+ hv_cda = phys_to_virt(cda_info.base_pfn << PAGE_SHIFT);
+
+ rc = hv_crash_trampoline_setup();
+ if (rc)
+ goto err_out;
+
+ smp_ops.crash_stop_other_cpus = hv_crash_stop_other_cpus;
+
+ crash_kexec_post_notifiers = true;
+ hv_crash_enabled = 1;
+ pr_info("Hyper-V: linux and hv kdump support enabled\n");
+
+ return;
+
+err_out:
+ unregister_nmi_handler(NMI_LOCAL, "hv_crash_nmi");
+ pr_err("Hyper-V: only linux (but not hyp) kdump support enabled\n");
+}
--
2.36.1.vfs.0.0
^ permalink raw reply related
* [PATCH v1 6/6] x86/hyperv: Enable build of hypervisor crashdump collection files
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
In-Reply-To: <20250910001009.2651481-1-mrathor@linux.microsoft.com>
Enable build of the new files introduced in the earlier commits and add
call to do the setup during boot.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
---
arch/x86/hyperv/Makefile | 6 ++++++
arch/x86/hyperv/hv_init.c | 1 +
include/asm-generic/mshyperv.h | 9 +++++++++
3 files changed, 16 insertions(+)
diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index d55f494f471d..6f5d97cddd80 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -5,4 +5,10 @@ obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o
ifdef CONFIG_X86_64
obj-$(CONFIG_PARAVIRT_SPINLOCKS) += hv_spinlock.o
+
+ ifdef CONFIG_MSHV_ROOT
+ CFLAGS_REMOVE_hv_trampoline.o += -pg
+ CFLAGS_hv_trampoline.o += -fno-stack-protector
+ obj-$(CONFIG_CRASH_DUMP) += hv_crash.o hv_trampoline.o
+ endif
endif
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index afdbda2dd7b7..577bbd143527 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -510,6 +510,7 @@ void __init hyperv_init(void)
memunmap(src);
hv_remap_tsc_clocksource();
+ hv_root_crash_init();
} else {
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index dbd4c2f3aee3..952c221765f5 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -367,6 +367,15 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
+#if CONFIG_CRASH_DUMP
+void hv_root_crash_init(void);
+void hv_crash_asm32(void);
+void hv_crash_asm64_lbl(void);
+void hv_crash_asm_end(void);
+#else /* CONFIG_CRASH_DUMP */
+static inline void hv_root_crash_init(void) {}
+#endif /* CONFIG_CRASH_DUMP */
+
#else /* CONFIG_MSHV_ROOT */
static inline bool hv_root_partition(void) { return false; }
static inline bool hv_l1vh_partition(void) { return false; }
--
2.36.1.vfs.0.0
^ permalink raw reply related
* [PATCH v1 4/6] x86/hyperv: Add trampoline asm code to transition from hypervisor
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
In-Reply-To: <20250910001009.2651481-1-mrathor@linux.microsoft.com>
Introduce a small asm stub to transition from the hypervisor to linux
upon devirtualization.
At a high level, during panic of either the hypervisor or the dom0 (aka
root), the nmi handler asks hypervisor to devirtualize. As part of that,
the arguments include an entry point to return back to linux. This asm
stub implements that entry point.
The stub is entered in protected mode, uses temporary gdt and page table
to enable long mode and get to kernel entry point which then restores full
kernel context to resume execution to kexec.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
---
arch/x86/hyperv/hv_trampoline.S | 105 ++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+)
create mode 100644 arch/x86/hyperv/hv_trampoline.S
diff --git a/arch/x86/hyperv/hv_trampoline.S b/arch/x86/hyperv/hv_trampoline.S
new file mode 100644
index 000000000000..27a755401a42
--- /dev/null
+++ b/arch/x86/hyperv/hv_trampoline.S
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * X86 specific Hyper-V kdump/crash related code.
+ *
+ * Copyright (C) 2025, Microsoft, Inc.
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/alternative.h>
+#include <asm/msr.h>
+#include <asm/processor-flags.h>
+#include <asm/nospec-branch.h>
+
+/*
+ * void noreturn hv_crash_asm32(arg1)
+ * arg1 == edi == 32bit PA of struct hv_crash_trdata
+ *
+ * The hypervisor jumps here upon devirtualization in protected mode. This
+ * code gets copied to a page in the low 4G ie, 32bit space so it can run
+ * in the protected mode. Hence we cannot use any compile/link time offsets or
+ * addresses. It restores long mode via temporary gdt and page tables and
+ * eventually jumps to kernel code entry at HV_CRASHDATA_OFFS_C_entry.
+ *
+ * PreCondition (ie, Hypervisor call back ABI):
+ * o CR0 is set to 0x0021: PE(prot mode) and NE are set, paging is disabled
+ * o CR4 is set to 0x0
+ * o IA32_EFER is set to 0x901 (SCE and NXE are set)
+ * o EDI is set to the Arg passed to HVCALL_DISABLE_HYP_EX.
+ * o CS, DS, ES, FS, GS are all initialized with a base of 0 and limit 0xFFFF
+ * o IDTR, TR and GDTR are initialized with a base of 0 and limit of 0xFFFF
+ * o LDTR is initialized as invalid (limit of 0)
+ * o MSR PAT is power on default.
+ * o Other state/registers are cleared. All TLBs flushed.
+ *
+ * See Intel SDM 10.8.5
+ */
+
+#define HV_CRASHDATA_OFFS_TRAMPCR3 0x0 /* 0 */
+#define HV_CRASHDATA_OFFS_KERNCR3 0x8 /* 8 */
+#define HV_CRASHDATA_OFFS_GDTRLIMIT 0x12 /* 18 */
+#define HV_CRASHDATA_OFFS_CS_JMPTGT 0x28 /* 40 */
+#define HV_CRASHDATA_OFFS_C_entry 0x30 /* 48 */
+#define HV_CRASHDATA_TRAMPOLINE_CS 0x8
+
+ .text
+ .code32
+
+SYM_CODE_START(hv_crash_asm32)
+ UNWIND_HINT_UNDEFINED
+ ANNOTATE_NOENDBR
+ movl $X86_CR4_PAE, %ecx
+ movl %ecx, %cr4
+
+ movl %edi, %ebx
+ add $HV_CRASHDATA_OFFS_TRAMPCR3, %ebx
+ movl %cs:(%ebx), %eax
+ movl %eax, %cr3
+
+ # Setup EFER for long mode now.
+ movl $MSR_EFER, %ecx
+ rdmsr
+ btsl $_EFER_LME, %eax
+ wrmsr
+
+ # Turn paging on using the temp 32bit trampoline page table.
+ movl %cr0, %eax
+ orl $(X86_CR0_PG), %eax
+ movl %eax, %cr0
+
+ /* since kernel cr3 could be above 4G, we need to be in the long mode
+ * before we can load 64bits of the kernel cr3. We use a temp gdt for
+ * that with CS.L=1 and CS.D=0 */
+ mov %edi, %eax
+ add $HV_CRASHDATA_OFFS_GDTRLIMIT, %eax
+ lgdtl %cs:(%eax)
+
+ /* not done yet, restore CS now to switch to CS.L=1 */
+ mov %edi, %eax
+ add $HV_CRASHDATA_OFFS_CS_JMPTGT, %eax
+ ljmp %cs:*(%eax)
+SYM_CODE_END(hv_crash_asm32)
+
+ /* we now run in full 64bit IA32-e long mode, CS.L=1 and CS.D=0 */
+ .code64
+ .balign 8
+SYM_CODE_START(hv_crash_asm64)
+ UNWIND_HINT_UNDEFINED
+ ANNOTATE_NOENDBR
+SYM_INNER_LABEL(hv_crash_asm64_lbl, SYM_L_GLOBAL)
+ /* restore kernel page tables so we can jump to kernel code */
+ mov %edi, %eax
+ add $HV_CRASHDATA_OFFS_KERNCR3, %eax
+ movq %cs:(%eax), %rbx
+ movq %rbx, %cr3
+
+ mov %edi, %eax
+ add $HV_CRASHDATA_OFFS_C_entry, %eax
+ movq %cs:(%eax), %rbx
+ ANNOTATE_RETPOLINE_SAFE
+ jmp *%rbx
+
+ int $3
+
+SYM_INNER_LABEL(hv_crash_asm_end, SYM_L_GLOBAL)
+SYM_CODE_END(hv_crash_asm64)
--
2.36.1.vfs.0.0
^ permalink raw reply related
* [PATCH v1 3/6] hyperv: Add definitions for hypervisor crash dump support
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
In-Reply-To: <20250910001009.2651481-1-mrathor@linux.microsoft.com>
Add data structures for hypervisor crash dump support to the hypervisor
host ABI header file. Details of their usages are in subsequent commits.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
---
include/hyperv/hvhdk_mini.h | 55 +++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index 858f6a3925b3..ad9a8048fb4e 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -116,6 +116,17 @@ enum hv_system_property {
/* Add more values when needed */
HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
+ HV_SYSTEM_PROPERTY_CRASHDUMPAREA = 47,
+};
+
+#define HV_PFN_RANGE_PGBITS 24 /* HV_SPA_PAGE_RANGE_ADDITIONAL_PAGES_BITS */
+union hv_pfn_range { /* HV_SPA_PAGE_RANGE */
+ u64 as_uint64;
+ struct {
+ /* 39:0: base pfn. 63:40: additional pages */
+ u64 base_pfn : 64 - HV_PFN_RANGE_PGBITS;
+ u64 add_pfns : HV_PFN_RANGE_PGBITS;
+ } __packed;
};
enum hv_dynamic_processor_feature_property {
@@ -142,6 +153,8 @@ struct hv_output_get_system_property {
#if IS_ENABLED(CONFIG_X86)
u64 hv_processor_feature_value;
#endif
+ union hv_pfn_range hv_cda_info; /* CrashdumpAreaAddress */
+ u64 hv_tramp_pa; /* CrashdumpTrampolineAddress */
};
} __packed;
@@ -234,6 +247,48 @@ union hv_gpa_page_access_state {
u8 as_uint8;
} __packed;
+enum hv_crashdump_action {
+ HV_CRASHDUMP_NONE = 0,
+ HV_CRASHDUMP_SUSPEND_ALL_VPS,
+ HV_CRASHDUMP_PREPARE_FOR_STATE_SAVE,
+ HV_CRASHDUMP_STATE_SAVED,
+ HV_CRASHDUMP_ENTRY,
+};
+
+struct hv_partition_event_root_crashdump_input {
+ u32 crashdump_action; /* enum hv_crashdump_action */
+} __packed;
+
+struct hv_input_disable_hyp_ex { /* HV_X64_INPUT_DISABLE_HYPERVISOR_EX */
+ u64 rip;
+ u64 arg;
+} __packed;
+
+struct hv_crashdump_area { /* HV_CRASHDUMP_AREA */
+ u32 version;
+ union {
+ u32 flags_as_uint32;
+ struct {
+ u32 cda_valid : 1;
+ u32 cda_unused : 31;
+ } __packed;
+ };
+ /* more unused fields */
+} __packed;
+
+union hv_partition_event_input {
+ struct hv_partition_event_root_crashdump_input crashdump_input;
+};
+
+enum hv_partition_event {
+ HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2,
+};
+
+struct hv_input_notify_partition_event {
+ u32 event; /* enum hv_partition_event */
+ union hv_partition_event_input input;
+} __packed;
+
struct hv_lp_startup_status {
u64 hv_status;
u64 substatus1;
--
2.36.1.vfs.0.0
^ permalink raw reply related
* [PATCH v1 2/6] hyperv: Add two new hypercall numbers to guest ABI public header
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
In-Reply-To: <20250910001009.2651481-1-mrathor@linux.microsoft.com>
In preparation for the subsequent crashdump patches, copy two hypercall
numbers to the guest ABI header published by Hyper-V. One to notify
hypervisor of an event that occurs in the root partition, other to ask
hypervisor to disable the hypervisor.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
---
include/hyperv/hvgdk_mini.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 1be7f6a02304..5441bf47059a 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -469,6 +469,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_MAP_DEVICE_INTERRUPT 0x007c
#define HVCALL_UNMAP_DEVICE_INTERRUPT 0x007d
#define HVCALL_RETARGET_INTERRUPT 0x007e
+#define HVCALL_NOTIFY_PARTITION_EVENT 0x0087
#define HVCALL_NOTIFY_PORT_RING_EMPTY 0x008b
#define HVCALL_REGISTER_INTERCEPT_RESULT 0x0091
#define HVCALL_ASSERT_VIRTUAL_INTERRUPT 0x0094
@@ -492,6 +493,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_VP_CPUID_VALUES 0x00f4
#define HVCALL_MMIO_READ 0x0106
#define HVCALL_MMIO_WRITE 0x0107
+#define HVCALL_DISABLE_HYP_EX 0x010f
/* HV_HYPERCALL_INPUT */
#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
--
2.36.1.vfs.0.0
^ permalink raw reply related
* [PATCH v1 1/6] x86/hyperv: Rename guest crash shutdown function
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
In-Reply-To: <20250910001009.2651481-1-mrathor@linux.microsoft.com>
Rename hv_machine_crash_shutdown to more appropriate
hv_guest_crash_shutdown and make it applicable to guests only. This
in preparation for the subsequent hypervisor root/dom0 crash support
patches.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
---
arch/x86/kernel/cpu/mshyperv.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 25773af116bc..1c6ec9b6107f 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -219,7 +219,7 @@ static void hv_machine_shutdown(void)
#endif /* CONFIG_KEXEC_CORE */
#ifdef CONFIG_CRASH_DUMP
-static void hv_machine_crash_shutdown(struct pt_regs *regs)
+static void hv_guest_crash_shutdown(struct pt_regs *regs)
{
if (hv_crash_handler)
hv_crash_handler(regs);
@@ -562,7 +562,8 @@ static void __init ms_hyperv_init_platform(void)
machine_ops.shutdown = hv_machine_shutdown;
#endif
#if defined(CONFIG_CRASH_DUMP)
- machine_ops.crash_shutdown = hv_machine_crash_shutdown;
+ if (!hv_root_partition())
+ machine_ops.crash_shutdown = hv_guest_crash_shutdown;
#endif
#endif
/*
--
2.36.1.vfs.0.0
^ permalink raw reply related
* [PATCH v1 0/6] Hyper-V: Implement hypervisor core collection
From: Mukesh Rathor @ 2025-09-10 0:10 UTC (permalink / raw)
To: linux-hyperv, linux-kernel, linux-arch
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd
This patch series implements hypervisor core collection when running
under linux as root (aka dom0). By default initial hypervisor ram is
already mapped into linux as reserved. Further any ram deposited comes
from linux memory heap. The hypervisor locks all that ram to protect
it from dom0 or any other domains. At a high level, the methodology
involes devirtualizing the system on the fly upon either linux crash
or the hypervisor crash, then collecting ram as usual. This means
hypervisor ram is automatically collected into the vmcore.
Hypervisor pages are then accessible via crash command (using raw mem
dump) or windbg which has the ability to read hypervisor pdb symbol
file.
V1:
o Describe changes in imperative mood. Remove "This commit"
o Remove pr_emerg: causing unnecessary review noise
o Add missing kexec_crash_loaded()
o Remove leftover unnecessary memcpy in hv_crash_setup_trampdata
o Address objtool warnings via annotations
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
arch/x86/hyperv/Makefile | 6 +
arch/x86/hyperv/hv_crash.c | 622 ++++++++++++++++++++++++++++++++
arch/x86/hyperv/hv_init.c | 1 +
arch/x86/hyperv/hv_trampoline.S | 105 ++++++
arch/x86/kernel/cpu/mshyperv.c | 5 +-
include/asm-generic/mshyperv.h | 9 +
include/hyperv/hvgdk_mini.h | 2 +
include/hyperv/hvhdk_mini.h | 55 +++
8 files changed, 803 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
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