* [PATCH v5 03/51] x86/tsc: Ensure that TSC recalibration doesn't run if TSC frequency is known
From: Sean Christopherson @ 2026-07-01 19:31 UTC (permalink / raw)
To: Jonathan Corbet, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Kiryl Shutsemau,
Rick Edgecombe, Sean Christopherson, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Ajay Kaher,
Alexey Makhalov, Jan Kiszka, Andy Lutomirski, Peter Zijlstra,
Juergen Gross, Daniel Lezcano, John Stultz
Cc: Shuah Khan, H. Peter Anvin, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, linux-doc, kvm, linux-kernel, linux-coco,
linux-hyperv, virtualization, xen-devel, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, David Woodhouse,
Michael Kelley, Thomas Gleixner
In-Reply-To: <20260701193212.749551-1-seanjc@google.com>
When attempting TSC recalibration post-boot, which is only done for ancient
CPUS (P4 and K7) on SMP=n kernels, assert that the TSC frequency isn't
known (explicitly provided by hardware) by way of MSR or CPUID, and bail if
the impossible happens. In practice, recalibration and TSC_KNOWN_FREQ are
mutually exclusive, as TSC_KNOWN_FREQ will only be set when running on
hardware that was released decades after recalibration was obsoleted, but
but it's hard to see that, especially when looking at just the TSC code.
Note, the WARN can likely be tripped by running in a virtual machine and
concocting an impossible CPU model, e.g. by combining a P4 signature with
CPUID 0x15. This is working as intended, as such a virtual CPU model is
wildly out-of-spec and is not supported.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kernel/tsc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 4d6a446645c0..4393902c0ddd 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -930,6 +930,9 @@ void recalibrate_cpu_khz(void)
if (!boot_cpu_has(X86_FEATURE_TSC))
return;
+ if (WARN_ON_ONCE(cpu_feature_enabled(X86_FEATURE_TSC_KNOWN_FREQ)))
+ return;
+
cpu_khz = x86_platform.calibrate_cpu();
tsc_khz = x86_platform.calibrate_tsc();
if (tsc_khz == 0)
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v5 02/51] x86/apic: Add CONFIG_X86_LOCAL_APIC=n stubs for apic_set_timer_period_{,k}hz()
From: Sean Christopherson @ 2026-07-01 19:31 UTC (permalink / raw)
To: Jonathan Corbet, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Kiryl Shutsemau,
Rick Edgecombe, Sean Christopherson, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Ajay Kaher,
Alexey Makhalov, Jan Kiszka, Andy Lutomirski, Peter Zijlstra,
Juergen Gross, Daniel Lezcano, John Stultz
Cc: Shuah Khan, H. Peter Anvin, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, linux-doc, kvm, linux-kernel, linux-coco,
linux-hyperv, virtualization, xen-devel, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, David Woodhouse,
Michael Kelley, Thomas Gleixner
In-Reply-To: <20260701193212.749551-1-seanjc@google.com>
Add stubs for the apic_set_timer_period_{,k}hz() APIs when the kernel is
built without support for a local APIC, and drop #ifdefs in callers that
don't need to check CONFIG_X86_LOCAL_APIC for other reasons.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/apic.h | 2 ++
arch/x86/kernel/cpu/vmware.c | 2 --
arch/x86/kernel/tsc.c | 2 --
arch/x86/kernel/tsc_msr.c | 2 --
4 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index cd84a94688a2..035998555e99 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -189,6 +189,8 @@ static inline void disable_local_APIC(void) { }
# define setup_boot_APIC_clock x86_init_noop
# define setup_secondary_APIC_clock x86_init_noop
static inline void lapic_update_tsc_freq(void) { }
+static inline void apic_set_timer_period_hz(u64 period_hz, const char *source) { }
+static inline void apic_set_timer_period_khz(u64 period_khz, const char *source) { }
static inline void init_bsp_APIC(void) { }
static inline void apic_intr_mode_select(void) { }
static inline void apic_intr_mode_init(void) { }
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 36f779dd311d..13b97265c535 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -422,10 +422,8 @@ static void __init vmware_platform_setup(void)
x86_platform.calibrate_tsc = vmware_get_tsc_khz;
x86_platform.calibrate_cpu = vmware_get_tsc_khz;
-#ifdef CONFIG_X86_LOCAL_APIC
/* Skip lapic calibration since we know the bus frequency. */
apic_set_timer_period_hz(ecx, "VMware hypervisor");
-#endif
} else {
pr_warn("Failed to get TSC freq from the hypervisor\n");
}
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index f9ecc9256863..4d6a446645c0 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -710,7 +710,6 @@ unsigned long native_calibrate_tsc(void)
if (boot_cpu_data.x86_vfm == INTEL_ATOM_GOLDMONT)
setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
-#ifdef CONFIG_X86_LOCAL_APIC
/*
* The local APIC appears to be fed by the core crystal clock
* (which sounds entirely sensible). We can set the global
@@ -718,7 +717,6 @@ unsigned long native_calibrate_tsc(void)
* timer later.
*/
apic_set_timer_period_khz(crystal_khz, "CPUID 0x15/0x16");
-#endif
return crystal_khz * ebx_numerator / eax_denominator;
}
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 7e990871e041..aece062aee7e 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -210,9 +210,7 @@ unsigned long cpu_khz_from_msr(void)
if (freq == 0)
pr_err("Error MSR_FSB_FREQ index %d is unknown\n", index);
-#ifdef CONFIG_X86_LOCAL_APIC
apic_set_timer_period_khz(freq, "MSR_FSB_FREQ");
-#endif
/*
* TSC frequency determined by MSR is always considered "known"
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v5 01/51] x86/apic: Provide helpers to set local APIC timer period in hz and khz
From: Sean Christopherson @ 2026-07-01 19:31 UTC (permalink / raw)
To: Jonathan Corbet, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Kiryl Shutsemau,
Rick Edgecombe, Sean Christopherson, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Ajay Kaher,
Alexey Makhalov, Jan Kiszka, Andy Lutomirski, Peter Zijlstra,
Juergen Gross, Daniel Lezcano, John Stultz
Cc: Shuah Khan, H. Peter Anvin, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, linux-doc, kvm, linux-kernel, linux-coco,
linux-hyperv, virtualization, xen-devel, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, David Woodhouse,
Michael Kelley, Thomas Gleixner
In-Reply-To: <20260701193212.749551-1-seanjc@google.com>
Add and use APIs to set the local APIC timer period instead of open coding
the subtle HZ math in a all external callers, and make lapic_timer_period
local to apic.c. Provide APIs to specify the frequency in both hertz and
kilohertz so that Hyper-V and VMware code aren't forced to lose precision.
Opportunistically use mul_u64_u32_div() to harden against the possibility
that the period in Khz is greater than 4294967, i.e. if the APIC timer runs
at ~4.29 GHz. As pointed out by Sashiko, 4294968 * 1000 == 0x1_000002c0,
and thus a Khz period of 4294968 would silently overflow the 32-bit
unsigned integer used by most callers.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/apic.h | 3 ++-
arch/x86/kernel/apic/apic.c | 12 +++++++++++-
arch/x86/kernel/cpu/mshyperv.c | 5 +----
arch/x86/kernel/cpu/vmware.c | 4 +---
arch/x86/kernel/jailhouse.c | 2 +-
arch/x86/kernel/tsc.c | 2 +-
arch/x86/kernel/tsc_msr.c | 2 +-
7 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 9cd493d467d4..cd84a94688a2 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -63,7 +63,6 @@ extern int apic_verbosity;
extern int local_apic_timer_c2_ok;
extern bool apic_is_disabled;
-extern unsigned int lapic_timer_period;
extern enum apic_intr_mode_id apic_intr_mode;
enum apic_intr_mode_id {
@@ -138,6 +137,8 @@ void register_lapic_address(unsigned long address);
extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern void lapic_update_tsc_freq(void);
+extern void apic_set_timer_period_hz(u64 period_hz, const char *source);
+extern void apic_set_timer_period_khz(u64 period_khz, const char *source);
#ifdef CONFIG_X86_64
static inline bool apic_force_enable(unsigned long addr)
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index aa1e19979aa8..8d3d930576fd 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -176,7 +176,7 @@ static struct resource lapic_resource = {
};
/* Measured in ticks per HZ. */
-unsigned int lapic_timer_period = 0;
+static unsigned int lapic_timer_period;
static void apic_pm_activate(void);
@@ -796,6 +796,16 @@ bool __init apic_needs_pit(void)
return lapic_timer_period == 0;
}
+void apic_set_timer_period_khz(u64 period_khz, const char *source)
+{
+ lapic_timer_period = mul_u64_u32_div(period_khz, 1000, HZ);
+}
+
+void apic_set_timer_period_hz(u64 period_hz, const char *source)
+{
+ lapic_timer_period = div_u64(period_hz, HZ);
+}
+
static int __init calibrate_APIC_clock(void)
{
struct clock_event_device *levt = this_cpu_ptr(&lapic_events);
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 185d4f677ec0..87beecec76f0 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -646,10 +646,7 @@ static void __init ms_hyperv_init_platform(void)
u64 hv_lapic_frequency;
rdmsrq(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
- hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
- lapic_timer_period = hv_lapic_frequency;
- pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n",
- lapic_timer_period);
+ apic_set_timer_period_hz(hv_lapic_frequency, "Hyper-V hypervisor");
}
register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST,
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 34b73573b108..36f779dd311d 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -424,9 +424,7 @@ static void __init vmware_platform_setup(void)
#ifdef CONFIG_X86_LOCAL_APIC
/* Skip lapic calibration since we know the bus frequency. */
- lapic_timer_period = ecx / HZ;
- pr_info("Host bus clock speed read from hypervisor : %u Hz\n",
- ecx);
+ apic_set_timer_period_hz(ecx, "VMware hypervisor");
#endif
} else {
pr_warn("Failed to get TSC freq from the hypervisor\n");
diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c
index f58ce9220e0f..f2d4ef89c085 100644
--- a/arch/x86/kernel/jailhouse.c
+++ b/arch/x86/kernel/jailhouse.c
@@ -65,7 +65,7 @@ static void jailhouse_get_wallclock(struct timespec64 *now)
static void __init jailhouse_timer_init(void)
{
- lapic_timer_period = setup_data.v1.apic_khz * (1000 / HZ);
+ apic_set_timer_period_khz(setup_data.v1.apic_khz, "Jailhouse hypervisor");
}
static unsigned long jailhouse_get_tsc(void)
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index ce10ae4b298b..f9ecc9256863 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -717,7 +717,7 @@ unsigned long native_calibrate_tsc(void)
* lapic_timer_period here to avoid having to calibrate the APIC
* timer later.
*/
- lapic_timer_period = crystal_khz * 1000 / HZ;
+ apic_set_timer_period_khz(crystal_khz, "CPUID 0x15/0x16");
#endif
return crystal_khz * ebx_numerator / eax_denominator;
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 48e6cc1cb017..7e990871e041 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -211,7 +211,7 @@ unsigned long cpu_khz_from_msr(void)
pr_err("Error MSR_FSB_FREQ index %d is unknown\n", index);
#ifdef CONFIG_X86_LOCAL_APIC
- lapic_timer_period = (freq * 1000) / HZ;
+ apic_set_timer_period_khz(freq, "MSR_FSB_FREQ");
#endif
/*
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v5 00/51] x86: Try to wrangle PV clocks vs. TSC
From: Sean Christopherson @ 2026-07-01 19:31 UTC (permalink / raw)
To: Jonathan Corbet, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Kiryl Shutsemau,
Rick Edgecombe, Sean Christopherson, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Ajay Kaher,
Alexey Makhalov, Jan Kiszka, Andy Lutomirski, Peter Zijlstra,
Juergen Gross, Daniel Lezcano, John Stultz
Cc: Shuah Khan, H. Peter Anvin, Vitaly Kuznetsov,
Broadcom internal kernel review list, Boris Ostrovsky,
Stephen Boyd, linux-doc, kvm, linux-kernel, linux-coco,
linux-hyperv, virtualization, xen-devel, Tom Lendacky,
Nikunj A Dadhania, David Woodhouse, David Woodhouse,
Michael Kelley, Thomas Gleixner
The primary goal of this series to fix flaws with SNP and TDX guests where a
PV clock provided by the untrusted hypervisor is used instead of the secure
TSC that is controlled by trusted firmware.
The secondary goal is modernize running under KVM. Currently, KVM guests will
use TSC for clocksource, but not sched_clock. And Linux-as-a-KVM-guest doesn't
support paravirt enumeration of the TSC/APIC frequencies, even though QEMU
provides that information by default.
The tertiary goal is to clean up the PV clock code to deduplicate logic across
hypervisors, and to hopefully make it all easier to maintain going forward.
The quaternary goal is to clean up the TSC calibration code, which was made
stupidly hard to follow by hypervisor code mixing in with the native
calibration routines, instead of being implemented as a pure alternative.
Note, the VMware and Xen changes still probably should get acks from those
maintainers, as my understanding of what they're trying to do may be flawed.
Lots more background on the SNP/TDX motiviation:
https://lore.kernel.org/all/20250106124633.1418972-13-nikunj@amd.com
As before, I deliberately omitted jailhouse-dev@googlegroups.com from the To/Cc,
as those emails bounced on v1, AFAICT nothing has changed.
v5:
- Use cpu_feature_enabled() instead of boot_cpu_has(). [Boris]
- WARN if recalibrate_cpu_khz() runs on a system with TSC_KNOWN_FREQ. [Thomas]
- Opportunistically drop a line break in native_calibrate_tsc(). [Thomas]
- Rely on callers of cpuid_get_tsc_info() to check the result instead of
unnecessarily zeroing the structure. [Boris]
- Ignore tsc_early_khz if the TSC frequency is provided by trusted firmware
or by the hypervisor. [Thomas, Sashiko]
- Cache CPUID output in acrn_init_platform() to avoid introducing a transient
bug where TSC_KNOWN_FREQ could be set even if the ACRN hypervisor didn't
actually provide the frequency. [Sashiko]
- Drop kvmclock's useless/dead check_tsc_unstable() call (it occurs before the
command line parameter is parsed). [Sashiko]
- Add helpers to set lapic_timer_period, to fix not-so-theoretical overflow
in the various "khz * 1000 / HZ" patterns. [Sashiko]
- Drop the "x86/xen: Obtain TSC frequency from CPUID if present" patch as it
doesn't have any dependencies/conflicts on/with this series, and Sashiko had
concerns about the assumptions it was making. [Sashiko]
- Collect reviews. [David] (Kirill's got dropped because the patch he reviewed
got completely rewritten).
v4:
- Use x86_init_noop() to skip save/restore on VMware and Xen instead of
nullifying x86_platform.{save,restore}_sched_clock_state. [Sashiko]
- Use '0' to indicate "failure" when getting the CPU frequency from CPUID, to
avoid using an out-param and thus make it all but impossible to
unintentionally clobber the global cpu_khz (which v3 did). [Sashiko]
- Rename cpuid_get_cpu_freq() => __cpu_khz_from_cpuid() to capture its
relationship with cpu_khz_from_cpuid().
- Compute lapic_timer_period in units of ticks, not Khz. [Sashiko]
- Kill off x86_platform_ops.calibrate_{cpu,tsc}(), and instead use dedicated
hooks for hypervisor code, and direct calls for TDX and SNP. [David, loosely]
- Drop SNP's secure TSC override of _CPU_ calibration, as there's zero
evidence it's justified or a net positive.
- Collect reviews/acks. [David, Wei]
- Decouple getting TSC/APIC frequencies from KVM PV CPUID from kvmclock. [David]
- Fix an amusing number of Opportunistically misspellings. [David]
- Set kvm_sched_clock_offset _before_ registering kvmclock as sched_clock,
and add a comment to guard against future goofs. [Sashiko]
- Keep "setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE)" in Hyper-V's handling
of HV_ACCESS_TSC_INVARIANT, as it's technically possible to have a VM
with HV_ACCESS_TSC_INVARIANT but not HV_ACCESS_FREQUENCY_MSRS. Though as
a _very_ nice side effect of using dedicated sequencing for selecting the
TSC frequency source, this would have naturally happened anyways. [Sashiko]
v3:
- https://lore.kernel.org/all/20260515191942.1892718-1-seanjc@google.com
- Collect reviews. [Michael, Thomas]
- Use Hyper-V reference counter / refcounter instead of Hyper-V timer. [Michael]
- Use the paravirt CPUID interface first proposed by VMware for KVM's
"official" mechanism for communicating frequency to KVM-aware guests,
instead of abusing Intel's CPUID leafs. [David]
- Deal with paravirt code being moved into asm/timers.h and
arch/x86/kernel/tsc.c.
v2:
- https://lore.kernel.org/all/Z8YWttWDtvkyCtdJ@google.com
- Add struct to hold the TSC CPUID output. [Boris]
- Don't pointlessly inline the TSC CPUID helpers. [Boris]
- Fix a variable goof in a helper, hopefully for real this time. [Dan]
- Collect reviews. [Nikunj]
- Override the sched_clock save/restore hooks if and only if a PV clock
is successfully registered.
- During resome, restore clocksources before reading persistent time.
- Clean up more warts created by kvmclock.
- Fix more bugs in kvmclock's suspend/resume handling.
- Try to harden kvmclock against future bugs.
v1: https://lore.kernel.org/all/20250201021718.699411-1-seanjc@google.com
David Woodhouse (2):
KVM: x86: Officially define CPUID 0x40000010 as PV Timing Info (TSC
and Bus)
x86/kvm: Obtain TSC frequency from PV CPUID if present
Sean Christopherson (49):
x86/apic: Provide helpers to set local APIC timer period in hz and khz
x86/apic: Add CONFIG_X86_LOCAL_APIC=n stubs for
apic_set_timer_period_{,k}hz()
x86/tsc: Ensure that TSC recalibration doesn't run if TSC frequency is
known
x86/tsc: Restrict recalibrate_cpu_khz() export to p4-clockmod and
powernow-k7
x86/sev: Mark TSC as reliable when configuring Secure TSC
x86/sev: Don't override CPU frequency calibration for SNP's Secure TSC
x86/sev: Move check for SNP Secure TSC support to tsc_early_init()
x86/sev: Shove SNP's secure/trusted TSC frequency directly into
"calibration"
x86/tsc: Add a standalone helper for getting TSC info from CPUID.0x15
x86/tdx: Force TSC frequency with CPUID-based info provided by the
TDX-Module
x86/tsc: Add dedicated hypervisor hooks for getting known TSC/CPU
frequencies
x86/acrn: Register TSC/CPU frequency callbacks iff frequency is
actually in CPUID
x86/acrn: Mark TSC frequency as known when using ACRN for calibration
x86/tsc: Consolidate forcing of X86_FEATURE_TSC_KNOWN_FREQ for PV code
x86/tsc: Kill off x86_platform_ops.calibrate_{cpu,tsc}() hooks
x86/tsc: Rename pit_hpet_ptimer_calibrate_cpu() =>
native_calibrate_cpu_late()
x86/tsc: Fold native_calibrate_cpu() into recalibrate_cpu_khz()
x86/kvmclock: Rename kvm_get_tsc_khz() to kvmclock_get_tsc_khz()
x86/kvmclock: Drop dead check on TSC being unstable during
kvmclock_init()
x86/kvm: Mark TSC as reliable when it's constant and nonstop
x86/tsc: Add standalone helper for getting CPU frequency from CPUID
x86/kvm: Get CPU base frequency from CPUID when it's available
clocksource: hyper-v: Register sched_clock save/restore iff it's
necessary
clocksource: hyper-v: Drop wrappers to sched_clock save/restore
helpers
clocksource: hyper-v: Don't save/restore TSC offset when using HV
sched_clock
x86/kvmclock: Setup kvmclock for secondary CPUs iff CONFIG_SMP=y
x86/kvm: Don't disable kvmclock on BSP in syscore_suspend()
x86/paravirt: Remove unnecessary PARAVIRT=n stub for
paravirt_set_sched_clock()
x86/paravirt: Move handling of unstable PV clocks into
paravirt_set_sched_clock()
x86/kvmclock: Move sched_clock save/restore helpers up in kvmclock.c
x86/xen/time: NOP-ify x86_platform's sched_clock save/restore hooks
x86/vmware: NOP-ify save/restore hooks when using VMware's sched_clock
x86/tsc: WARN if TSC sched_clock save/restore used with PV sched_clock
x86/paravirt: Pass sched_clock save/restore helpers during
registration
x86/kvmclock: Move kvm_sched_clock_init() down in kvmclock.c
x86/xen/time: Mark xen_setup_vsyscall_time_info() as __init
x86/pvclock: Mark setup helpers and related various as
__init/__ro_after_init
x86/pvclock: WARN if pvclock's valid_flags are overwritten
x86/kvmclock: Refactor handling of PVCLOCK_TSC_STABLE_BIT during
kvmclock_init()
timekeeping: Resume clocksources before reading persistent clock
x86/kvmclock: Hook clocksource.suspend/resume when kvmclock isn't
sched_clock
x86/kvmclock: WARN if wall clock is read while kvmclock is suspended
x86/paravirt: Mark __paravirt_set_sched_clock() as __init
x86/paravirt: Plumb a return code into __paravirt_set_sched_clock()
x86/paravirt: Don't use a PV sched_clock in CoCo guests with trusted
TSC
x86/kvmclock: Use TSC for sched_clock if it's constant and non-stop
x86/kvmclock: Plumb in AP-online and BSP-resume to kvmlock, for
documentation
x86/paravirt: Move using_native_sched_clock() stub into timer.h
x86/kvm: Get local APIC bus frequency from PV CPUID Timing Info
.../admin-guide/kernel-parameters.txt | 5 +
Documentation/virt/kvm/x86/cpuid.rst | 12 +
arch/x86/coco/sev/core.c | 21 +-
arch/x86/coco/tdx/tdx.c | 19 +-
arch/x86/include/asm/acrn.h | 5 -
arch/x86/include/asm/apic.h | 5 +-
arch/x86/include/asm/kvm_para.h | 12 +-
arch/x86/include/asm/sev.h | 4 +-
arch/x86/include/asm/tdx.h | 2 +
arch/x86/include/asm/timer.h | 15 +-
arch/x86/include/asm/tsc.h | 10 +-
arch/x86/include/asm/x86_init.h | 8 +-
arch/x86/include/uapi/asm/kvm_para.h | 11 +
arch/x86/kernel/apic/apic.c | 12 +-
arch/x86/kernel/cpu/acrn.c | 14 +-
arch/x86/kernel/cpu/mshyperv.c | 70 +-----
arch/x86/kernel/cpu/vmware.c | 19 +-
arch/x86/kernel/jailhouse.c | 9 +-
arch/x86/kernel/kvm.c | 101 ++++++--
arch/x86/kernel/kvmclock.c | 208 +++++++++++------
arch/x86/kernel/pvclock.c | 9 +-
arch/x86/kernel/tsc.c | 218 +++++++++++-------
arch/x86/kernel/tsc_msr.c | 4 +-
arch/x86/kernel/x86_init.c | 2 -
arch/x86/mm/mem_encrypt_amd.c | 3 -
arch/x86/xen/time.c | 14 +-
drivers/clocksource/hyperv_timer.c | 38 ++-
include/clocksource/hyperv_timer.h | 2 -
kernel/time/timekeeping.c | 9 +-
29 files changed, 540 insertions(+), 321 deletions(-)
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply
* Re: [PATCH net 1/2] vsock/virtio: collapse receive queue under memory pressure
From: Bobby Eshleman @ 2026-07-01 16:34 UTC (permalink / raw)
To: Stefano Garzarella
Cc: netdev, Jason Wang, Jakub Kicinski, Paolo Abeni,
Michael S. Tsirkin, kvm, virtualization, Xuan Zhuo, Eric Dumazet,
Simon Horman, linux-kernel, Stefan Hajnoczi, David S. Miller,
Eugenio Pérez, stable, Brien Oberstein
In-Reply-To: <20260626134823.206676-2-sgarzare@redhat.com>
On Fri, Jun 26, 2026 at 03:48:22PM +0200, Stefano Garzarella wrote:
> From: Stefano Garzarella <sgarzare@redhat.com>
>
> When many small packets accumulate in the receive queue, the skb overhead
> can exceed buf_alloc even while the payload is within bounds. This causes
> virtio_transport_inc_rx_pkt() to reject packets, leading to connection
> resets during large transfers under backpressure.
>
> The issue was reported by Brien, who has a reproducer, but it is also
> easily reproducible with iperf-vsock [1] using a small packet size:
>
> iperf3 --vsock -c $CID -l 129
>
> which fails immediately without this patch but with commit 059b7dbd20a6
> ("vsock/virtio: fix potential unbounded skb queue").
>
> Inspired by TCP's tcp_collapse() which solves a similar problem, add
> virtio_transport_collapse_rx_queue() that walks the receive queue and
> re-copies data into compact linear skbs to reduce the overhead.
>
> The collapse is triggered from virtio_transport_recv_enqueue() when
> virtio_transport_inc_rx_pkt() fails. A pre-scan counts the eligible bytes
> to size each allocation precisely, avoiding waste for isolated small
> packets. Partially consumed skbs are kept as-is to preserve
> buf_used/fwd_cnt accounting, EOM-marked skbs to maintain SEQPACKET
> message boundaries, and skbs already larger than the collapse target
> because they already have a good data-to-overhead ratio.
>
> [1] https://github.com/stefano-garzarella/iperf-vsock
>
> Fixes: 059b7dbd20a6 ("vsock/virtio: fix potential unbounded skb queue")
> Cc: stable@vger.kernel.org
> Reported-by: Brien Oberstein <brienpub@gmail.com>
> Closes: https://lore.kernel.org/netdev/618701dd023e$063de350$12b9a9f0$@gmail.com/
> Tested-by: Brien Oberstein <brienpub@gmail.com>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> ---
> net/vmw_vsock/virtio_transport_common.c | 148 +++++++++++++++++++++++-
> 1 file changed, 146 insertions(+), 2 deletions(-)
>
> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index 09475007165b..304ea424995d 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -420,6 +420,137 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
> return ret;
> }
>
> +static bool virtio_transport_can_collapse(struct sk_buff *skb,
> + unsigned int size)
> +{
> + /* skbs that are partially consumed, mark a SEQPACKET message boundary,
> + * or are already large enough should not be collapsed: they either
> + * need special accounting, carry protocol state, or already have a
> + * good data-to-overhead ratio.
> + */
> + if (VIRTIO_VSOCK_SKB_CB(skb)->offset)
> + return false;
> + if (le32_to_cpu(virtio_vsock_hdr(skb)->flags) & VIRTIO_VSOCK_SEQ_EOM)
> + return false;
> + if (skb->len >= size)
> + return false;
> + return true;
> +}
> +
> +/* Iterate through the packets in the queue starting from the current skb to
> + * count the number of bytes we can collapse.
> + */
> +static unsigned int
> +virtio_transport_collapse_size(struct sk_buff *skb,
> + struct sk_buff_head *queue,
> + unsigned int max_size)
> +{
> + unsigned int target = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
> +
> + while ((skb = skb_peek_next(skb, queue)) &&
> + virtio_transport_can_collapse(skb, max_size)) {
> + unsigned int len = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
> +
> + if (len > max_size - target)
> + return target;
> +
> + target += len;
> + }
> +
> + return target;
> +}
> +
> +/* Called under lock_sock when skb overhead exceeds the budget. */
> +static void virtio_transport_collapse_rx_queue(struct virtio_vsock_sock *vvs)
> +{
> + /* Use the same linear allocation threshold as virtio_vsock_alloc_skb()
> + * to avoid adding pressure on the page allocator.
> + */
> + unsigned int collapse_max = SKB_MAX_ORDER(VIRTIO_VSOCK_SKB_HEADROOM,
> + PAGE_ALLOC_COSTLY_ORDER);
> + struct sk_buff *skb, *next_skb, *new_skb = NULL;
> + struct sk_buff_head new_queue;
> +
> + __skb_queue_head_init(&new_queue);
> +
> + skb_queue_walk_safe(&vvs->rx_queue, skb, next_skb) {
> + struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb);
> + u32 src_off = VIRTIO_VSOCK_SKB_CB(skb)->offset;
> + u32 src_len = skb->len - src_off;
> + bool keep = false;
> +
> + if (!virtio_transport_can_collapse(skb, collapse_max)) {
> + /* Finalize pending collapsed skb to preserve packet
> + * ordering.
> + */
> + if (new_skb) {
> + __skb_queue_tail(&new_queue, new_skb);
> + new_skb = NULL;
> + }
> + keep = true;
> + goto next;
> + }
> +
> + /* Finalize if this packet won't fit in the remaining tailroom,
> + * so we can allocate a right-sized new_skb.
> + */
> + if (new_skb && src_len > skb_tailroom(new_skb)) {
> + __skb_queue_tail(&new_queue, new_skb);
> + new_skb = NULL;
> + }
> +
> + if (!new_skb) {
> + unsigned int alloc_size;
> +
> + alloc_size = virtio_transport_collapse_size(skb, &vvs->rx_queue,
> + collapse_max);
> +
> + /* Only this skb's data is eligible, nothing to merge
> + * with. Keep as-is.
> + */
> + if (alloc_size <= src_len) {
> + keep = true;
> + goto next;
> + }
> +
> + new_skb = virtio_vsock_alloc_linear_skb(alloc_size +
> + VIRTIO_VSOCK_SKB_HEADROOM, GFP_KERNEL);
> + if (!new_skb)
> + goto out;
> +
> + memcpy(virtio_vsock_hdr(new_skb), hdr,
> + sizeof(struct virtio_vsock_hdr));
> + virtio_vsock_hdr(new_skb)->len = 0;
> + }
> +
> + /* Cannot fail since src_off/src_len are within bounds, but if
> + * it does, discard new_skb to avoid queuing corrupted data.
> + */
> + if (WARN_ON_ONCE(skb_copy_bits(skb, src_off,
> + skb_put(new_skb, src_len),
> + src_len))) {
> + kfree_skb(new_skb);
> + new_skb = NULL;
> + goto out;
> + }
> +
> + le32_add_cpu(&virtio_vsock_hdr(new_skb)->len, src_len);
> + virtio_vsock_hdr(new_skb)->flags |= hdr->flags;
> +
> +next:
> + __skb_unlink(skb, &vvs->rx_queue);
> + if (keep)
> + __skb_queue_tail(&new_queue, skb);
> + else
> + consume_skb(skb);
> + }
> +out:
> + if (new_skb)
> + __skb_queue_tail(&new_queue, new_skb);
> +
> + skb_queue_splice(&new_queue, &vvs->rx_queue);
I think the new skbs will also need skb_set_owner_sk_safe(skb, sk)
when adding to rx_queue?
Best,
Bobby
> +}
> +
> static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
> u32 len)
> {
> @@ -1363,8 +1494,21 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
> spin_lock_bh(&vvs->rx_lock);
>
> can_enqueue = virtio_transport_inc_rx_pkt(vvs, len);
> - if (!can_enqueue)
> - goto out;
> + if (!can_enqueue) {
> + /* Try to collapse the receive queue to reduce skb overhead and
> + * make room for this packet.
> + * Unlock rx_lock since the collapse may sleep or, in any case,
> + * take some time to collapse the skbs, but this is safe, since
> + * sk_lock is held by caller so no one else can enqueue or
> + * dequeue.
> + */
> + spin_unlock_bh(&vvs->rx_lock);
> + virtio_transport_collapse_rx_queue(vvs);
> + spin_lock_bh(&vvs->rx_lock);
> + can_enqueue = virtio_transport_inc_rx_pkt(vvs, len);
> + if (!can_enqueue)
> + goto out;
> + }
>
> if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM)
> vvs->msg_count++;
> --
> 2.54.0
>
>
^ permalink raw reply
* Re: [PATCH 12/13] mm/mprotect: convert mprotect code to use vma_flags_t
From: Lance Yang @ 2026-07-01 16:09 UTC (permalink / raw)
To: ljs
Cc: akpm, tsbogend, maddy, mpe, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, l.stach, inki.dae, sw0312.kim,
kyungmin.park, krzk, peter.griffin, jani.nikula, joonas.lahtinen,
rodrigo.vivi, tursulin, robin.clark, lumag, lyude, dakr,
tomi.valkeinen, hjc, heiko, andy.yan, thierry.reding, mperttunen,
jonathanh, kraxel, dmitry.osipenko, zack.rusin, matthew.brost,
thomas.hellstrom, oleksandr_andrushchenko, deller, bcrl, viro,
brauner, muchun.song, osalvador, david, ziy, baolin.wang, liam,
npache, ryan.roberts, dev.jain, baohua, lance.yang, hughd, vbabka,
rppt, surenb, mhocko, jannh, pfalcato, kees, perex, tiwai,
linux-mips, linux-kernel, linuxppc-dev, dri-devel, etnaviv,
linux-arm-kernel, linux-samsung-soc, intel-gfx, linux-arm-msm,
freedreno, nouveau, linux-rockchip, linux-tegra, virtualization,
intel-xe, xen-devel, linux-fbdev, linux-aio, linux-fsdevel,
linux-mm, linux-sound
In-Reply-To: <7ef626d8a12dc742cfc09d080be5dc09850e873a.1782760670.git.ljs@kernel.org>
On Mon, Jun 29, 2026 at 08:25:35PM +0100, Lorenzo Stoakes wrote:
>Replace use of the legacy vm_flags_t flags with vma_flags_t values
>throughout the mprotect logic.
>
>Note that we retain the legacy vm_flags_t bit shifting code in
>do_mprotect_key(), deferring a vma_flags_t approach to this for the time
>being.
>
>Additionally update comments to reflect the changes to be consistent.
>
>No functional change intended.
>
>Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>
>---
> mm/mprotect.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
>diff --git a/mm/mprotect.c b/mm/mprotect.c
>index 9cbf932b028c..c9504b2a2525 100644
>--- a/mm/mprotect.c
>+++ b/mm/mprotect.c
>@@ -40,7 +40,7 @@
>
> static bool maybe_change_pte_writable(struct vm_area_struct *vma, pte_t pte)
> {
>- if (WARN_ON_ONCE(!(vma->vm_flags & VM_WRITE)))
>+ if (WARN_ON_ONCE(!vma_test(vma, VMA_WRITE_BIT)))
> return false;
>
> /* Don't touch entries that are not even readable. */
>@@ -97,7 +97,7 @@ static bool can_change_shared_pte_writable(struct vm_area_struct *vma,
> bool can_change_pte_writable(struct vm_area_struct *vma, unsigned long addr,
> pte_t pte)
> {
>- if (!(vma->vm_flags & VM_SHARED))
>+ if (!vma_test(vma, VMA_SHARED_BIT))
> return can_change_private_pte_writable(vma, addr, pte);
>
> return can_change_shared_pte_writable(vma, pte);
>@@ -194,7 +194,7 @@ static __always_inline void set_write_prot_commit_flush_ptes(struct vm_area_stru
> {
> bool set_write;
>
>- if (vma->vm_flags & VM_SHARED) {
>+ if (vma_test(vma, VMA_SHARED_BIT)) {
> set_write = can_change_shared_pte_writable(vma, ptent);
> prot_commit_flush_ptes(vma, addr, ptep, oldpte, ptent, nr_ptes,
> /* idx = */ 0, set_write, tlb);
>@@ -811,8 +811,8 @@ mprotect_fixup(struct vma_iterator *vmi, struct mmu_gather *tlb,
> vm_unacct_memory(nrpages);
>
> /*
>- * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
>- * fault on access.
>+ * Private VMA_LOCKED_BIT VMA becoming writable: trigger COW to avoid
>+ * major fault on access.
> */
> if (vma_flags_test(&new_vma_flags, VMA_WRITE_BIT) &&
> vma_flags_test(&old_vma_flags, VMA_LOCKED_BIT) &&
>@@ -886,7 +886,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
> goto out;
> start = vma->vm_start;
> error = -EINVAL;
>- if (!(vma->vm_flags & VM_GROWSDOWN))
>+ if (!vma_test(vma, VMA_GROWSDOWN_BIT))
> goto out;
> } else {
> if (vma->vm_start > start)
>@@ -894,7 +894,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
> if (unlikely(grows & PROT_GROWSUP)) {
> end = vma->vm_end;
> error = -EINVAL;
>- if (!(vma->vm_flags & VM_GROWSUP))
>+ if (!vma_test(vma, VMA_GROWSUP_BIT))
IIUC, should this be
if (!vma_test_single_mask(vma, VMA_GROWSUP))
instead?
#elif defined(CONFIG_PARISC)
#define VM_GROWSUP INIT_VM_FLAG(GROWSUP)
...
#ifndef VM_GROWSUP
#define VM_GROWSUP VM_NONE
...
VM_GROWSUP is only defined as GROWSUP on parisc and becomes VM_NONE
elsewhere. But VMA_GROWSUP_BIT is the raw ARCH_1 bit, which is also used
for other arch-specific VMA flags:
DECLARE_VMA_BIT_ALIAS(SAO, ARCH_1), /* Strong Access Ordering (powerpc) */
DECLARE_VMA_BIT_ALIAS(GROWSUP, ARCH_1), /* parisc */
DECLARE_VMA_BIT_ALIAS(SPARC_ADI, ARCH_1), /* sparc64 */
DECLARE_VMA_BIT_ALIAS(ARM64_BTI, ARCH_1), /* arm64 */
DECLARE_VMA_BIT_ALIAS(ARCH_CLEAR, ARCH_1), /* sparc64, arm64 */
DECLARE_VMA_BIT_ALIAS(MAPPED_COPY, ARCH_1), /* !CONFIG_MMU */
Other vma_test() changes look fine to me: just fixed INIT_VM_FLAG()
masks matching their VMA_*_BIT :)
Cheers, Lance
> goto out;
> }
> }
>@@ -918,7 +918,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
> }
>
> /* Does the application expect PROT_READ to imply PROT_EXEC */
>- if (rier && (vma->vm_flags & VM_MAYEXEC))
>+ if (rier && vma_test(vma, VMA_MAYEXEC_BIT))
> prot |= PROT_EXEC;
>
> /*
>--
>2.54.0
>
>
^ permalink raw reply
* Re: [PATCH] vdpa/mlx5: fix wrong list iterated in add_direct_chain error path
From: Dragos Tatulea @ 2026-07-01 15:02 UTC (permalink / raw)
To: lirongqing, Michael S . Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Kees Cook, Rosen Penev, Parav Pandit,
Eli Cohen, virtualization, linux-kernel
In-Reply-To: <20260701113608.1972-1-lirongqing@baidu.com>
On 01.07.26 13:36, lirongqing wrote:
> From: Li RongQing <lirongqing@baidu.com>
>
> In add_direct_chain(), newly allocated direct MR entries are added to
> the local list 'tmp', which is spliced into mr->head only on success.
> On the error path, the cleanup loop was incorrectly iterating over
> mr->head instead of tmp.
>
> Fix by iterating over 'tmp' in the err_alloc cleanup path.
>
> Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code")
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> ---
> drivers/vdpa/mlx5/core/mr.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> index 6d02ccf..1a224f0 100644
> --- a/drivers/vdpa/mlx5/core/mr.c
> +++ b/drivers/vdpa/mlx5/core/mr.c
> @@ -480,7 +480,7 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
> return 0;
>
> err_alloc:
> - list_for_each_entry_safe(dmr, n, &mr->head, list) {
> + list_for_each_entry_safe(dmr, n, &tmp, list) {
> list_del_init(&dmr->list);
> unmap_direct_mr(mvdev, dmr);
> kfree(dmr);
Thanks for your patch!
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Thanks,
Dragos
^ permalink raw reply
* Re: [PATCH] vdpa/mlx5: fix wrong list iterated in add_direct_chain error path
From: Eugenio Perez Martin @ 2026-07-01 13:44 UTC (permalink / raw)
To: lirongqing
Cc: Dragos Tatulea, Michael S . Tsirkin, Jason Wang, Xuan Zhuo,
Kees Cook, Rosen Penev, Parav Pandit, Eli Cohen, virtualization,
linux-kernel
In-Reply-To: <20260701113608.1972-1-lirongqing@baidu.com>
On Wed, Jul 1, 2026 at 1:36 PM lirongqing <lirongqing@baidu.com> wrote:
>
> From: Li RongQing <lirongqing@baidu.com>
>
> In add_direct_chain(), newly allocated direct MR entries are added to
> the local list 'tmp', which is spliced into mr->head only on success.
> On the error path, the cleanup loop was incorrectly iterating over
> mr->head instead of tmp.
>
> Fix by iterating over 'tmp' in the err_alloc cleanup path.
>
> Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code")
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Thanks!
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> ---
> drivers/vdpa/mlx5/core/mr.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> index 6d02ccf..1a224f0 100644
> --- a/drivers/vdpa/mlx5/core/mr.c
> +++ b/drivers/vdpa/mlx5/core/mr.c
> @@ -480,7 +480,7 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
> return 0;
>
> err_alloc:
> - list_for_each_entry_safe(dmr, n, &mr->head, list) {
> + list_for_each_entry_safe(dmr, n, &tmp, list) {
> list_del_init(&dmr->list);
> unmap_direct_mr(mvdev, dmr);
> kfree(dmr);
> --
> 2.9.4
>
^ permalink raw reply
* Re: [PATCH v2 1/2] tools/virtio: Add missing compat definitions for vhost_net_test
From: SJ Park @ 2026-07-01 13:36 UTC (permalink / raw)
To: Yichong Chen
Cc: SJ Park, mst, jasowang, xuanzhuo, eperezma, akpm, rppt, ljs,
pabeni, linux-kernel, virtualization
In-Reply-To: <20260629022124.131894-2-chenyichong@uniontech.com>
On Mon, 29 Jun 2026 10:21:23 +0800 Yichong Chen <chenyichong@uniontech.com> wrote:
> vhost_net_test builds virtio_ring.c in userspace.
>
> Recent virtio headers pull in helper headers that are not provided by
> the tools/virtio compatibility layer, including asm/percpu_types.h,
> linux/completion.h, linux/mod_devicetable.h and
> linux/virtio_features.h.
>
> Add the missing compat definitions and the DMA attribute used by the
> current virtio ring code.
I confirmed this patch fixes the build on my setup.
>
> Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Tested-by: SJ Park <sj@kernel.org>
Thanks,
SJ
[...]
^ permalink raw reply
* Re: [PATCH v2 2/2] tools/include: Include stdint.h for SIZE_MAX in overflow.h
From: SJ Park @ 2026-07-01 13:35 UTC (permalink / raw)
To: Yichong Chen
Cc: SJ Park, mst, jasowang, xuanzhuo, eperezma, akpm, rppt, ljs,
pabeni, linux-kernel, virtualization
In-Reply-To: <20260629022124.131894-3-chenyichong@uniontech.com>
On Mon, 29 Jun 2026 10:21:24 +0800 Yichong Chen <chenyichong@uniontech.com> wrote:
> tools/include/linux/overflow.h uses SIZE_MAX in its size helper
> functions.
>
> Include stdint.h so tools users that include overflow.h without another
> SIZE_MAX provider can build.
On the latest mm-new reverting this patch (for test), I was able to build
tools/virtio.
git checkout akpm.korg.mm/mm-new
[...]
HEAD is now at f5ea2fbe68e0c mm/swap, PM: hibernate: atomically replace hibernation pin
$ git revert 9d462d8b9b705548451325ee4376dfd549e14aa2 -s --no-edit
[detached HEAD f2202247e38d9] Revert "tools/include: include stdint.h for SIZE_MAX in overflow.h"
Date: Wed Jul 1 06:33:03 2026 -0700
1 file changed, 1 deletion(-)
$ make -C tools/virtio/ clean
make: Entering directory '/home/lkhack/worktree.linux/tools/virtio'
rm -f *.o vringh_test virtio_test vhost_net_test vhost_test/*.o \
vhost_test/.*.cmd vhost_test/Module.symvers \
vhost_test/modules.order *.d
make: Leaving directory '/home/lkhack/worktree.linux/tools/virtio'
$ make -C tools/virtio/ test
make: Entering directory '/home/lkhack/worktree.linux/tools/virtio'
cc -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h -mfunction-return=thunk -fcf-protection=none -mindirect-branch-register -pthread -c -o virtio_test.o virtio_test.c
cc -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h -mfunction-return=thunk -fcf-protection=none -mindirect-branch-register -pthread -c -o virtio_ring.o ../../drivers/virtio/virtio_ring.c
cc -pthread virtio_test.o virtio_ring.o -o virtio_test
cc -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h -mfunction-return=thunk -fcf-protection=none -mindirect-branch-register -pthread -c -o vringh_test.o vringh_test.c
cc -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h -mfunction-return=thunk -fcf-protection=none -mindirect-branch-register -pthread -c -o vringh.o ../../drivers/vhost/vringh.c
cc -pthread vringh_test.o vringh.o virtio_ring.o -o vringh_test
cc -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h -mfunction-return=thunk -fcf-protection=none -mindirect-branch-register -pthread -c -o vhost_net_test.o vhost_net_test.c
cc -pthread vhost_net_test.o virtio_ring.o -o vhost_net_test
make: Leaving directory '/home/lkhack/worktree.linux/tools/virtio'
Am I missing something?
>
> Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
> ---
> tools/include/linux/overflow.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/tools/include/linux/overflow.h b/tools/include/linux/overflow.h
> index 3427d7880326..98963688143f 100644
> --- a/tools/include/linux/overflow.h
> +++ b/tools/include/linux/overflow.h
> @@ -1,4 +1,5 @@
> /* SPDX-License-Identifier: GPL-2.0 OR MIT */
> +#include <stdint.h>
> #ifndef __LINUX_OVERFLOW_H
> #define __LINUX_OVERFLOW_H
Shouldn't the include placed after #define __LINUX_OVERFLOW_H ?
Thanks,
SJ
[...]
^ permalink raw reply
* [PATCH] vdpa/mlx5: fix wrong list iterated in add_direct_chain error path
From: lirongqing @ 2026-07-01 11:36 UTC (permalink / raw)
To: Dragos Tatulea, Michael S . Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Kees Cook, Rosen Penev, Parav Pandit,
Eli Cohen, virtualization, linux-kernel
Cc: Li RongQing
From: Li RongQing <lirongqing@baidu.com>
In add_direct_chain(), newly allocated direct MR entries are added to
the local list 'tmp', which is spliced into mr->head only on success.
On the error path, the cleanup loop was incorrectly iterating over
mr->head instead of tmp.
Fix by iterating over 'tmp' in the err_alloc cleanup path.
Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
drivers/vdpa/mlx5/core/mr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 6d02ccf..1a224f0 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -480,7 +480,7 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
return 0;
err_alloc:
- list_for_each_entry_safe(dmr, n, &mr->head, list) {
+ list_for_each_entry_safe(dmr, n, &tmp, list) {
list_del_init(&dmr->list);
unmap_direct_mr(mvdev, dmr);
kfree(dmr);
--
2.9.4
^ permalink raw reply related
* Re: [PATCH v2 2/3] drm/virtio: honor blob_alignment requirements
From: Alyssa Ross @ 2026-07-01 11:10 UTC (permalink / raw)
To: Sergio Lopez
Cc: Chia-I Wu, Jason Wang, Michael S. Tsirkin, Eugenio Pérez,
Xuan Zhuo, linux-kernel, Simona Vetter, Dmitry Osipenko,
Thomas Zimmermann, David Airlie, Gurchetan Singh, Gerd Hoffmann,
virtualization, dri-devel, Maxime Ripard, Maarten Lankhorst
In-Reply-To: <20260428194450.518296-3-slp@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]
On Tue, Apr 28, 2026 at 09:44:49PM +0200, Sergio Lopez wrote:
> If VIRTIO_GPU_F_BLOB_ALIGNMENT has been negotiated, blob size must be
> aligned to blob_alignment. Validate this in verify_blob() so that
> invalid requests are rejected early.
>
> Signed-off-by: Sergio Lopez <slp@redhat.com>
FYI: this change breaks crosvm, which is squatting the 5 and 6 values
of VIRTIO_GPU_F_* with different meanings. I've reported it as a
crosvm bug, so hopefully it can be taken care of there.
https://issuetracker.google.com/issues/529852979
> ---
> drivers/gpu/drm/virtio/virtgpu_ioctl.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> index c33c057365f8..d0c4edf1eaf4 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> @@ -489,6 +489,11 @@ static int verify_blob(struct virtio_gpu_device *vgdev,
> params->size = rc_blob->size;
> params->blob = true;
> params->blob_flags = rc_blob->blob_flags;
> +
> + if (vgdev->has_blob_alignment &&
> + !IS_ALIGNED(params->size, vgdev->blob_alignment))
> + return -EINVAL;
> +
> return 0;
> }
>
> --
> 2.53.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/7] list: Add mutable iterator variants
From: Kaitao Cheng @ 2026-07-01 11:07 UTC (permalink / raw)
To: Jani Nikula, David Laight, Christian König,
David Hildenbrand (Arm), Alexei Starovoitov
Cc: Andrew Morton, Jens Axboe, Tejun Heo, Alexander Viro,
Christian Brauner, Daniel Borkmann, Andrii Nakryiko,
Johannes Weiner, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Paul Moore, Andy Shevchenko,
Paul E. McKenney, Shakeel Butt, David Howells, Simona Vetter,
Randy Dunlap, Luca Ceresoli, Philipp Stanner, linux-block,
linux-kernel, cgroups, linux-ntfs-dev, linux-fsdevel, io-uring,
audit, bpf, netdev, dri-devel, linux-perf-users,
linux-trace-kernel, kexec, live-patching, linux-modules,
linux-crypto, linux-pm, rcu, sched-ext, linux-mm, virtualization,
damon, llvm, Kaitao Cheng, Muchun Song
In-Reply-To: <734f66ca51485ee3ec9788c0eaaead681e00664b@intel.com>
在 2026/6/25 19:00, Jani Nikula 写道:
> On Thu, 25 Jun 2026, Kaitao Cheng <kaitao.cheng@linux.dev> wrote:
>> 在 2026/6/24 22:23, David Laight 写道:
>>> On Wed, 24 Jun 2026 15:23:47 +0200
>>> Christian König <christian.koenig@amd.com> wrote:
>>>> On 6/24/26 15:14, Kaitao Cheng wrote:
>>>>> 在 2026/6/22 16:42, David Laight 写道:
>>>>>> On Mon, 22 Jun 2026 12:05:31 +0800
>>>>>> Kaitao Cheng <kaitao.cheng@linux.dev> wrote:
>>>>>>
>>>>>>> From: Kaitao Cheng <chengkaitao@kylinos.cn>
>>>>>>>
>>>>>>> The list_for_each*_safe() helpers are used when the loop body may
>>>>>>> remove the current entry. Their API exposes the temporary cursor at
>>>>>>> every call site, even though most users only need it for the iterator
>>>>>>> implementation and never reference it in the loop body.
>>>>>>>
>>>>>>> Add *_mutable() variants for list and hlist iteration. The new helpers
>>>>>>> support both forms: callers may keep passing an explicit temporary cursor
>>>>>>> when they need to inspect or reset it, or omit it and let the helper use
>>>>>>> a unique internal cursor.
>>>>>>
>>>>>> I'm not really sure 'mutable' means anything either.
>>>>>> It is possible to make it valid for the loop body (or even other threads)
>>>>>> to delete arbitrary list items - but that needs significant extra overheads.
>>>>>>
>>>>>> It might be worth doing something that doesn't need the extra variable,
>>>>>> but there is little point doing all the churn just to rename things.
>>>>>>
>>>>>>>
>>>>>>> This makes call sites that only mutate the list through the current entry
>>>>>>> less noisy, while keeping the existing *_safe() helpers available for
>>>>>>> compatibility.
>>>>>>>
>>>>>>> Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
>>>>>>> ---
>>>>>>> include/linux/list.h | 269 +++++++++++++++++++++++++++++++++++++------
>>>>>>> 1 file changed, 231 insertions(+), 38 deletions(-)
>>>>>>>
>>>>>>> diff --git a/include/linux/list.h b/include/linux/list.h
>>>>>>> index 09d979976b3b..1081def7cea9 100644
>>>>>>> --- a/include/linux/list.h
>>>>>>> +++ b/include/linux/list.h
>>>>>>> @@ -7,6 +7,7 @@
>>>>>>> #include <linux/stddef.h>
>>>>>>> #include <linux/poison.h>
>>>>>>> #include <linux/const.h>
>>>>>>> +#include <linux/args.h>
>>>>>>>
>>>>>>> #include <asm/barrier.h>
>>>>>>>
>>>>>>> @@ -763,28 +764,72 @@ static inline void list_splice_tail_init(struct list_head *list,
>>>>>>> #define list_for_each_prev(pos, head) \
>>>>>>> for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev)
>>>>>>>
>>>>>>> -/**
>>>>>>> - * list_for_each_safe - iterate over a list safe against removal of list entry
>>>>>>> - * @pos: the &struct list_head to use as a loop cursor.
>>>>>>> - * @n: another &struct list_head to use as temporary storage
>>>>>>> - * @head: the head for your list.
>>>>>>> +/*
>>>>>>> + * list_for_each_safe is an old interface, use list_for_each_mutable instead.
>>>>>>> */
>>>>>>> #define list_for_each_safe(pos, n, head) \
>>>>>>> for (pos = (head)->next, n = pos->next; \
>>>>>>> !list_is_head(pos, (head)); \
>>>>>>> pos = n, n = pos->next)
>>>>>>>
>>>>>>> +#define __list_for_each_mutable_internal(pos, tmp, head) \
>>>>>>> + for (typeof(pos) tmp = (pos = (head)->next)->next; \
>>>>>>
>>>>>> Use auto
>>>>>>
>>>>>>> + !list_is_head(pos, (head)); \
>>>>>>> + pos = tmp, tmp = pos->next)
>>>>>>> +
>>>>>>> +#define __list_for_each_mutable1(pos, head) \
>>>>>>> + __list_for_each_mutable_internal(pos, __UNIQUE_ID(next), head)
>>>>>>> +
>>>>>>> +#define __list_for_each_mutable2(pos, next, head) \
>>>>>>> + list_for_each_safe(pos, next, head)
>>>>>>> +
>>>>>>> /**
>>>>>>> - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
>>>>>>> + * list_for_each_mutable - iterate over a list safe against entry removal
>>>>>>> * @pos: the &struct list_head to use as a loop cursor.
>>>>>>> - * @n: another &struct list_head to use as temporary storage
>>>>>>> - * @head: the head for your list.
>>>>>>> + * @...: either (head) or (next, head)
>>>>>>> + *
>>>>>>> + * next: another &struct list_head to use as optional temporary storage.
>>>>>>> + * The temporary cursor is internal unless explicitly supplied by
>>>>>>> + * the caller.
>>>>>>> + * head: the head for your list.
>>>>>>> + */
>>>>>>> +#define list_for_each_mutable(pos, ...) \
>>>>>>> + CONCATENATE(__list_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \
>>>>>>> + (pos, __VA_ARGS__)
>>>>>>
>>>>>> The variable argument count logic really just slows down compilation.
>>>>>> Maybe there aren't enough copies of this code to make that significant.
>>>>>> But just because you can do it doesn't mean it is a gooD idea.
>>>>>> I'm also not sure it really adds anything to the readability.
>>>>>>
>>>>>> And, it you are going to make the middle argument optional there is
>>>>>> no need to change the macro name.
>>>>>
>>>>> Christian König and Jani Nikula also disagree with the variadic-argument
>>>>> implementation approach. If we abandon that method, it means we will
>>>>> inevitably need to add some new macros. If mutable is not a good name,
>>>>> suggestions for better alternatives would be welcome; coming up with a
>>>>> suitable name is indeed rather tricky.
>>>>
>>>> I don't think you need to add a new macro for the specific use case that people want to modify the next element of the iteration.
>>>>
>>>> If I remember your numbers correctly that is a really corner case and keeping using the existing *_safe() macros for that sounds perfectly fine to me.
>>>
>>> IIRC currently you have a choice of either:
>>> define Item that can't be deleted
>>> list_for_each() The current item.
>>> list_for_each_safe() The next item.
>>> There is also likely to be code that updates the variables to allow
>>> for other scenarios.
>>>
>>> Note that if increase a reference count and release a lock then list_for_each()
>>> is likely safer than list_for_each_safe() :-)
>>>
>>> list.h has 9 variants of the 'safe' loop.
>>> The bloat of another 9 is getting excessive.
>>>
>>> It has to be said that this is one of my least favourite type of list...
>>
>> Hi Christian König, David Laight, Jani Nikula, David Hildenbrand,
>> Andy Shevchenko, Alexei Starovoitov
>>
>> For ease of discussion, I need to summarize the currently possible
>> approaches and briefly describe their respective pros and cons,
>> using the list_for_each_entry* interfaces as examples.
>>
>> 1. Add list_for_each_entry_mutable, while keeping list_for_each_entry
>> and list_for_each_entry_safe unchanged. list_for_each_entry_mutable
>> would be used specifically for safe deletion scenarios that do not
>> need to expose the temporary cursor externally. The code can refer to
>> the v1 version.
>>
>> Pros: Does not depend on immediate per-subsystem adaptation and can be
>> merged directly.
>> Cons: Requires adding a whole set of mutable interfaces, which makes the
>> code somewhat redundant.
>
> Seems fine, and the original _safe naming is ambiguous anyway.
>
>> 2. Directly optimize away the temporary cursor in list_for_each_entry_safe
>> and define it inside the loop instead, changing the interface from four
>> arguments to three.
>>
>> Pros: Does not add redundant interfaces.
>> Cons: (1) Users need to manually update special cases that use the
>> traversal variable of list_for_each_entry_safe, the new
>> list_for_each_entry_safe would no longer apply there and would
>> need to be open-coded.
>> (2) Because the macro arguments changes, all list_for_each_entry_safe
>> callers would need to be modified and merged together, making it
>> difficult to merge such a large amount of code at once.
>
> This won't fly because there are literally thousands of
> list_for_each_entry_safe() users.
>
>> 3. Use a variadic macro approach to optimize list_for_each_entry_safe,
>> so that it supports both three and four arguments.
>>
>> Pros: (1) Does not add redundant interfaces.
>> (2) Does not depend on immediate per-subsystem adaptation and can
>> be merged directly.
>> Cons: (1) Increases compile time.
>> (2) Makes the interface harder for users to use.
>
> Basically I'm against any variadic macro tricks where the optional
> argument is not the last argument. That's just way too surprising, and
> goes against common practice in just about all other languages.
>
>> 4. Optimize list_for_each_entry by defining the temporary cursor internally,
>> making it compatible with the functionality of list_for_each_entry_safe.
>> The code can refer to the v2 version.
>>
>> Pros: (1) Does not add redundant interfaces.
>> (2) The number of externally visible arguments of list_for_each_entry
>> remains unchanged, still three.
>> Cons: (1) list_for_each_entry and list_for_each_entry_safe would be merged
>> into one, and list_for_each_entry_safe would gradually be deprecated.
>> (2) Users need to manually update special cases that use the traversal
>> variable of list_for_each_entry, the new list_for_each_entry would no
>> longer apply there and would need to be open-coded. There are 15 such
>> cases in total.
>
> This sounds good to me, though I take it there's some code size increase
> and/or performance penalty?
>
> Maybe the 15 cases are questionable anyway?
>
>> 5. Use a variadic macro approach to optimize list_for_each_entry, so that
>> it supports both three and four arguments.
>>
>> Pros: (1) Does not add redundant interfaces.
>> (2) Does not depend on immediate per-subsystem adaptation and can be
>> merged directly.
>> Cons: (1) Increases compile time.
>> (2) list_for_each_entry and list_for_each_entry_safe would be merged
>> into one, and list_for_each_entry_safe would gradually be deprecated.
>
> Please don't do the macro tricks.
>
>> 6. Make no changes, keep the current logic unchanged, and close the current
>> email discussion.
>
> I like hiding the temporary stuff when possible.
>
> BR,
> Jani.
Hi all,
If there are no objections, I will make the changes using the first approach.
Hi David Laight,
You previously expressed a different opinion. Do you have any further comments
on the current proposed approach?
--
Thanks
Kaitao Cheng
^ permalink raw reply
* Re: [PATCH net 1/2] vsock/virtio: collapse receive queue under memory pressure
From: Stefano Garzarella @ 2026-07-01 10:13 UTC (permalink / raw)
To: Paolo Abeni
Cc: netdev, Jason Wang, Jakub Kicinski, Michael S. Tsirkin, kvm,
virtualization, Xuan Zhuo, Eric Dumazet, Simon Horman,
linux-kernel, Stefan Hajnoczi, David S. Miller,
Eugenio Pérez, stable, Brien Oberstein
In-Reply-To: <6a6be4b0-e02d-46ca-b8bf-c27bd681d253@redhat.com>
On Tue, Jun 30, 2026 at 11:53:04AM +0200, Paolo Abeni wrote:
>On 6/26/26 3:48 PM, Stefano Garzarella wrote:
>> From: Stefano Garzarella <sgarzare@redhat.com>
>>
>> When many small packets accumulate in the receive queue, the skb overhead
>> can exceed buf_alloc even while the payload is within bounds. This causes
>> virtio_transport_inc_rx_pkt() to reject packets, leading to connection
>> resets during large transfers under backpressure.
>>
>> The issue was reported by Brien, who has a reproducer, but it is also
>> easily reproducible with iperf-vsock [1] using a small packet size:
>>
>> iperf3 --vsock -c $CID -l 129
>>
>> which fails immediately without this patch but with commit 059b7dbd20a6
>> ("vsock/virtio: fix potential unbounded skb queue").
>>
>> Inspired by TCP's tcp_collapse() which solves a similar problem, add
>> virtio_transport_collapse_rx_queue() that walks the receive queue and
>> re-copies data into compact linear skbs to reduce the overhead.
>>
>> The collapse is triggered from virtio_transport_recv_enqueue() when
>> virtio_transport_inc_rx_pkt() fails. A pre-scan counts the eligible bytes
>> to size each allocation precisely, avoiding waste for isolated small
>> packets. Partially consumed skbs are kept as-is to preserve
>> buf_used/fwd_cnt accounting, EOM-marked skbs to maintain SEQPACKET
>> message boundaries, and skbs already larger than the collapse target
>> because they already have a good data-to-overhead ratio.
>>
>> [1] https://github.com/stefano-garzarella/iperf-vsock
>>
>> Fixes: 059b7dbd20a6 ("vsock/virtio: fix potential unbounded skb queue")
>> Cc: stable@vger.kernel.org
>> Reported-by: Brien Oberstein <brienpub@gmail.com>
>> Closes: https://lore.kernel.org/netdev/618701dd023e$063de350$12b9a9f0$@gmail.com/
>> Tested-by: Brien Oberstein <brienpub@gmail.com>
>> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
>> ---
>> net/vmw_vsock/virtio_transport_common.c | 148 +++++++++++++++++++++++-
>> 1 file changed, 146 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
>> index 09475007165b..304ea424995d 100644
>> --- a/net/vmw_vsock/virtio_transport_common.c
>> +++ b/net/vmw_vsock/virtio_transport_common.c
>> @@ -420,6 +420,137 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
>> return ret;
>> }
>>
>> +static bool virtio_transport_can_collapse(struct sk_buff *skb,
>> + unsigned int size)
>
>Why passing a `size` argument here? AFAICS the actual argument is always
>a constant and IMHO rightfully so.
This comes from a previous implementation where this was not constant.
With the current code, I agree that a macro should be better.
I'll fix it.
>
>> +{
>> + /* skbs that are partially consumed, mark a SEQPACKET message boundary,
>> + * or are already large enough should not be collapsed: they either
>> + * need special accounting, carry protocol state, or already have a
>> + * good data-to-overhead ratio.
>> + */
>> + if (VIRTIO_VSOCK_SKB_CB(skb)->offset)
>> + return false;
>> + if (le32_to_cpu(virtio_vsock_hdr(skb)->flags) & VIRTIO_VSOCK_SEQ_EOM)
>> + return false;
>> + if (skb->len >= size)
>> + return false;
>> + return true;
>> +}
>> +
>> +/* Iterate through the packets in the queue starting from the current skb to
>> + * count the number of bytes we can collapse.
>> + */
>> +static unsigned int
>> +virtio_transport_collapse_size(struct sk_buff *skb,
>> + struct sk_buff_head *queue,
>> + unsigned int max_size)
>> +{
>> + unsigned int target = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
>> +
>> + while ((skb = skb_peek_next(skb, queue)) &&
>> + virtio_transport_can_collapse(skb, max_size)) {
>> + unsigned int len = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
>> +
>> + if (len > max_size - target)
>> + return target;
>> +
>> + target += len;
>> + }
>> +
>> + return target;
>> +}
>> +
>> +/* Called under lock_sock when skb overhead exceeds the budget. */
>> +static void virtio_transport_collapse_rx_queue(struct virtio_vsock_sock *vvs)
>> +{
>> + /* Use the same linear allocation threshold as virtio_vsock_alloc_skb()
>> + * to avoid adding pressure on the page allocator.
>> + */
>> + unsigned int collapse_max = SKB_MAX_ORDER(VIRTIO_VSOCK_SKB_HEADROOM,
>> + PAGE_ALLOC_COSTLY_ORDER);
>> + struct sk_buff *skb, *next_skb, *new_skb = NULL;
>> + struct sk_buff_head new_queue;
>> +
>> + __skb_queue_head_init(&new_queue);
>> +
>> + skb_queue_walk_safe(&vvs->rx_queue, skb, next_skb) {
>
>If the queue is relevantly big, walking all of it may take a significant
>amount of time/cache misses and causes traffic burstines. I think you
>could add an additional stop condition, i.e. when the current queue size
>is below a reasonable threshold (allowing the current packet to be
>inserted plus some more slack).
Makes sense, any suggestion on the threshold?
I was thinking something like this: merge until we have space for at
least 2 skbs (because for now we estimate the overhead based on the
number of skbs, but in the future I'd like to support truesize), but
still trying to fill collapse_max as much as possible.
Does that make sense, or should we be more aggressive?
>
>/P
>
>> + struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb);
>> + u32 src_off = VIRTIO_VSOCK_SKB_CB(skb)->offset;
>> + u32 src_len = skb->len - src_off;
>> + bool keep = false;
>> +
>> + if (!virtio_transport_can_collapse(skb, collapse_max)) {
>
>Minor nit, possibly something alike the following lead to more
>compact/more readable code:
>
>
> keep = !virtio_transport_can_collapse(skb, collapse_max);
> if (keep) {
>
Yeah, so I can remove the initialization to false. I'll change it.
>> + /* Finalize pending collapsed skb to preserve packet
>> + * ordering.
>> + */
>> + if (new_skb) {
>> + __skb_queue_tail(&new_queue, new_skb);
>> + new_skb = NULL;
>> + }
>> + keep = true;
>> + goto next;
>> + }
>> +
>> + /* Finalize if this packet won't fit in the remaining tailroom,
>> + * so we can allocate a right-sized new_skb.
>> + */
>> + if (new_skb && src_len > skb_tailroom(new_skb)) {
>> + __skb_queue_tail(&new_queue, new_skb);
>> + new_skb = NULL;
>
>Possibly introduce an helper for the above 2 statements?
Do you mean something like this?
static void virtio_transport_queue_skb(struct sk_buff_head *queue,
struct sk_buff **skb)
{
__skb_queue_tail(queue, *skb);
*skb = NULL;
}
Not sure, just for 2 places, but if you prefer it, I can change.
Thanks,
Stefano
^ permalink raw reply
* [linux-next:master] BUILD REGRESSION be5c93fa674f0fc3c8f359c2143abce6bbb422e6
From: kernel test robot @ 2026-07-01 10:12 UTC (permalink / raw)
To: Andrew Morton
Cc: Linux Memory Management List, apparmor, linux-arm-kernel,
linux-input, linux-remoteproc, linux-rockchip, linux-usb,
virtualization, Mark Brown
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: be5c93fa674f0fc3c8f359c2143abce6bbb422e6 Add linux-next specific files for 20260630
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202607010945.6lDjBFTU-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202607011210.PI7XDDb1-lkp@intel.com
drivers/remoteproc/remoteproc_internal.h:131:5: error: incompatible integer to pointer conversion assigning to 'void *' from 'int' [-Wint-conversion]
drivers/remoteproc/remoteproc_internal.h:131:7: error: call to undeclared function 'ioremap_prot'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
drivers/remoteproc/remoteproc_internal.h:146:2: error: call to undeclared function 'iounmap'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
mm/hugetlb.c:3095:4: warning: array subscript -1 is below array bounds of 'struct list_head[1]' [-Warray-bounds]
Unverified Error/Warning (likely false positive, kindly check if interested):
https://lore.kernel.org/oe-kbuild/202607010826.2wLg1q08-lkp@intel.com
https://lore.kernel.org/oe-kbuild/202607011451.icwPyCIk-lkp@intel.com
drivers/hid/hid-asus.c:620 asus_kbd_backlight_work() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/i2c/busses/i2c-rk3x.c:1131 rk3x_i2c_xfer_common() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/rpmsg/rpmsg_char.c:236 rpmsg_eptdev_read_iter() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/usb/host/ehci-hub.c:1080 ehci_hub_control() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/usb/host/ehci-hub.c:691 ehci_hub_status_data() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/usb/host/ehci-sched.c:1290 itd_urb_transaction() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/usb/host/ehci-sched.c:2093 sitd_urb_transaction() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/virtio/virtio_input.c:333 virtinput_probe() error: calling 'spin_unlock_irqrestore()' with bogus flags
drivers/virtio/virtio_input.c:56 virtinput_recv_events() error: calling 'spin_unlock_irqrestore()' with bogus flags
security/apparmor/apparmorfs.c:590 policy_update() warn: passing zero to 'PTR_ERR'
Error/Warning ids grouped by kconfigs:
recent_errors
|-- s390-randconfig-002-20260701
| |-- drivers-remoteproc-remoteproc_internal.h:error:call-to-undeclared-function-ioremap_prot-ISO-C99-and-later-do-not-support-implicit-function-declarations
| |-- drivers-remoteproc-remoteproc_internal.h:error:call-to-undeclared-function-iounmap-ISO-C99-and-later-do-not-support-implicit-function-declarations
| `-- drivers-remoteproc-remoteproc_internal.h:error:incompatible-integer-to-pointer-conversion-assigning-to-void-from-int
|-- sparc-randconfig-r131-20260701
| `-- mm-hugetlb.c:warning:array-subscript-is-below-array-bounds-of-struct-list_head
`-- x86_64-randconfig-161-20260701
|-- drivers-hid-hid-asus.c-asus_kbd_backlight_work()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-i2c-busses-i2c-rk3x.c-rk3x_i2c_xfer_common()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-rpmsg-rpmsg_char.c-rpmsg_eptdev_read_iter()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-usb-host-ehci-hub.c-ehci_hub_control()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-usb-host-ehci-hub.c-ehci_hub_status_data()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-usb-host-ehci-sched.c-itd_urb_transaction()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-usb-host-ehci-sched.c-sitd_urb_transaction()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-virtio-virtio_input.c-virtinput_probe()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
|-- drivers-virtio-virtio_input.c-virtinput_recv_events()-error:calling-spin_unlock_irqrestore()-with-bogus-flags
`-- security-apparmor-apparmorfs.c-policy_update()-warn:passing-zero-to-PTR_ERR
elapsed time: 823m
configs tested: 227
configs skipped: 6
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc allyesconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc randconfig-001-20260701 gcc-12.5.0
arc randconfig-002-20260701 gcc-12.5.0
arm allnoconfig clang-17
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm allyesconfig gcc-16.1.0
arm defconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001-20260701 gcc-12.5.0
arm randconfig-002-20260701 gcc-12.5.0
arm randconfig-003-20260701 gcc-12.5.0
arm randconfig-004-20260701 gcc-12.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260701 gcc-12.5.0
arm64 randconfig-001-20260701 gcc-16.1.0
arm64 randconfig-002-20260701 clang-17
arm64 randconfig-002-20260701 gcc-12.5.0
arm64 randconfig-003-20260701 gcc-12.5.0
arm64 randconfig-004-20260701 clang-17
arm64 randconfig-004-20260701 gcc-12.5.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260701 gcc-10.5.0
csky randconfig-001-20260701 gcc-12.5.0
csky randconfig-002-20260701 gcc-12.5.0
hexagon allmodconfig clang-23
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-16.1.0
hexagon defconfig clang-23
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260701 clang-23
hexagon randconfig-001-20260701 gcc-11.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260701 clang-17
hexagon randconfig-002-20260701 gcc-11.5.0
i386 allmodconfig clang-22
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 allyesconfig gcc-14
i386 buildonly-randconfig-001-20260701 clang-22
i386 buildonly-randconfig-002-20260701 clang-22
i386 buildonly-randconfig-003-20260701 clang-22
i386 buildonly-randconfig-004-20260701 clang-22
i386 buildonly-randconfig-005-20260701 clang-22
i386 buildonly-randconfig-006-20260701 clang-22
i386 defconfig clang-22
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260701 clang-22
i386 randconfig-002-20260701 clang-22
i386 randconfig-003-20260701 clang-22
i386 randconfig-004-20260701 clang-22
i386 randconfig-005-20260701 clang-22
i386 randconfig-006-20260701 clang-22
i386 randconfig-007-20260701 clang-22
i386 randconfig-011-20260701 gcc-14
i386 randconfig-012-20260701 gcc-14
i386 randconfig-013-20260701 gcc-14
i386 randconfig-014-20260701 gcc-14
i386 randconfig-015-20260701 gcc-14
i386 randconfig-016-20260701 gcc-14
i386 randconfig-017-20260701 gcc-14
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-20
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260701 clang-23
loongarch randconfig-001-20260701 gcc-11.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260701 clang-19
loongarch randconfig-002-20260701 gcc-11.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k allyesconfig gcc-16.1.0
m68k defconfig clang-23
m68k defconfig gcc-16.1.0
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
microblaze defconfig gcc-16.1.0
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
mips gpr_defconfig clang-23
nios2 allmodconfig clang-20
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-23
nios2 defconfig gcc-11.5.0
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260701 gcc-11.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260701 gcc-11.5.0
nios2 randconfig-002-20260701 gcc-8.5.0
openrisc allmodconfig clang-20
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-16.1.0
parisc allyesconfig clang-17
parisc allyesconfig gcc-16.1.0
parisc defconfig gcc-16.1.0
parisc randconfig-001-20260701 clang-17
parisc randconfig-001-20260701 gcc-13.4.0
parisc randconfig-002-20260701 clang-17
parisc randconfig-002-20260701 gcc-15.2.0
parisc64 defconfig clang-23
parisc64 defconfig gcc-16.1.0
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-16.1.0
powerpc randconfig-001-20260701 clang-17
powerpc randconfig-001-20260701 gcc-8.5.0
powerpc randconfig-002-20260701 clang-17
powerpc randconfig-002-20260701 clang-23
powerpc64 randconfig-001-20260701 clang-17
powerpc64 randconfig-002-20260701 clang-17
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001-20260701 clang-23
riscv randconfig-002-20260701 clang-23
s390 allmodconfig clang-17
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001-20260701 clang-23
s390 randconfig-002-20260701 clang-23
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allnoconfig gcc-16.1.0
sh allyesconfig clang-17
sh allyesconfig gcc-16.1.0
sh defconfig gcc-14
sh randconfig-001-20260701 clang-23
sh randconfig-002-20260701 clang-23
sparc allnoconfig clang-23
sparc allnoconfig gcc-16.1.0
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260701 gcc-13.4.0
sparc randconfig-002-20260701 gcc-13.4.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260701 gcc-13.4.0
sparc64 randconfig-002-20260701 gcc-13.4.0
um allmodconfig clang-17
um allnoconfig clang-17
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260701 gcc-13.4.0
um randconfig-002-20260701 gcc-13.4.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001-20260701 clang-22
x86_64 buildonly-randconfig-001-20260701 gcc-14
x86_64 buildonly-randconfig-002-20260701 clang-22
x86_64 buildonly-randconfig-003-20260701 clang-22
x86_64 buildonly-randconfig-004-20260701 clang-22
x86_64 buildonly-randconfig-004-20260701 gcc-14
x86_64 buildonly-randconfig-005-20260701 clang-22
x86_64 buildonly-randconfig-006-20260701 clang-22
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001-20260701 clang-22
x86_64 randconfig-001-20260701 gcc-14
x86_64 randconfig-002-20260701 gcc-14
x86_64 randconfig-003-20260701 gcc-14
x86_64 randconfig-004-20260701 clang-22
x86_64 randconfig-004-20260701 gcc-14
x86_64 randconfig-005-20260701 gcc-14
x86_64 randconfig-006-20260701 gcc-14
x86_64 randconfig-011-20260701 gcc-14
x86_64 randconfig-012-20260701 gcc-14
x86_64 randconfig-013-20260701 gcc-14
x86_64 randconfig-014-20260701 gcc-14
x86_64 randconfig-015-20260701 gcc-14
x86_64 randconfig-016-20260701 gcc-14
x86_64 randconfig-071-20260701 gcc-14
x86_64 randconfig-072-20260701 gcc-14
x86_64 randconfig-073-20260701 gcc-14
x86_64 randconfig-074-20260701 gcc-14
x86_64 randconfig-075-20260701 gcc-14
x86_64 randconfig-076-20260701 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig clang-20
xtensa allyesconfig gcc-16.1.0
xtensa randconfig-001-20260701 gcc-13.4.0
xtensa randconfig-002-20260701 gcc-13.4.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH] drm/virtio: defer hotplug event from dequeue worker to avoid deadlock
From: Ryosuke Yasuoka @ 2026-07-01 9:23 UTC (permalink / raw)
To: Dmitry Osipenko, David Airlie, Gerd Hoffmann, Gurchetan Singh,
Chia-I Wu, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Simona Vetter, Dmitry Baryshkov, Javier Martinez Canillas
Cc: dri-devel, virtualization, linux-kernel
In-Reply-To: <5aa634c1-7530-4b1f-931a-a5a5ac6c908a@collabora.com>
On 30/06/2026 16:46, Dmitry Osipenko wrote:
> Hi,
>
> On 6/30/26 12:16, Ryosuke Yasuoka wrote:
>> A probe-time deadlock can occur between the dequeue worker and
>> drm_client_register(). During probe, drm_client_register() holds
>> clientlist_mutex and calls the fbdev hotplug callback, which triggers an
>> atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs()
>> waiting for virtqueue space. The dequeue worker that would free that
>> space calls virtio_gpu_cmd_get_display_info_cb(), which invokes
>> drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting
>> to acquire the same clientlist_mutex. Since wake_up() is only called
>> after the resp_cb loop, the probe thread is never woken and both threads
>> deadlock.
>>
>> Fix this by deferring the hotplug notification from
>> virtio_gpu_cmd_get_display_info_cb() to a separate work item. The
>> display data (outputs[i].info) is still updated synchronously in the
>> callback, and the deferred work only triggers a re-probe notification to
>> DRM clients.
>>
>> Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client")
>> Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
>> Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
>> Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
>> ---
>> drivers/gpu/drm/virtio/virtgpu_drv.h | 3 +++
>> drivers/gpu/drm/virtio/virtgpu_kms.c | 3 +++
>> drivers/gpu/drm/virtio/virtgpu_vq.c | 12 ++++++++++--
>> 3 files changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
>> index 7449907754a4..27ffa4697ae9 100644
>> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
>> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
>> @@ -264,6 +264,8 @@ struct virtio_gpu_device {
>>
>> struct work_struct config_changed_work;
>>
>> + struct work_struct hotplug_work;
>> +
>> struct work_struct obj_free_work;
>> spinlock_t obj_free_lock;
>> struct list_head obj_free_list;
>> @@ -350,6 +352,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
>> uint32_t x, uint32_t y,
>> struct virtio_gpu_object_array *objs,
>> struct virtio_gpu_fence *fence);
>> +void virtio_gpu_hotplug_work_func(struct work_struct *work);
>> void virtio_gpu_panic_cmd_resource_flush(struct virtio_gpu_device *vgdev,
>> uint32_t resource_id,
>> uint32_t x, uint32_t y,
>> diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
>> index cfde9f573df6..cfb532ba43a4 100644
>> --- a/drivers/gpu/drm/virtio/virtgpu_kms.c
>> +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
>> @@ -154,6 +154,8 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
>> INIT_WORK(&vgdev->config_changed_work,
>> virtio_gpu_config_changed_work_func);
>>
>> + INIT_WORK(&vgdev->hotplug_work, virtio_gpu_hotplug_work_func);
>> +
>> INIT_WORK(&vgdev->obj_free_work,
>> virtio_gpu_array_put_free_work);
>> INIT_LIST_HEAD(&vgdev->obj_free_list);
>> @@ -293,6 +295,7 @@ void virtio_gpu_deinit(struct drm_device *dev)
>> flush_work(&vgdev->obj_free_work);
>> flush_work(&vgdev->ctrlq.dequeue_work);
>> flush_work(&vgdev->cursorq.dequeue_work);
>> + flush_work(&vgdev->hotplug_work);
>> flush_work(&vgdev->config_changed_work);
>> virtio_reset_device(vgdev->vdev);
>> vgdev->vdev->config->del_vqs(vgdev->vdev);
>> diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
>> index 67865810a2e7..084d98f5dc7b 100644
>> --- a/drivers/gpu/drm/virtio/virtgpu_vq.c
>> +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
>> @@ -816,6 +816,15 @@ virtio_gpu_cmd_resource_detach_backing(struct virtio_gpu_device *vgdev,
>> virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
>> }
>>
>> +void virtio_gpu_hotplug_work_func(struct work_struct *work)
>> +{
>> + struct virtio_gpu_device *vgdev =
>> + container_of(work, struct virtio_gpu_device, hotplug_work);
>> +
>> + if (!drm_helper_hpd_irq_event(vgdev->ddev))
>> + drm_kms_helper_hotplug_event(vgdev->ddev);
>> +}
>> +
>> static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
>> struct virtio_gpu_vbuffer *vbuf)
>> {
>> @@ -841,8 +850,7 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
>> spin_unlock(&vgdev->display_info_lock);
>> wake_up(&vgdev->resp_wq);
>>
>> - if (!drm_helper_hpd_irq_event(vgdev->ddev))
>> - drm_kms_helper_hotplug_event(vgdev->ddev);
>> + schedule_work(&vgdev->hotplug_work);
>> }
>>
>> static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
>
Hi,
Thank you for your review.
> Could you please move drm_kms_helper_hotplug_event() to virtio_gpu_init(), placing it after wait_event_timeout(display_info_pending)? This will avoid additional work_struct that otherwise needs to be cancelled in virtio_gpu_init() on the timeout.
IIUC, moving the drm_kms_helper_hotplug_event() and _hpd_irq_event()
into virtio_gpu_init() after wait_event_timeout() would not prevent the
issue.
Looking at the syzbot call traces[1][2], the deadlock occurs during
drm_client_setup(), which runs after virtio_gpu_init() has already
returned. The display_info_cb that triggers the deadlock is called from
the dequeue worker while drm_client_register() holds clientlist_mutex.
Thread A:
virtio_gpu_probe()
-> virtio_gpu_init() // sends GET_DISPLAY_INFO and waits up to 5s
-> drm_dev_register()
-> drm_client_setup() // deadlock happens HERE
-> drm_client_register() // holds clientlist_mutex
...
-> virtio_gpu_queue_fenced_ctrl_buffer()
-> wait_event() // waits for free space
Thread B:
virtio_gpu_dequeue_ctrl_func()
-> reclaim_vbufs() // make free space
-> resp_cb()
-> virtio_gpu_cmd_get_display_info_cb
-> drm_helper_hpd_irq_event()
-> drm_kms_helper_hotplug_event()
-> drm_client_dev_hotplug() // need to lock clientlist_mutex
-> wake_up() // never reached
IIUC the hotplug notification in display_info_cb is needed because it
notifies DRM after updating by the callback with fresh data from the host.
This work_struct ensures display_info_cb never blocks on
clientlist_mutex in the dequeue worker, while preserving the hotplug
notification with fresh data.
[1] https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
[2] https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
Best regards,
Ryosuke
^ permalink raw reply
* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Jürgen Groß @ 2026-07-01 8:33 UTC (permalink / raw)
To: Sean Christopherson, Ingo Molnar
Cc: Arnd Bergmann, linux-kernel, linux-pm, linux-edac@vger.kernel.org,
x86, linux-acpi, kvm, linux-coco, linux-pci, virtualization,
linux-ide, dri-devel, linux-fbdev, linux-crypto,
open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
linux-perf-users, linux-mtd, platform-driver-x86,
Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
Ingo Molnar, Dave Hansen, H. Peter Anvin, Paolo Bonzini,
Kirill A. Shutemov, Rick Edgecombe, Pu Wen, Bjorn Helgaas,
Ajay Kaher, Alexey Makhalov, Broadcom internal kernel review list,
Viresh Kumar, Reinette Chatre, Dave Martin, James Morse,
Babu Moger, Tony W Wang-oc, Damien Le Moal, Niklas Cassel,
Dave Airlie, Helge Deller, linux-geode, Olivia Mackall,
Herbert Xu, Linus Walleij, Bartosz Golaszewski,
Greg Kroah-Hartman, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Guenter Roeck, Peter Zijlstra,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, Josh Poimboeuf, Pawan Gupta, Vitaly Kuznetsov,
Andy Lutomirski, Boris Ostrovsky, Huang Rui, Mario Limonciello,
Perry Yuan, K Prateek Nayak, srinivas.pandruvada@linux.intel.com,
Artem Bityutskiy, Artem Bityutskiy, Miquel Raynal,
Richard Weinberger, Vignesh Raghavendra, Ashok Raj, Hans de Goede,
Ilpo Järvinen, Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <akQR9YMtMHReJTfB@google.com>
[-- Attachment #1.1.1: Type: text/plain, Size: 1484 bytes --]
On 30.06.26 20:59, Sean Christopherson wrote:
> On Mon, Jun 29, 2026, Ingo Molnar wrote:
>> * Arnd Bergmann <arnd@arndb.de> wrote:
>>
>>>>>> Note that most patches of this series are independent from each other.
>>>>>> Only the patches removing a specific interface (patches 7, 15, 26 and
>>>>>> 30) and the last two patches of the series depend on all previous
>>>>>> patches.
>>>>>
>>>>> It looks like you are touching most files twice or more here, to
>>>>> first convert from rdmsr to rdmsrq and then to change the
>>>>> two-argument rdmsrq() macro to a single-argument inline. If you
>>>>> introduce the inline version of rdmsrq() first, you should be
>>>>> able to skip the second step (patch 31) as they could be able
>>>>> to coexist.
>>>>
>>>> I've discussed how to structure the series with Ingo Molnar before [1]. The
>>>> current approach was his preference.
>>>
>>> Ok.
>>
>> Note that the individual patches are IMO significantly easier to review
>> through the actual 32-bit => 64-bit variable assignment changes done
>> in isolation (which sometimes include minor cleanups), while
>> the Coccinelle semantic patch:
>>
>> { a(b,c) => c = a(b) }
>>
>> which changes both the function signature and the order of terms as
>> well, is just a single add-on treewide patch.
>
> Is the plan for subsystem maintainers to pick up the relevant patches, and then
> do the treewide change one release cycle later?
Yes, please.
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 v5] virtio_net: disable cb when NAPI is busy-polled
From: patchwork-bot+netdevbpf @ 2026-07-01 0:20 UTC (permalink / raw)
To: Longjun Tang
Cc: kuba, horms, mst, jasowang, edumazet, virtualization, netdev,
tanglongjun
In-Reply-To: <20260629024230.37325-1-lange_tang@163.com>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 29 Jun 2026 10:42:30 +0800 you wrote:
> From: Longjun Tang <tanglongjun@kylinos.cn>
>
> When busy-poll is active, napi_schedule_prep() returns false in
> virtqueue_napi_schedule(), so virtqueue_disable_cb() is skipped.
> The device may keep firing irqs until reaches virtqueue_napi_complete().
> Under load (received == budget), it will lead to a large number
> of spurious interrupts.
>
> [...]
Here is the summary with links:
- [v5] virtio_net: disable cb when NAPI is busy-polled
https://git.kernel.org/netdev/net/c/1eb8fc67ca41
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 14/18] fuse: convert iomap ops to ->iomap_next()
From: Joanne Koong @ 2026-07-01 0:09 UTC (permalink / raw)
To: brauner, hch
Cc: djwong, willy, hsiangkao, linux-fsdevel, linux-xfs,
Miklos Szeredi, German Maglione, Vivek Goyal, Stefan Hajnoczi,
Eugenio Pérez, open list:FUSE FILESYSTEM [CORE], open list,
open list:VIRTIO FILE SYSTEM
In-Reply-To: <20260701000949.1666714-1-joannelkoong@gmail.com>
Convert fuse iomap_ops to the new ->iomap_next() callback. This uses the
iomap_process() helper, which finishes the previous mapping if needed
and produces the next one. No functional changes are intended.
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
fs/fuse/dax.c | 10 ++++++++--
fs/fuse/file.c | 8 +++++++-
fs/fuse/virtio_fs.c | 2 +-
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c
index 8b53625ac7ab..e8d8c9f5d728 100644
--- a/fs/fuse/dax.c
+++ b/fs/fuse/dax.c
@@ -653,9 +653,15 @@ static int fuse_iomap_end(struct inode *inode, loff_t pos, loff_t length,
return 0;
}
+static int fuse_iomap_next(const struct iomap_iter *iter, struct iomap *iomap,
+ struct iomap *srcmap)
+{
+ return iomap_process(iter, iomap, srcmap, fuse_iomap_begin,
+ fuse_iomap_end);
+}
+
static const struct iomap_ops fuse_iomap_ops = {
- .iomap_begin = fuse_iomap_begin,
- .iomap_end = fuse_iomap_end,
+ .iomap_next = fuse_iomap_next,
};
static void fuse_wait_dax_page(struct inode *inode)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e052a0d44dee..5c0d400629cc 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -890,8 +890,14 @@ static int fuse_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return 0;
}
+static int fuse_iomap_next(const struct iomap_iter *iter, struct iomap *iomap,
+ struct iomap *srcmap)
+{
+ return iomap_process(iter, iomap, srcmap, fuse_iomap_begin, NULL);
+}
+
static const struct iomap_ops fuse_iomap_ops = {
- .iomap_begin = fuse_iomap_begin,
+ .iomap_next = fuse_iomap_next,
};
struct fuse_fill_read_data {
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index df25d4faca41..84e699f88574 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -1024,7 +1024,7 @@ static void virtio_fs_cleanup_vqs(struct virtio_device *vdev)
}
/* Map a window offset to a page frame number. The window offset will have
- * been produced by .iomap_begin(), which maps a file offset to a window
+ * been produced by .iomap_next(), which maps a file offset to a window
* offset.
*/
static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
--
2.52.0
^ permalink raw reply related
* Re: [PATCH net-next v4] vsock/virtio: rewrite MSG_ZEROCOPY flag handling
From: patchwork-bot+netdevbpf @ 2026-06-30 20:32 UTC (permalink / raw)
To: Arseniy Krasnov
Cc: stefanha, sgarzare, davem, edumazet, kuba, pabeni, mst, jasowang,
bobbyeshleman, xuanzhuo, eperezma, horms, kvm, virtualization,
netdev, linux-kernel, oxffffaa, rulkc
In-Reply-To: <20260628182052.951760-1-avkrasnov@rulkc.org>
Hello:
This patch was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Sun, 28 Jun 2026 21:20:52 +0300 you wrote:
> Logically it was based on TCP implementation, so to make further support
> easier, rewrite it in the TCP way (like in 'tcp_sendmsg_locked()'). By
> this way, patch also adds handling case when 'msg_ubuf' is already set.
>
> Signed-off-by: Arseniy Krasnov <avkrasnov@rulkc.org>
> ---
> Changelog v1->v2:
> * Rebase on last 'net-next'. Don't need 'skb_zcopy_set()' now - it was
> already added.
> Changelog v2->v3:
> * Update commit message.
> * Remove one empty line.
> Changelog v3->v4:
> * Update commit message.
>
> [...]
Here is the summary with links:
- [net-next,v4] vsock/virtio: rewrite MSG_ZEROCOPY flag handling
https://git.kernel.org/netdev/net-next/c/f456c1922c49
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH V2] MAINTAINERS: Update Jason Wang's email address
From: patchwork-bot+netdevbpf @ 2026-06-30 20:32 UTC (permalink / raw)
To: Jason Wang; +Cc: mst, virtualization, netdev, eperezma, kvm, linux-kernel
In-Reply-To: <20260629014525.16297-1-jasowang@redhat.com>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 29 Jun 2026 09:45:24 +0800 you wrote:
> I will use jasowangio@gmail.com for future review and discussion.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> Changes since V1:
> - Add mailmap entry
>
> [...]
Here is the summary with links:
- [V2] MAINTAINERS: Update Jason Wang's email address
https://git.kernel.org/netdev/net/c/1398b1014909
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: H. Peter Anvin @ 2026-06-30 20:06 UTC (permalink / raw)
To: Arnd Bergmann, Juergen Gross, linux-kernel, linux-pm,
linux-edac@vger.kernel.org, x86, linux-acpi, kvm, linux-coco,
linux-pci, virtualization, linux-ide, dri-devel, linux-fbdev,
linux-crypto, open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
linux-perf-users, linux-mtd, platform-driver-x86
Cc: Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
Ingo Molnar, Dave Hansen, Sean Christopherson, Paolo Bonzini,
Kirill A. Shutemov, Rick Edgecombe, Pu Wen, Bjorn Helgaas,
Ajay Kaher, Alexey Makhalov, Broadcom internal kernel review list,
Viresh Kumar, Reinette Chatre, Dave Martin, James Morse,
Babu Moger, Tony W Wang-oc, Damien Le Moal, Niklas Cassel,
Dave Airlie, Helge Deller, linux-geode, Olivia Mackall,
Herbert Xu, Linus Walleij, Bartosz Golaszewski,
Greg Kroah-Hartman, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Guenter Roeck, Peter Zijlstra,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, Josh Poimboeuf, Pawan Gupta, Vitaly Kuznetsov,
Andy Lutomirski, Boris Ostrovsky, Huang Rui, Mario Limonciello,
Perry Yuan, K Prateek Nayak, srinivas.pandruvada@linux.intel.com,
Artem Bityutskiy, Artem Bityutskiy, Miquel Raynal,
Richard Weinberger, Vignesh Raghavendra, Ashok Raj, Hans de Goede,
Ilpo Järvinen, Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <d315e0a8-e4e9-4f7e-80a9-7c236849eabd@app.fastmail.com>
On 2026-06-29 01:38, Arnd Bergmann wrote:
>>
>> There is no RDMSRQ instruction on any x86 CPU. Are you mixing this up with
>> WRMSRNS/RDMSR using an immediate for addressing the MSR?
>
> Yes, I was just confused about the exact definition here and assumed
> the single-register output version was actually called rdmsrq.
>
So just to be clear:
There are three instructions(*):
wrmsr - implicit form only
wrmsrns - implicit or immediate
rdmsr - implicit or immediate
The implicit form are the same on 32 and 64 bits (and, in fact, 16 bits): they
take a MSR register address in %ecx and the data as two 32-bit words in
%edx:%eax. This interface predates x86-64 by about a decade, and the Linux MSR
interfaces were designed when Linux was 32-bit only, so it made sense at the
time to treat them as two halves, especially since MSRs often are various
kinds of bitfields. It didn't help that gcc at the time was extremely
inefficient in its handling of multiword arithmetic (it is much better now),
so using a u64 would have made for much worse code.
The immediate forms are 64-bit only and use a single arbitrary 64-bit
register; the MSR address is kept in an immediate in the instruction, just
like they are for most other register types. The only thing that is "special"
there is that the possible register address space is very large (2^32)
although in practice a very small fraction of that is (currently) used.
The immediate forms are expected to be faster, and provide for further
performance improvements in future microarchitectures. This is important,
because it provides a fine-grain uniform architecture for supervisor-only
state, instead of having to give a bulk ISA (XSAVES/XRSTORS) that is different
from the fine-grained architecture, and still get good performance. This gives
the kernel very fine level control over the context switch flows, for one thing.
WRMSRNS is a non-serializing form of WRMSR, which is defined as an
architecturally hard-serializing instruction, although some MSRs have been
retconned as non-serializing (and the set is different between vendors.) We
want to switch that over to the model where the kernel explicitly opts in to
nonserialization, but that means using alternatives since not all CPUs have
the WRMSRNS instruction.
Furthermore, we want to use alternatives so we can make use of the
immediate-format instructions when the MSR address is known at compile time,
which it is in *nearly* all cases. If we are smart about it we can also use
this to let the tracing framework be specific about what MSRs to trace, since
some MSRs are frequently accessed, but many are set at startup and then
rarely, if ever, touched.
(*) There are actually two more instructions:
RDMSRLIST
WRMSRLIST
... which are bulk versions of RDMSR and WRMSRNS respectively. They can be
useful to save and restore entire groups of MSRs in one shot, such as
performance counter configurations. By architecturally allowing the memory
operations and MSR operations to operate asynchronously, they give some of the
pipeline benefits of the immediate MSR operations without requiring the MSR
set to have been set at compile time or code to be dynamically generated.
However, they expose an entirely different programming model, whereas the
immediate- and -NS instruction choices can be entirely hidden at the C level.
^ permalink raw reply
* Re: [PATCH 00/32] x86/msr: Drop 32-bit MSR interfaces
From: Sean Christopherson @ 2026-06-30 18:59 UTC (permalink / raw)
To: Ingo Molnar
Cc: Arnd Bergmann, Juergen Gross, linux-kernel, linux-pm,
linux-edac@vger.kernel.org, x86, linux-acpi, kvm, linux-coco,
linux-pci, virtualization, linux-ide, dri-devel, linux-fbdev,
linux-crypto, open list:GPIO SUBSYSTEM, linux-hyperv, linux-hwmon,
linux-perf-users, linux-mtd, platform-driver-x86,
Rafael J . Wysocki, Daniel Lezcano, Zhang Rui,
lukasz.luba@arm.com, Jason Baron, Borislav Petkov, Tony Luck,
Yazen Ghannam, Len Brown, Pavel Machek, Thomas Gleixner,
Ingo Molnar, Dave Hansen, H. Peter Anvin, Paolo Bonzini,
Kirill A. Shutemov, Rick Edgecombe, Pu Wen, Bjorn Helgaas,
Ajay Kaher, Alexey Makhalov, Broadcom internal kernel review list,
Viresh Kumar, Reinette Chatre, Dave Martin, James Morse,
Babu Moger, Tony W Wang-oc, Damien Le Moal, Niklas Cassel,
Dave Airlie, Helge Deller, linux-geode, Olivia Mackall,
Herbert Xu, Linus Walleij, Bartosz Golaszewski,
Greg Kroah-Hartman, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Long Li, Guenter Roeck, Peter Zijlstra,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, Josh Poimboeuf, Pawan Gupta, Vitaly Kuznetsov,
Andy Lutomirski, Boris Ostrovsky, Huang Rui, Mario Limonciello,
Perry Yuan, K Prateek Nayak, srinivas.pandruvada@linux.intel.com,
Artem Bityutskiy, Artem Bityutskiy, Miquel Raynal,
Richard Weinberger, Vignesh Raghavendra, Ashok Raj, Hans de Goede,
Ilpo Järvinen, Rajneesh Bhardwaj, David E Box, xen-devel
In-Reply-To: <akJUz0kYkEBdLSZ3@gmail.com>
On Mon, Jun 29, 2026, Ingo Molnar wrote:
> * Arnd Bergmann <arnd@arndb.de> wrote:
>
> > >>> Note that most patches of this series are independent from each other.
> > >>> Only the patches removing a specific interface (patches 7, 15, 26 and
> > >>> 30) and the last two patches of the series depend on all previous
> > >>> patches.
> > >>
> > >> It looks like you are touching most files twice or more here, to
> > >> first convert from rdmsr to rdmsrq and then to change the
> > >> two-argument rdmsrq() macro to a single-argument inline. If you
> > >> introduce the inline version of rdmsrq() first, you should be
> > >> able to skip the second step (patch 31) as they could be able
> > >> to coexist.
> > >
> > > I've discussed how to structure the series with Ingo Molnar before [1]. The
> > > current approach was his preference.
> >
> > Ok.
>
> Note that the individual patches are IMO significantly easier to review
> through the actual 32-bit => 64-bit variable assignment changes done
> in isolation (which sometimes include minor cleanups), while
> the Coccinelle semantic patch:
>
> { a(b,c) => c = a(b) }
>
> which changes both the function signature and the order of terms as
> well, is just a single add-on treewide patch.
Is the plan for subsystem maintainers to pick up the relevant patches, and then
do the treewide change one release cycle later?
^ permalink raw reply
* Re: [PATCH net-next v4] vsock/virtio: rewrite MSG_ZEROCOPY flag handling
From: Paolo Abeni @ 2026-06-30 15:52 UTC (permalink / raw)
To: Arseniy Krasnov, Stefan Hajnoczi, Stefano Garzarella,
David S. Miller, Eric Dumazet, Jakub Kicinski, Michael S. Tsirkin,
Jason Wang, Bobby Eshleman, Xuan Zhuo, Eugenio Pérez,
Simon Horman
Cc: kvm, virtualization, netdev, linux-kernel, oxffffaa, rulkc
In-Reply-To: <20260628182052.951760-1-avkrasnov@rulkc.org>
On 6/28/26 8:20 PM, Arseniy Krasnov wrote:
> Logically it was based on TCP implementation, so to make further support
> easier, rewrite it in the TCP way (like in 'tcp_sendmsg_locked()'). By
> this way, patch also adds handling case when 'msg_ubuf' is already set.
>
> Signed-off-by: Arseniy Krasnov <avkrasnov@rulkc.org>
The PW bot is on holiday, no automated notifications for a while.
Applied, thanks!
/P
^ permalink raw reply
* Re: [PATCH 01/13] mm: introduce vma_flags_can_grow() and vma_can_grow()
From: Zi Yan @ 2026-06-30 15:09 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, Thomas Bogendoerfer, Madhavan Srinivasan,
Michael Ellerman, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Lucas Stach,
Inki Dae, Seung-Woo Kim, Kyungmin Park, Krzysztof Kozlowski,
Peter Griffin, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Tvrtko Ursulin, Rob Clark, Dmitry Baryshkov, Lyude Paul,
Danilo Krummrich, Tomi Valkeinen, Sandy Huang, Heiko Stübner,
Andy Yan, Thierry Reding, Mikko Perttunen, Jonathan Hunter,
Gerd Hoffmann, Dmitry Osipenko, Zack Rusin, Matthew Brost,
Thomas Hellstrom, Oleksandr Andrushchenko, Helge Deller,
Benjamin LaHaise, Alexander Viro, Christian Brauner, Muchun Song,
Oscar Salvador, David Hildenbrand, Baolin Wang, Liam R . Howlett,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Hugh Dickins, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan,
Michal Hocko, Jann Horn, Pedro Falcato, Kees Cook,
Jaroslav Kysela, Takashi Iwai, linux-mips, linux-kernel,
linuxppc-dev, dri-devel, etnaviv, linux-arm-kernel,
linux-samsung-soc, intel-gfx, linux-arm-msm, freedreno, nouveau,
linux-rockchip, linux-tegra, virtualization, intel-xe, xen-devel,
linux-fbdev, linux-aio, linux-fsdevel, linux-mm, linux-sound
In-Reply-To: <akNucoP3eaDN2_Vz@lucifer>
On Tue Jun 30, 2026 at 3:38 AM EDT, Lorenzo Stoakes wrote:
> On Mon, Jun 29, 2026 at 04:26:18PM -0400, Zi Yan wrote:
>> On Mon Jun 29, 2026 at 3:25 PM EDT, Lorenzo Stoakes wrote:
>> > These test whether the VMA has stack sematics, i.e. is able to grow upwards
>> > or downwards depending on the architecture.
>> >
>> > In order to account for arches which do not support upward-growing stacks,
>> > introduce VMA_GROWSUP whose definition depends on the architecture
>> > supporting it, and use vma_flags_test_single_mask() in vma_flags_can_grow()
>> > to account for this.
>> >
>> > Update the VMA userland tests to reflect the changes
>> >
>> > No functional change intended.
>> >
>> > Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>
>> > ---
>> > include/linux/mm.h | 21 ++++++++++++++++++---
>> > tools/testing/vma/include/dup.h | 4 ++++
>> > 2 files changed, 22 insertions(+), 3 deletions(-)
>> >
>> > diff --git a/include/linux/mm.h b/include/linux/mm.h
>> > index 868b2334bff3..cf7df1569052 100644
>> > --- a/include/linux/mm.h
>> > +++ b/include/linux/mm.h
>> > @@ -472,6 +472,7 @@ enum {
>> > #define VM_SAO INIT_VM_FLAG(SAO)
>> > #elif defined(CONFIG_PARISC)
>> > #define VM_GROWSUP INIT_VM_FLAG(GROWSUP)
>> > +#define VMA_GROWSUP mk_vma_flags(VMA_GROWSUP_BIT)
>> > #elif defined(CONFIG_SPARC64)
>> > #define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI)
>> > #define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR)
>> > @@ -483,6 +484,7 @@ enum {
>> > #endif
>> > #ifndef VM_GROWSUP
>> > #define VM_GROWSUP VM_NONE
>> > +#define VMA_GROWSUP EMPTY_VMA_FLAGS
>> > #endif
>> > #ifdef CONFIG_ARM64_MTE
>> > #define VM_MTE INIT_VM_FLAG(MTE)
>> > @@ -1563,11 +1565,24 @@ static inline bool vma_is_initial_stack(const struct vm_area_struct *vma)
>> > vma->vm_end >= vma->vm_mm->start_stack;
>> > }
>> >
>> > -static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma)
>> > +static inline bool vma_flags_can_grow(const vma_flags_t *flags)
>> > {
>> > - int maybe_stack = vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP);
>> > + if (vma_flags_test_single_mask(flags, VMA_GROWSUP))
>> > + return true;
>> > + if (vma_flags_test(flags, VMA_GROWSDOWN_BIT))
>> > + return true;
>> > +
>> > + return false;
>> > +}
>> >
>> > - if (!maybe_stack)
>> > +static inline bool vma_can_grow(const struct vm_area_struct *vma)
>> > +{
>> > + return vma_flags_can_grow(&vma->flags);
>>
>> Would it save vma_flags_can_grow() if we do below?
>>
>> return vma_test(vma, VMA_GROWSDOWN_BIT) || vma_test_single_mask(vma, VMA_GROWSUP);
>>
>> I find these two functions when I am reading mm.h.
>
> Yeah but we require vma_flags_can_grow() for code in mmap.c, the majority of
> checks of this have only vma_flags_t to work with not a VMA :)
>
Got it. I think I need to finish this series. :)
>>
>> > +}
>> > +
>> > +static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma)
>> > +{
>> > + if (!vma_can_grow(vma))
>> > return false;
>> >
>> > if ((vma->vm_flags & VM_STACK_INCOMPLETE_SETUP) ==
>> > diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h
>> > index 5d7d0afd7765..6f5bcd7fbcd8 100644
>> > --- a/tools/testing/vma/include/dup.h
>> > +++ b/tools/testing/vma/include/dup.h
>> > @@ -245,8 +245,10 @@ enum {
>> > #define VM_STACK INIT_VM_FLAG(STACK)
>> > #ifdef CONFIG_STACK_GROWS_UP
>> > #define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)
>> > +#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)
>> > #else
>> > #define VM_STACK_EARLY VM_NONE
>> > +#define VMA_STACK_EARLY EMPTY_VMA_FLAGS
>> > #endif
>> > #ifdef CONFIG_ARCH_HAS_PKEYS
>> > #define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT)
>> > @@ -315,6 +317,8 @@ enum {
>> >
>> > /* Bits set in the VMA until the stack is in its final location */
>> > #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
>> > +#define VMA_STACK_INCOMPLETE_SETUP append_vma_flags( \
>> > + VMA_STACK_EARLY, VMA_RAND_READ_BIT, VMA_SEQ_READ_BIT)
>> >
>> > #define TASK_EXEC_BIT ((current->personality & READ_IMPLIES_EXEC) ? \
>> > VM_EXEC_BIT : VM_READ_BIT)
>>
>> Why are VMA_STACK_EARLY and VMA_STACK_INCOMPLETE_SETUP added here but
>> not in mm.h?
>
> Yeah urgh oops my bad. It doesn't really break anything but I'll fix it if a
> respin is needed...
Sure.
--
Best Regards,
Yan, Zi
^ 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