* Re: [PATCH] docs: fix typos in Documentation/PCI/
From: Bjorn Helgaas @ 2026-04-21 16:28 UTC (permalink / raw)
To: josh ziegler; +Cc: bhelgaas, corbet, skhan, linux-pci, linux-doc, linux-kernel
In-Reply-To: <20260421012059.251492-1-joshziegler76@gmail.com>
On Mon, Apr 20, 2026 at 09:20:59PM -0400, josh ziegler wrote:
> Fix "chose" -> "choose" in pci.rst
> Fix "result an" -> "result in an" in pciebus-howto.rst
>
> Signed-off-by: josh ziegler <joshziegler76@gmail.com>
Applied with Randy's ack to pci/misc for v7.2, thanks!
Updated subject line to match local history:
Documentation: PCI: Fix typos
> ---
> Documentation/PCI/pci.rst | 2 +-
> Documentation/PCI/pciebus-howto.rst | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/PCI/pci.rst b/Documentation/PCI/pci.rst
> index f4d2662871ab..be35e9a1ee75 100644
> --- a/Documentation/PCI/pci.rst
> +++ b/Documentation/PCI/pci.rst
> @@ -338,7 +338,7 @@ the PCI_IRQ_MSI and PCI_IRQ_MSIX flags will fail, so try to always
> specify PCI_IRQ_INTX as well.
>
> Drivers that have different interrupt handlers for MSI/MSI-X and
> -legacy INTx should chose the right one based on the msi_enabled
> +legacy INTx should choose the right one based on the msi_enabled
> and msix_enabled flags in the pci_dev structure after calling
> pci_alloc_irq_vectors.
>
> diff --git a/Documentation/PCI/pciebus-howto.rst b/Documentation/PCI/pciebus-howto.rst
> index 375d9ce171f6..9cc133ccdeec 100644
> --- a/Documentation/PCI/pciebus-howto.rst
> +++ b/Documentation/PCI/pciebus-howto.rst
> @@ -97,7 +97,7 @@ register its service with the PCI Express Port Bus driver (see
> section 5.2.1 & 5.2.2). It is important that a service driver
> initializes the pcie_port_service_driver data structure, included in
> header file /include/linux/pcieport_if.h, before calling these APIs.
> -Failure to do so will result an identity mismatch, which prevents
> +Failure to do so will result in an identity mismatch, which prevents
> the PCI Express Port Bus driver from loading a service driver.
>
> pcie_port_service_register
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH v12 10/16] KVM: guest_memfd: Add flag to remove from direct map
From: Sean Christopherson @ 2026-04-21 16:31 UTC (permalink / raw)
To: Nikita Kalyazin
Cc: kvm@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
kernel@xen0n.name, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, loongarch@lists.linux.dev,
linux-pm@vger.kernel.org, pbonzini@redhat.com, corbet@lwn.net,
maz@kernel.org, oupton@kernel.org, joey.gouly@arm.com,
suzuki.poulose@arm.com, yuzenghui@huawei.com,
catalin.marinas@arm.com, will@kernel.org, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
x86@kernel.org, hpa@zytor.com, luto@kernel.org,
peterz@infradead.org, willy@infradead.org,
akpm@linux-foundation.org, david@kernel.org,
lorenzo.stoakes@oracle.com, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, ast@kernel.org,
daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev,
eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev,
john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me,
haoluo@google.com, jolsa@kernel.org, jgg@ziepe.ca,
jhubbard@nvidia.com, peterx@redhat.com, jannh@google.com,
pfalcato@suse.de, skhan@linuxfoundation.org, riel@surriel.com,
ryan.roberts@arm.com, jgross@suse.com, yu-cheng.yu@intel.com,
kas@kernel.org, coxu@redhat.com, ackerleytng@google.com,
yosry@kernel.org, ajones@ventanamicro.com, maobibo@loongson.cn,
tabba@google.com, prsampat@amd.com, wu.fei9@sanechips.com.cn,
mlevitsk@redhat.com, jmattson@google.com, jthoughton@google.com,
agordeev@linux.ibm.com, alex@ghiti.fr, aou@eecs.berkeley.edu,
borntraeger@linux.ibm.com, chenhuacai@kernel.org,
baolu.lu@linux.intel.com, dev.jain@arm.com, gor@linux.ibm.com,
hca@linux.ibm.com, palmer@dabbelt.com, pjw@kernel.org,
shijie@os.amperecomputing.com, svens@linux.ibm.com,
thuth@redhat.com, yang@os.amperecomputing.com,
Liam.Howlett@oracle.com, urezki@gmail.com,
zhengqi.arch@bytedance.com, gerald.schaefer@linux.ibm.com,
jiayuan.chen@shopee.com, lenb@kernel.org, pavel@kernel.org,
rafael@kernel.org, yangyicong@hisilicon.com,
vannapurve@google.com, jackmanb@google.com, patrick.roy@linux.dev,
Jack Thomson, Takahiro Itazuri, Derek Manwaring, Nikita Kalyazin
In-Reply-To: <20260410151746.61150-11-kalyazin@amazon.com>
On Fri, Apr 10, 2026, Nikita Kalyazin wrote:
> From: Patrick Roy <patrick.roy@linux.dev>
>
> Add GUEST_MEMFD_FLAG_NO_DIRECT_MAP flag for KVM_CREATE_GUEST_MEMFD()
> ioctl. When set, guest_memfd folios will be removed from the direct map
> after preparation, with direct map entries only restored when the folios
> are freed.
>
> To ensure these folios do not end up in places where the kernel cannot
> deal with them, set AS_NO_DIRECT_MAP on the guest_memfd's struct
> address_space if GUEST_MEMFD_FLAG_NO_DIRECT_MAP is requested.
>
> Note that this flag causes removal of direct map entries for all
> guest_memfd folios independent of whether they are "shared" or "private"
> (although current guest_memfd only supports either all folios in the
> "shared" state, or all folios in the "private" state if
> GUEST_MEMFD_FLAG_MMAP is not set). The usecase for removing direct map
> entries of also the shared parts of guest_memfd are a special type of
> non-CoCo VM where, host userspace is trusted to have access to all of
> guest memory, but where Spectre-style transient execution attacks
> through the host kernel's direct map should still be mitigated. In this
> setup, KVM retains access to guest memory via userspace mappings of
> guest_memfd, which are reflected back into KVM's memslots via
> userspace_addr. This is needed for things like MMIO emulation on x86_64
> to work.
>
> Direct map entries are zapped right before guest or userspace mappings
> of gmem folios are set up, e.g. in kvm_gmem_fault_user_mapping() or
> kvm_gmem_get_pfn() [called from the KVM MMU code].
...
> +#define KVM_GMEM_FOLIO_NO_DIRECT_MAP BIT(0)
> +
> +static bool kvm_gmem_folio_no_direct_map(struct folio *folio)
> +{
> + return ((u64)folio->private) & KVM_GMEM_FOLIO_NO_DIRECT_MAP;
> +}
> +
> +static int kvm_gmem_folio_zap_direct_map(struct folio *folio)
> +{
> + int r = 0;
> +
> + VM_WARN_ON_FOLIO(!folio_test_locked(folio), folio);
> +
> + if (WARN_ON_ONCE(!(GMEM_I(folio_inode(folio))->flags & GUEST_MEMFD_FLAG_NO_DIRECT_MAP)))
> + return -EINVAL;
> +
> + if (kvm_gmem_folio_no_direct_map(folio))
> + goto out;
> +
> + r = folio_zap_direct_map(folio);
> + if (!r)
> + folio->private = (void *)((u64)folio->private | KVM_GMEM_FOLIO_NO_DIRECT_MAP);
> +
> +out:
> + return r;
> +}
> +
> +static void kvm_gmem_folio_restore_direct_map(struct folio *folio)
> +{
> + folio_restore_direct_map(folio);
> + folio->private = (void *)((u64)folio->private & ~KVM_GMEM_FOLIO_NO_DIRECT_MAP);
> +}
Making guest_memfd responsible for zapping and restoring the direct map on a per-
folio basis feels wrong given the addition of AS_NO_DIRECT_MAP. I especially don't
like that the "rules" for when an AS_NO_DIRECT_MAP folio has a direct map will vary
based on the owner, and even within an owner (e.g. guest_memfd) will be ad hoc.
E.g. as per the series to add guest_memfd write() support[*]:
When direct map removal is implemented [2]
- write() will not be allowed to access pages that have already
been removed from direct map
- on completion, write() will remove the populated pages from
direct map
That's pretty gross ABI, because with KVM_GMEM_FOLIO_NO_DIRECT_MAP, userspace can
write() exactly once. To re-write memory, I assume userspace would need to do a
PUNCH_HOLE or truncate.
What's preventing us from handling this automagically in e.g. filemap_add_folio()
and filemap_remove_folio()? Then the usage rules are pretty straightforward: the
kernel must *always* assume the direct map is invalid for folios from
AS_NO_DIRECT_MAP mappings.
Then if KVM needs to utilize a kernel mapping, e.g. in kvm_gmem_populate(), KVM
could use dedicated variants of kmap_local_xxx() to deal with a local mapping for
a folio/page without a direct map. Or, KVM could simply disallow the specific
sequence that would require KVM to do the memcpy (I'm pretty sure we can do that
with in-place shared=>private conversion support).
I realize that could throw a big wrench into write() performance, but IMO, before
merging either series, we need a complete story for exactly how this will all fit
together, in a maintainable fashion and with sane ABI.
[*] https://lore.kernel.org/all/20251114151828.98165-1-kalyazin@amazon.com
^ permalink raw reply
* Re: [PATCH v12 00/16] Direct Map Removal Support for guest_memfd
From: Sean Christopherson @ 2026-04-21 16:36 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Nikita Kalyazin, kvm@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
kernel@xen0n.name, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, loongarch@lists.linux.dev,
linux-pm@vger.kernel.org, pbonzini@redhat.com, corbet@lwn.net,
maz@kernel.org, oupton@kernel.org, joey.gouly@arm.com,
suzuki.poulose@arm.com, yuzenghui@huawei.com,
catalin.marinas@arm.com, will@kernel.org, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
x86@kernel.org, hpa@zytor.com, luto@kernel.org,
peterz@infradead.org, willy@infradead.org,
akpm@linux-foundation.org, david@kernel.org,
lorenzo.stoakes@oracle.com, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, ast@kernel.org,
daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev,
eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev,
john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me,
haoluo@google.com, jolsa@kernel.org, jgg@ziepe.ca,
jhubbard@nvidia.com, peterx@redhat.com, jannh@google.com,
pfalcato@suse.de, skhan@linuxfoundation.org, riel@surriel.com,
ryan.roberts@arm.com, jgross@suse.com, yu-cheng.yu@intel.com,
kas@kernel.org, coxu@redhat.com, ackerleytng@google.com,
yosry@kernel.org, ajones@ventanamicro.com, maobibo@loongson.cn,
tabba@google.com, prsampat@amd.com, wu.fei9@sanechips.com.cn,
mlevitsk@redhat.com, jmattson@google.com, jthoughton@google.com,
agordeev@linux.ibm.com, alex@ghiti.fr, aou@eecs.berkeley.edu,
borntraeger@linux.ibm.com, chenhuacai@kernel.org,
baolu.lu@linux.intel.com, dev.jain@arm.com, gor@linux.ibm.com,
hca@linux.ibm.com, palmer@dabbelt.com, pjw@kernel.org,
shijie@os.amperecomputing.com, svens@linux.ibm.com,
thuth@redhat.com, yang@os.amperecomputing.com,
Liam.Howlett@oracle.com, urezki@gmail.com,
zhengqi.arch@bytedance.com, gerald.schaefer@linux.ibm.com,
jiayuan.chen@shopee.com, lenb@kernel.org, pavel@kernel.org,
rafael@kernel.org, yangyicong@hisilicon.com,
vannapurve@google.com, jackmanb@google.com, patrick.roy@linux.dev,
Jack Thomson, Takahiro Itazuri, Derek Manwaring, Nikita Kalyazin
In-Reply-To: <aed88qcV6PjEIHnd@lucifer>
On Tue, Apr 21, 2026, Lorenzo Stoakes wrote:
> On Fri, Apr 10, 2026 at 03:17:47PM +0000, Kalyazin, Nikita wrote:
> > From: Nikita Kalyazin <nikita.kalyazin@linux.dev>
> >
> > [ based on kvm/next ]
>
> Hm, given this touches a fair bit of mm, I wonder if we shouldn't try to do this
> through the mm tree?
Yeah, when the time comes, the mm pieces definitely need to go through the mm
tree. Ideally, I think this would be merged in two separate parts, with all mm
changes going through the mm tree, and then the KVM changes through the KVM tree
using a stable topic branch/tag from Andrew.
^ permalink raw reply
* Re: [PATCH v2 00/16] fs,x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem
From: Babu Moger @ 2026-04-21 16:46 UTC (permalink / raw)
To: Reinette Chatre, Moger, Babu, corbet@lwn.net, tony.luck@intel.com,
Dave.Martin@arm.com, james.morse@arm.com, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com
Cc: skhan@linuxfoundation.org, x86@kernel.org, hpa@zytor.com,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kas@kernel.org, rick.p.edgecombe@intel.com,
akpm@linux-foundation.org, pmladek@suse.com,
rdunlap@infradead.org, dapeng1.mi@linux.intel.com,
kees@kernel.org, elver@google.com, paulmck@kernel.org,
lirongqing@baidu.com, safinaskar@gmail.com, fvdl@google.com,
seanjc@google.com, pawan.kumar.gupta@linux.intel.com,
xin@zytor.com, tiala@microsoft.com, chang.seok.bae@intel.com,
Lendacky, Thomas, elena.reshetova@intel.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-coco@lists.linux.dev, kvm@vger.kernel.org,
eranian@google.com, peternewman@google.com
In-Reply-To: <8d969f11-4a7f-4e36-b85a-c3ed714fc603@intel.com>
Hi Reinette,
On 4/21/26 11:15, Reinette Chatre wrote:
> Hi Babu,
>
> On 4/21/26 8:08 AM, Babu Moger wrote:
>> Hi Reinette,
>>
>> On 4/20/26 22:17, Reinette Chatre wrote:
>>> Hi Babu,
>>>
>>> On 4/20/26 5:40 PM, Moger, Babu wrote:
>>>>
>>>> We already discussed moving back to the default group on every mode
>>>> switch. Doing so here would once again cause extra MSR writes on
>>>> each mode transition, which is undesirable.
>>>>
>>>
>>> Needing to avoid extra MSR writes in resctrl is not so absolute. Consider, for
>>> example, how resctrl initializes default allocations when a new resource group is
>>> created. resctrl aims to initialize with sane defaults and the user is expected to
>>> follow with desired allocations.
>>>
>>> I am not against optimizing, I just want to be careful with such general statements.
>>>
>>> Considering your proposal in https://lore.kernel.org/lkml/39e0c786-cc35-4555-bfb9-ff7cd758c423@amd.com/:
>>>
>>> I do not think we should make info/kernel_mode read-only. If I understand correctly
>>> doing so would accommodate AMD PLZA but it ignores the discussions on how resctrl could
>>> support MPAM ... or do you perhaps have proposal on how MPAM can be supported when considering
>>> your proposal? Even if you do not want to consider MPAM - what if the PLZA_PQR register's
>>> scope becomes per-CPU in the next version of AMD PLZA?
>>>
>>> The idea behind info/kernel_mode is that the active mode it identifies indicates which
>>> configuration files exist to configure the active mode. Since the mode may not always
>>> depend on global configuration, for which info/kernel_mode_assignment was created, but instead
>>> rely on per-resource group files, I do not see how resctrl can build on a read-only
>>> info/kernel_mode backed by a mode and group change via info/kernel_mode_assignment.
>>> Specifically, MPAM support may not use info/kernel_mode_assignment at all.
>>> Instead, MPAM may use something like described in https://lore.kernel.org/lkml/aYyxAPdTFejzsE42@e134344.arm.com/
>>>
>>> Could we perhaps consider dropping info/kernel_mode_assignment entirely for
>>> AMD PLZA's global allocations? Similar to what you suggest, the mode and
>>> group assignment could be done via the info/kernel_mode file instead?
>>>
>>> Thinking about this more since the CPUs allocation is global, these could *theoretically*
>>> be included also (but see later).
>>> This could mean that "kernel_mode_cpus" and "kernel_mode_cpus_list" could be dropped?
>>> Although, this may complicate the interface since user space may want a convenient way
>>> to modify just CPUs independently from needing to repeat the mode and group every time.
>>>
>>> Consider, for example:
>>>
>>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/;cpus_list=5-8" > info/kernel_mode
>>
>> This looks reasonable.
>>
>>>
>>> Having named fields (a) makes this extensible, (b) output does not need to be split among files,
>>> and (c) "inherit_ctrl_and_mon" can continue to be supported.
>>>
>>> The named fields could be made optional, if group is omitted then it will become the
>>> default resource group, and if cpus/cpus_list is omitted then it will default to all CPUs.
>>> This may not be intuitive since a user may expect that not mentioning a field means
>>> that the field is left untouched. Have you considered this scenario in your proposal?
>>>
>>> As an alternative the group could be made a required field and "kernel_mode_cpus"/"kernel_mode_cpuslist"
>>> can stay? This may be the simplest approach.
>>
>> How about keeping a single option to update the CPUs using
>> kernel_mode_cpus / kernel_mode_cpuslist within the group?
>>
>> Should we consider removing the per‑CPU extension altogether? By
>> default, the mode already applies to all online CPUs, and any
>> per‑CPU requirements can be handled within the group using
>> kernel_mode_cpus / kernel_mode_cpuslist.
>
> It sounds like we are saying the same thing?
> When considering all the sharp corners I agree that keeping kernel_mode_cpus/kernel_mode_cpuslist
> seems most user friendly. When doing so there is no need to include CPU assignment in the global
> files.
Actually, I was talking about removing _per_cpu extension also as the
per-CPU requirement is handled inside the group using
kernel_mode_cpus/kernel_mode_cpuslist. It can be documented.
global_assign_ctrl_assign_mon_per_cpu -> global_assign_ctrl_assign_mon
global_assign_ctrl_inherit_mon_per_cpu -> global_assign_ctrl_inherit_mon
>>
>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/
>>
>> Why do we still need to keep the "inherit_ctrl_and_mon"? By default all the groups in the system falls in this category it is not plza enabled group.
>>
>>
>> System boots up with following options if PLZA is supported.
>>
>> # cat info/kernel_mode
>> global_assign_ctrl_assign_mon_per_cpu
>> global_assign_ctrl_inherit_mon_per_cpu
>>
>> No groups are associated with kernel mode at this point.
>
> To me it seems useful to be clear to user space on what the current mode is. If I understand correctly
> above default scenario essentially means "inherit_ctrl_and_mon" but instead of adding it to this file
> we will need to add documentation that describes to user space how this file should be interpreted.
> It seems easier to me to just be clear via info/kernel_mode itself on what the current active mode is?
>
> I think something like below will be more intuitive and not need much additional
> documentation to understand (I am just adding the "uninitialized" as an example to match text
> printed in schemata file during pseudo-locking ... even if there is a group named "uninitialized"
> the lack of "/" could be used to make it clear what this means?):
>
> # cat info/kernel_mode
> [inherit_ctrl_and_mon]
> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
> global_assign_ctrl_inherit_mon_per_cpu:group=uninitialized
>
Sounds ok to me.
> I also think an interface like this would be simpler for user space to use as it (user space) switches
> between PLZA capable and non-PLZA capable systems since user space need not associate existence of
> the file with some kernel mode state in addition to actual content of the file when it does exist.
>
> I assumed that info/kernel_mode can just always be made visible and not depend on PLZA
> capable hardware. This means that on Intel and Arm this file can show:
>
> # cat info/kernel_mode
> [inherit_ctrl_and_mon]
>
Yes. Sure.
> For Intel this is accurate and also for Arm if I interpret the Arm implementation correctly
> (see mpam_thread_switch()) in https://lore.kernel.org/lkml/20260313144617.3420416-7-ben.horgan@arm.com/
>
>>
>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/" > info/kernel_mode
>>
>> # cat info/kernel_mode
>> global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/
>> global_assign_ctrl_inherit_mon_per_cpu
>>
>>
>> # echo "global_assign_ctrl_inherit_mon_per_cpu:group=//" > info/kernel_mode
>>
>>
>> # cat info/kernel_mode
>> global_assign_ctrl_assign_mon_per_cpu
>> global_assign_ctrl_inherit_mon_per_cpu:group=//
>>
>>
>> How does this look?
>
> In addition to above I think it will be helpful to add a clear indication to user
> space on what the current active mode is, for example, via the [] characters.
# echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/" >
info/kernel_mode
# cat info/kernel_mode
inherit_ctrl_and_mon
global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
[global_assign_ctrl_assign_mon_per_cpu]:group=ctrl1/mon1/
Something like this?
There is one problem here. The mode "inherit_ctrl_and_mon" listing not
consistent with others.
Thanks
Babu
^ permalink raw reply
* Re: [PATCH v12 09/16] KVM: arm64: define kvm_arch_gmem_supports_no_direct_map()
From: Marc Zyngier @ 2026-04-21 16:55 UTC (permalink / raw)
To: Kalyazin, Nikita
Cc: kvm@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
kernel@xen0n.name, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, loongarch@lists.linux.dev,
linux-pm@vger.kernel.org, pbonzini@redhat.com, corbet@lwn.net,
oupton@kernel.org, joey.gouly@arm.com, suzuki.poulose@arm.com,
yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org,
seanjc@google.com, tglx@kernel.org, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org,
hpa@zytor.com, luto@kernel.org, peterz@infradead.org,
willy@infradead.org, akpm@linux-foundation.org, david@kernel.org,
lorenzo.stoakes@oracle.com, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, ast@kernel.org,
daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev,
eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev,
john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me,
haoluo@google.com, jolsa@kernel.org, jgg@ziepe.ca,
jhubbard@nvidia.com, peterx@redhat.com, jannh@google.com,
pfalcato@suse.de, skhan@linuxfoundation.org, riel@surriel.com,
ryan.roberts@arm.com, jgross@suse.com, yu-cheng.yu@intel.com,
kas@kernel.org, coxu@redhat.com, ackerleytng@google.com,
yosry@kernel.org, ajones@ventanamicro.com, maobibo@loongson.cn,
tabba@google.com, prsampat@amd.com, wu.fei9@sanechips.com.cn,
mlevitsk@redhat.com, jmattson@google.com, jthoughton@google.com,
agordeev@linux.ibm.com, alex@ghiti.fr, aou@eecs.berkeley.edu,
borntraeger@linux.ibm.com, chenhuacai@kernel.org,
baolu.lu@linux.intel.com, dev.jain@arm.com, gor@linux.ibm.com,
hca@linux.ibm.com, palmer@dabbelt.com, pjw@kernel.org,
shijie@os.amperecomputing.com, svens@linux.ibm.com,
thuth@redhat.com, yang@os.amperecomputing.com,
Liam.Howlett@oracle.com, urezki@gmail.com,
zhengqi.arch@bytedance.com, gerald.schaefer@linux.ibm.com,
jiayuan.chen@shopee.com, lenb@kernel.org, pavel@kernel.org,
rafael@kernel.org, yangyicong@hisilicon.com,
vannapurve@google.com, jackmanb@google.com, patrick.roy@linux.dev,
Thomson, Jack, Itazuri, Takahiro, Manwaring, Derek
In-Reply-To: <20260410151746.61150-10-kalyazin@amazon.com>
On Fri, 10 Apr 2026 16:19:24 +0100,
"Kalyazin, Nikita" <kalyazin@amazon.co.uk> wrote:
>
> From: Patrick Roy <patrick.roy@linux.dev>
>
> Support for GUEST_MEMFD_FLAG_NO_DIRECT_MAP on arm64 depends on 1) direct
> map manipulations at 4k granularity being possible, and 2) FEAT_S2FWB.
>
> 1) is met whenever the direct map is set up at 4k granularity (e.g. not
> with huge/gigantic pages) at boottime, as due to ARM's
> break-before-make semantics, breaking huge mappings into 4k mappings in
> the direct map is not possible (BBM would require temporary invalidation
> of the entire huge mapping, even if only a 4k subrange should be zapped,
> which will probably crash the kernel). However, the current default for
> rodata_full is true, which forces a 4k direct map.
Where is this 4kB requirement enforced? Or is it that you means
"PAGE_SIZE"?
>
> 2) is required to allow KVM to elide cache coherency operations when
> installing stage 2 page tables, which require the direct map to be
> entry for the newly mapped memory to be present (which it will not be,
> as guest_memfd would have removed direct map entries in
> kvm_gmem_get_pfn()).
>
> Cc: Will Deacon <will@kernel.org>
> Signed-off-by: Patrick Roy <patrick.roy@linux.dev>
> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Nikita Kalyazin <nikita.kalyazin@linux.dev>
> ---
> arch/arm64/include/asm/kvm_host.h | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 70cb9cfd760a..fbdd43e7e94e 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -19,6 +19,7 @@
> #include <linux/maple_tree.h>
> #include <linux/percpu.h>
> #include <linux/psci.h>
> +#include <linux/set_memory.h>
> #include <asm/arch_gicv3.h>
> #include <asm/barrier.h>
> #include <asm/cpufeature.h>
> @@ -1682,6 +1683,18 @@ static __always_inline enum fgt_group_id __fgt_reg_to_group_id(enum vcpu_sysreg
> \
> p; \
> })
> +#ifdef CONFIG_KVM_GUEST_MEMFD
KVM/arm64 has:
select KVM_GUEST_MEMFD
> +static inline bool kvm_arch_gmem_supports_no_direct_map(struct kvm *kvm)
> +{
> + /*
> + * Without FWB, direct map access is needed in kvm_pgtable_stage2_map(),
> + * as it calls dcache_clean_inval_poc().
> + */
> + return can_set_direct_map() && cpus_have_final_cap(ARM64_HAS_STAGE2_FWB);
> +}
> +#define kvm_arch_gmem_supports_no_direct_map kvm_arch_gmem_supports_no_direct_map
> +#endif /* CONFIG_KVM_GUEST_MEMFD */
Why is it an inline function? Given that it takes a kvm parameter,
I fully expect that you'll have to evaluate this at some point.
But since struct kvm cannot be dereferenced in asm/kvm_host.h, it will
have to move. How about doing it right now?
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v12 10/16] KVM: guest_memfd: Add flag to remove from direct map
From: Frank van der Linden @ 2026-04-21 17:08 UTC (permalink / raw)
To: Sean Christopherson
Cc: Nikita Kalyazin, kvm@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
kernel@xen0n.name, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, loongarch@lists.linux.dev,
linux-pm@vger.kernel.org, pbonzini@redhat.com, corbet@lwn.net,
maz@kernel.org, oupton@kernel.org, joey.gouly@arm.com,
suzuki.poulose@arm.com, yuzenghui@huawei.com,
catalin.marinas@arm.com, will@kernel.org, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
x86@kernel.org, hpa@zytor.com, luto@kernel.org,
peterz@infradead.org, willy@infradead.org,
akpm@linux-foundation.org, david@kernel.org,
lorenzo.stoakes@oracle.com, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, ast@kernel.org,
daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev,
eddyz87@gmail.com, song@kernel.org, yonghong.song@linux.dev,
john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me,
haoluo@google.com, jolsa@kernel.org, jgg@ziepe.ca,
jhubbard@nvidia.com, peterx@redhat.com, jannh@google.com,
pfalcato@suse.de, skhan@linuxfoundation.org, riel@surriel.com,
ryan.roberts@arm.com, jgross@suse.com, yu-cheng.yu@intel.com,
kas@kernel.org, coxu@redhat.com, ackerleytng@google.com,
yosry@kernel.org, ajones@ventanamicro.com, maobibo@loongson.cn,
tabba@google.com, prsampat@amd.com, wu.fei9@sanechips.com.cn,
mlevitsk@redhat.com, jmattson@google.com, jthoughton@google.com,
agordeev@linux.ibm.com, alex@ghiti.fr, aou@eecs.berkeley.edu,
borntraeger@linux.ibm.com, chenhuacai@kernel.org,
baolu.lu@linux.intel.com, dev.jain@arm.com, gor@linux.ibm.com,
hca@linux.ibm.com, palmer@dabbelt.com, pjw@kernel.org,
shijie@os.amperecomputing.com, svens@linux.ibm.com,
thuth@redhat.com, yang@os.amperecomputing.com,
Liam.Howlett@oracle.com, urezki@gmail.com,
zhengqi.arch@bytedance.com, gerald.schaefer@linux.ibm.com,
jiayuan.chen@shopee.com, lenb@kernel.org, pavel@kernel.org,
rafael@kernel.org, yangyicong@hisilicon.com,
vannapurve@google.com, jackmanb@google.com, patrick.roy@linux.dev,
Jack Thomson, Takahiro Itazuri, Derek Manwaring, Nikita Kalyazin
In-Reply-To: <aeemS2wm38Cm4qAf@google.com>
On Tue, Apr 21, 2026 at 9:31 AM Sean Christopherson <seanjc@google.com> wrote:
>
> On Fri, Apr 10, 2026, Nikita Kalyazin wrote:
> > From: Patrick Roy <patrick.roy@linux.dev>
> >
> > Add GUEST_MEMFD_FLAG_NO_DIRECT_MAP flag for KVM_CREATE_GUEST_MEMFD()
> > ioctl. When set, guest_memfd folios will be removed from the direct map
> > after preparation, with direct map entries only restored when the folios
> > are freed.
> >
> > To ensure these folios do not end up in places where the kernel cannot
> > deal with them, set AS_NO_DIRECT_MAP on the guest_memfd's struct
> > address_space if GUEST_MEMFD_FLAG_NO_DIRECT_MAP is requested.
> >
> > Note that this flag causes removal of direct map entries for all
> > guest_memfd folios independent of whether they are "shared" or "private"
> > (although current guest_memfd only supports either all folios in the
> > "shared" state, or all folios in the "private" state if
> > GUEST_MEMFD_FLAG_MMAP is not set). The usecase for removing direct map
> > entries of also the shared parts of guest_memfd are a special type of
> > non-CoCo VM where, host userspace is trusted to have access to all of
> > guest memory, but where Spectre-style transient execution attacks
> > through the host kernel's direct map should still be mitigated. In this
> > setup, KVM retains access to guest memory via userspace mappings of
> > guest_memfd, which are reflected back into KVM's memslots via
> > userspace_addr. This is needed for things like MMIO emulation on x86_64
> > to work.
> >
> > Direct map entries are zapped right before guest or userspace mappings
> > of gmem folios are set up, e.g. in kvm_gmem_fault_user_mapping() or
> > kvm_gmem_get_pfn() [called from the KVM MMU code].
>
> ...
>
> > +#define KVM_GMEM_FOLIO_NO_DIRECT_MAP BIT(0)
> > +
> > +static bool kvm_gmem_folio_no_direct_map(struct folio *folio)
> > +{
> > + return ((u64)folio->private) & KVM_GMEM_FOLIO_NO_DIRECT_MAP;
> > +}
> > +
> > +static int kvm_gmem_folio_zap_direct_map(struct folio *folio)
> > +{
> > + int r = 0;
> > +
> > + VM_WARN_ON_FOLIO(!folio_test_locked(folio), folio);
> > +
> > + if (WARN_ON_ONCE(!(GMEM_I(folio_inode(folio))->flags & GUEST_MEMFD_FLAG_NO_DIRECT_MAP)))
> > + return -EINVAL;
> > +
> > + if (kvm_gmem_folio_no_direct_map(folio))
> > + goto out;
> > +
> > + r = folio_zap_direct_map(folio);
> > + if (!r)
> > + folio->private = (void *)((u64)folio->private | KVM_GMEM_FOLIO_NO_DIRECT_MAP);
> > +
> > +out:
> > + return r;
> > +}
> > +
> > +static void kvm_gmem_folio_restore_direct_map(struct folio *folio)
> > +{
> > + folio_restore_direct_map(folio);
> > + folio->private = (void *)((u64)folio->private & ~KVM_GMEM_FOLIO_NO_DIRECT_MAP);
> > +}
>
> Making guest_memfd responsible for zapping and restoring the direct map on a per-
> folio basis feels wrong given the addition of AS_NO_DIRECT_MAP. I especially don't
> like that the "rules" for when an AS_NO_DIRECT_MAP folio has a direct map will vary
> based on the owner, and even within an owner (e.g. guest_memfd) will be ad hoc.
>
> E.g. as per the series to add guest_memfd write() support[*]:
>
> When direct map removal is implemented [2]
> - write() will not be allowed to access pages that have already
> been removed from direct map
> - on completion, write() will remove the populated pages from
> direct map
>
> That's pretty gross ABI, because with KVM_GMEM_FOLIO_NO_DIRECT_MAP, userspace can
> write() exactly once. To re-write memory, I assume userspace would need to do a
> PUNCH_HOLE or truncate.
>
> What's preventing us from handling this automagically in e.g. filemap_add_folio()
> and filemap_remove_folio()? Then the usage rules are pretty straightforward: the
> kernel must *always* assume the direct map is invalid for folios from
> AS_NO_DIRECT_MAP mappings.
>
> Then if KVM needs to utilize a kernel mapping, e.g. in kvm_gmem_populate(), KVM
> could use dedicated variants of kmap_local_xxx() to deal with a local mapping for
> a folio/page without a direct map. Or, KVM could simply disallow the specific
> sequence that would require KVM to do the memcpy (I'm pretty sure we can do that
> with in-place shared=>private conversion support).
>
> I realize that could throw a big wrench into write() performance, but IMO, before
> merging either series, we need a complete story for exactly how this will all fit
> together, in a maintainable fashion and with sane ABI.
>
> [*] https://lore.kernel.org/all/20251114151828.98165-1-kalyazin@amazon.com
>
I agree with this - this approach would also allow for memory that was
never in the direct map to begin with, or has been taken out already
(for which I happen to have a use case :-)). guest_memfd and other
code can then assume that AS_NO_DIRECT_MAP means they have to take
explicit action to map it if needed. It's a clean, simple ABI.
With the current set of patches, it seems like this couldn't be done
in a clean manner.
- Frank
^ permalink raw reply
* Re: [PATCH net-deletions] net: remove ISDN subsystem and Bluetooth CMTP
From: Randy Dunlap @ 2026-04-21 17:12 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, marcel, mchehab+huawei, jani.nikula, gregkh, demarchi,
justonli, ivecera, jonathan.cameron, kees, marco.crivellari,
ferr.lambarginio, nihaal, mingo, tglx, linmq006, linux-doc,
linux-bluetooth
In-Reply-To: <CABBYNZ+yCH2hxbS32o6eDT7BDMLZd3YpjUZ=sfiw=z9XjMT6OQ@mail.gmail.com>
On 4/21/26 6:55 AM, Luiz Augusto von Dentz wrote:
> Hi Jakub,
>
> On Mon, Apr 20, 2026 at 10:21 PM Jakub Kicinski <kuba@kernel.org> wrote:
>>
>> Remove the ISDN (mISDN, CAPI) subsystem and Bluetooth CMTP protocol
>> from the kernel tree.
>>
>>
>
> Acked-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Please don't send 1.7 MB emails for an Ack.
See https://people.kernel.org/tglx/,
especially "Trim replies".
--
~Randy
^ permalink raw reply
* Re: [PATCH net-deletions] net: remove ax25 and amateur radio (hamradio) subsystem
From: Stephen Hemminger @ 2026-04-21 17:14 UTC (permalink / raw)
To: Dan Cross
Cc: Jakub Kicinski, davem, netdev, edumazet, pabeni, andrew+netdev,
horms, corbet, skhan, federico.vaga, carlos.bilbao, avadhut.naik,
alexs, si.yanteng, dzm91, 2023002089, tsbogend, dsahern,
jani.nikula, mchehab+huawei, gregkh, jirislaby, tytso, herbert,
ebiggers, johannes.berg, geert, pablo, tglx, mashiro.chen, mingo,
dqfext, jreuter, sdf, pkshih, enelsonmoore, mkl, toke, kees,
jlayton, wangliang74, aha310510, takamitz, kuniyu, linux-doc,
linux-mips
In-Reply-To: <CAEoi9W6ZRw6aEh62Xbgkg-TW8URHbVp6dHTT9krFiTkotjTuTA@mail.gmail.com>
On Tue, 21 Apr 2026 12:17:23 -0400
Dan Cross <crossd@gmail.com> wrote:
> On Tue, Apr 21, 2026 at 9:55 AM Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> > On Mon, 20 Apr 2026 19:18:23 -0700
> > Jakub Kicinski <kuba@kernel.org> wrote:
> > > Remove the amateur radio (AX.25, NET/ROM, ROSE) protocol implementation
> > > and all associated hamradio device drivers from the kernel tree.
> > > This set of protocols has long been a huge bug/syzbot magnet,
> > > and since nobody stepped up to help us deal with the influx
> > > of the AI-generated bug reports we need to move it out of tree
> > > to protect our sanity.
> > >
> > > The code is moved to an out-of-tree repo:
> > > https://github.com/linux-netdev/mod-orphan
> > > if it's cleaned up and reworked there we can accept it back.
> >
> > It would be good if these protocols could be done in userspace
> > or with BPF?
>
> Consensus for a userspace implementation is what folks on linux-hams
> seem to be converging on.
>
> The amateur radio protocols are more or less specific to low-speed
> links, they are not particularly coupled to anything else that
> requires running in the kernel, and the main coupling point (IP over
> AX.25) can be implemented via TAP/TUN.
>
> There are several popular packages that already implement AX.25 and
> NET/ROM in user-space (for the interested, LinBPQ seems to be the
> canonical example). The main missing piece is ROSE, but it is likely
> easier to add that to an existing package, or potentially something
> brand new, than keep it in the kernel.
>
> There's no compelling reason to keep these protocols in the kernel,
> whether in-tree or out-of-tree; at least, one has not been
> articulated.
>
> - Dan C.
Thanks, my other concern is carrying support for these in ip commands.
If not kernel based, then iproute2 doesn't need to worry.
^ permalink raw reply
* Re: [PATCH v11 07/20] gpu: nova-core: mm: Add TLB flush support
From: Joel Fernandes @ 2026-04-21 17:23 UTC (permalink / raw)
To: Danilo Krummrich
Cc: linux-kernel, Miguel Ojeda, Boqun Feng, Gary Guo, Bjorn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Dave Airlie, Daniel Almeida, Koen Koning, dri-devel,
rust-for-linux, Nikola Djukic, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jonathan Corbet,
Alex Deucher, Christian Koenig, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Huang Rui, Matthew Auld,
Lucas De Marchi, Thomas Hellstrom, Helge Deller, Alex Gaynor,
Boqun Feng, John Hubbard, Alistair Popple, Timur Tabi, Edwin Peer,
Alexandre Courbot, Andrea Righi, Andy Ritger, Zhi Wang,
Balbir Singh, Philipp Stanner, Elle Rhumsaa, alexeyi,
Eliot Courtney, joel, linux-doc, amd-gfx, intel-gfx, intel-xe,
linux-fbdev
In-Reply-To: <9f30b572-04be-4adc-b5f0-a286ea601996@nvidia.com>
On Tue, Apr 21, 2026 at 09:47:39AM -0400, Joel Fernandes wrote:
>
>
> On 4/16/2026 6:53 PM, Danilo Krummrich wrote:
> > On Fri Apr 17, 2026 at 12:18 AM CEST, Joel Fernandes wrote:
> >> On 4/16/2026 5:45 PM, Danilo Krummrich wrote:
> >>> Why do we need the try_access() dance in the first place? I assume this ends up
> >>> being called from the BarAccess destructor?
> >>
> >> BarAccess is different. The try_access() calls here are in tlb.rs and
> >> pramin.rs for Bar0.
> >
> > Yes, and we shouldn't need them in the first place; we should have a
> > &Device<Bound> in all call paths this is called from.
So it causes a bit more threading of the device, but agreed it is an improvement.
Here is a preview, let me know if this is not what you had in mind, thanks!
---8<-----------------------
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 6ea9ab7647ced..c2756525dffad 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -322,7 +322,7 @@ pub(crate) fn new<'a>(
// PRAMIN covers all physical VRAM (including GSP-reserved areas
// above the usable region, e.g. the BAR1 page directory).
let pramin_vram_region = 0..gsp_static_info.total_fb_end;
- GpuMm::new(devres_bar.clone(), spec.chipset, GpuBuddyParams {
+ GpuMm::new(devres_bar.clone(), pdev.as_ref(), spec.chipset, GpuBuddyParams {
base_offset: usable_vram.start,
size: usable_vram.end - usable_vram.start,
chunk_size: Alignment::new::<SZ_4K>(),
diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs
index 2583e32fb5dc1..1c0d076a785d5 100644
--- a/drivers/gpu/nova-core/mm.rs
+++ b/drivers/gpu/nova-core/mm.rs
@@ -32,6 +32,7 @@ fn from(pfn: Pfn) -> Self {
use kernel::{
bitfield,
+ device,
devres::Devres,
gpu::buddy::{
GpuBuddy,
@@ -75,13 +76,14 @@ impl GpuMm {
/// areas). PRAMIN window accesses are validated against this range.
pub(crate) fn new(
bar: Arc<Devres<Bar0>>,
+ dev: &device::Device<device::Bound>,
chipset: Chipset,
buddy_params: GpuBuddyParams,
pramin_vram_region: core::ops::Range<u64>,
) -> Result<impl PinInit<Self>> {
let buddy = GpuBuddy::new(buddy_params)?;
let tlb_init = Tlb::new(bar.clone());
- let pramin_init = pramin::Pramin::new(bar, chipset, pramin_vram_region)?;
+ let pramin_init = pramin::Pramin::new(bar, dev, chipset, pramin_vram_region)?;
Ok(pin_init!(Self {
buddy,
diff --git a/drivers/gpu/nova-core/mm/bar_user.rs b/drivers/gpu/nova-core/mm/bar_user.rs
index 086d33776c48a..172f9c0f5b4d8 100644
--- a/drivers/gpu/nova-core/mm/bar_user.rs
+++ b/drivers/gpu/nova-core/mm/bar_user.rs
@@ -4,6 +4,7 @@
//! for GPU work submission, and applications to access GPU buffers via mmap().
use kernel::{
+ device,
io::Io,
prelude::*, //
};
@@ -45,6 +46,7 @@ pub(crate) fn new(pdb_addr: VramAddress, chipset: Chipset, va_size: u64) -> Resu
/// Map physical pages to a contiguous BAR1 virtual range.
pub(crate) fn map<'a>(
&'a mut self,
+ dev: &'a device::Device<device::Bound>,
mm: &'a GpuMm,
bar: &'a Bar1,
pfns: &[Pfn],
@@ -54,10 +56,11 @@ pub(crate) fn map<'a>(
return Err(EINVAL);
}
- let mapped = self.vmm.map_pages(mm, pfns, None, writable)?;
+ let mapped = self.vmm.map_pages(dev, mm, pfns, None, writable)?;
Ok(BarUserAccess {
vmm: &mut self.vmm,
+ dev,
mm,
bar,
mapped: Some(mapped),
@@ -72,6 +75,7 @@ pub(crate) fn map<'a>(
/// [`Vmm::unmap_pages()`], which consumes it).
pub(crate) struct BarUserAccess<'a> {
vmm: &'a mut Vmm,
+ dev: &'a device::Device<device::Bound>,
mm: &'a GpuMm,
bar: &'a Bar1,
/// Needs to be an `Option` so that we can `take()` it and call `Drop`
@@ -144,7 +148,7 @@ pub(crate) fn try_write64(&self, value: u64, offset: usize) -> Result {
impl Drop for BarUserAccess<'_> {
fn drop(&mut self) {
if let Some(mapped) = self.mapped.take() {
- if self.vmm.unmap_pages(self.mm, mapped).is_err() {
+ if self.vmm.unmap_pages(self.dev, self.mm, mapped).is_err() {
kernel::pr_warn_once!("BarUserAccess: unmap_pages failed.\n");
}
}
@@ -158,7 +162,7 @@ fn drop(&mut self) {
/// and test pages as needed.
#[cfg(CONFIG_NOVA_MM_SELFTESTS)]
pub(crate) fn run_self_test(
- dev: &kernel::device::Device,
+ pdev: &device::Device<device::Bound>,
mm: &GpuMm,
bar1: &Bar1,
bar1_pdb: u64,
@@ -180,12 +184,13 @@ pub(crate) fn run_self_test(
const PATTERN_PRAMIN: u32 = 0xDEAD_BEEF;
const PATTERN_BAR1: u32 = 0xCAFE_BABE;
+ let dev = pdev.as_ref();
dev_info!(dev, "MM: Starting self-test...\n");
let pdb_addr = VramAddress::new(bar1_pdb);
// Check if initial page tables are in VRAM.
- if crate::mm::pagetable::check_pdb_valid(mm.pramin(), pdb_addr, chipset).is_err() {
+ if crate::mm::pagetable::check_pdb_valid(pdev, mm.pramin(), pdb_addr, chipset).is_err() {
dev_info!(dev, "MM: Self-test SKIPPED - no valid VRAM page tables\n");
return Ok(());
}
@@ -208,7 +213,7 @@ pub(crate) fn run_self_test(
let mut vmm = Vmm::new(pdb_addr, chipset.mmu_version(), SZ_64K.into_safe_cast())?;
// Create a test mapping.
- let mapped = vmm.map_pages(mm, &[test_pfn], None, true)?;
+ let mapped = vmm.map_pages(pdev, mm, &[test_pfn], None, true)?;
let test_vfn = mapped.vfn_start;
// Pre-compute test addresses for the PRAMIN to BAR1 read test.
@@ -219,7 +224,7 @@ pub(crate) fn run_self_test(
// Test 1: Write via PRAMIN, read via BAR1.
{
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(pdev)?;
window.try_write32(vram_read_addr, PATTERN_PRAMIN)?;
}
@@ -239,19 +244,19 @@ pub(crate) fn run_self_test(
};
// Cleanup - invalidate PTE.
- vmm.unmap_pages(mm, mapped)?;
+ vmm.unmap_pages(pdev, mm, mapped)?;
// Test 2: Two-phase prepare/execute API.
- let prepared = vmm.prepare_map(mm, 1, None)?;
- let mapped2 = vmm.execute_map(mm, prepared, &[test_pfn], true)?;
- let readback = vmm.read_mapping(mm, mapped2.vfn_start)?;
+ let prepared = vmm.prepare_map(pdev, mm, 1, None)?;
+ let mapped2 = vmm.execute_map(pdev, mm, prepared, &[test_pfn], true)?;
+ let readback = vmm.read_mapping(pdev, mm, mapped2.vfn_start)?;
let test2_passed = if readback == Some(test_pfn) {
true
} else {
dev_err!(dev, "MM: Test 2 FAILED - Two-phase map readback mismatch\n");
false
};
- vmm.unmap_pages(mm, mapped2)?;
+ vmm.unmap_pages(pdev, mm, mapped2)?;
// Test 3: Range-constrained allocation with a hole — exercises block.size()-driven
// BAR1 mapping. A 4K hole is punched at base+16K, then a single 32K allocation
@@ -311,7 +316,7 @@ pub(crate) fn run_self_test(
)?;
}
- let mapped = vmm.map_pages(mm, &pfns, None, true)?;
+ let mapped = vmm.map_pages(pdev, mm, &pfns, None, true)?;
let bar1_base_vfn: usize = mapped.vfn_start.raw().into_safe_cast();
let bar1_base = bar1_base_vfn.checked_mul(PAGE_SIZE).ok_or(EOVERFLOW)?;
@@ -326,7 +331,7 @@ pub(crate) fn run_self_test(
bar1.try_write32(PATTERN_BAR1, page_bar1_off)?;
let pramin_val = {
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(pdev)?;
window.try_read32(page_phys.into_safe_cast())?
};
@@ -342,7 +347,7 @@ pub(crate) fn run_self_test(
}
}
- vmm.unmap_pages(mm, mapped)?;
+ vmm.unmap_pages(pdev, mm, mapped)?;
}
// Verify aggregate: all returned block sizes must sum to allocation size.
@@ -363,11 +368,11 @@ pub(crate) fn run_self_test(
// Test 4: Exercise `BarUser::map()` end-to-end.
let mut bar_user = BarUser::new(pdb_addr, chipset, SZ_64K.into_safe_cast())?;
let test4_passed = {
- let access = bar_user.map(mm, bar1, &[test_pfn], true)?;
+ let access = bar_user.map(pdev, mm, bar1, &[test_pfn], true)?;
// Write pattern via PRAMIN, read via BarUserAccess.
{
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(pdev)?;
window.try_write32(test_vram.raw(), PATTERN_BAR1)?;
}
diff --git a/drivers/gpu/nova-core/mm/pagetable.rs b/drivers/gpu/nova-core/mm/pagetable.rs
index 922ff8bd4f0fd..b267dcf4dd8ba 100644
--- a/drivers/gpu/nova-core/mm/pagetable.rs
+++ b/drivers/gpu/nova-core/mm/pagetable.rs
@@ -22,7 +22,10 @@
VirtualAddress,
VramAddress, //
};
-use kernel::prelude::*;
+use kernel::{
+ device,
+ prelude::*, //
+};
/// Extracts the page table index at a given level from a virtual address.
pub(super) trait VaLevelIndex {
@@ -386,10 +389,11 @@ fn from(val: AperturePde) -> Self {
/// Check if the PDB has valid, VRAM-backed page tables.
#[cfg(CONFIG_NOVA_MM_SELFTESTS)]
fn check_pdb_inner<M: MmuConfig>(
+ dev: &device::Device<device::Bound>,
pramin: &pramin::Pramin,
pdb_addr: VramAddress,
) -> Result {
- let mut window = pramin.get_window()?;
+ let mut window = pramin.get_window(dev)?;
let raw = window.try_read64(pdb_addr.raw())?;
if !M::Pde::new(raw).is_valid_vram() {
@@ -401,12 +405,13 @@ fn check_pdb_inner<M: MmuConfig>(
/// Check if the PDB has valid, VRAM-backed page tables, dispatching by MMU version.
#[cfg(CONFIG_NOVA_MM_SELFTESTS)]
pub(super) fn check_pdb_valid(
+ dev: &device::Device<device::Bound>,
pramin: &pramin::Pramin,
pdb_addr: VramAddress,
chipset: crate::gpu::Chipset,
) -> Result {
match MmuVersion::from(chipset.arch()) {
- MmuVersion::V2 => check_pdb_inner::<MmuV2>(pramin, pdb_addr),
- MmuVersion::V3 => check_pdb_inner::<MmuV3>(pramin, pdb_addr),
+ MmuVersion::V2 => check_pdb_inner::<MmuV2>(dev, pramin, pdb_addr),
+ MmuVersion::V3 => check_pdb_inner::<MmuV3>(dev, pramin, pdb_addr),
}
}
diff --git a/drivers/gpu/nova-core/mm/pagetable/map.rs b/drivers/gpu/nova-core/mm/pagetable/map.rs
index a9719580143e1..16af491472dbc 100644
--- a/drivers/gpu/nova-core/mm/pagetable/map.rs
+++ b/drivers/gpu/nova-core/mm/pagetable/map.rs
@@ -5,6 +5,7 @@
use core::marker::PhantomData;
use kernel::{
+ device,
gpu::buddy::{
AllocatedBlocks,
GpuBuddyAllocFlags,
@@ -73,7 +74,11 @@ pub(super) fn new(pdb_addr: VramAddress) -> Self {
}
/// Allocate and zero a physical page table page.
- fn alloc_and_zero_page(mm: &GpuMm, level: PageTableLevel) -> Result<PreparedPtPage> {
+ fn alloc_and_zero_page(
+ dev: &device::Device<device::Bound>,
+ mm: &GpuMm,
+ level: PageTableLevel,
+ ) -> Result<PreparedPtPage> {
let blocks = KBox::pin_init(
mm.buddy().alloc_blocks(
GpuBuddyAllocMode::Simple,
@@ -87,7 +92,7 @@ fn alloc_and_zero_page(mm: &GpuMm, level: PageTableLevel) -> Result<PreparedPtPa
let page_vram = VramAddress::new(blocks.iter().next().ok_or(ENOMEM)?.offset());
// Zero via PRAMIN.
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(dev)?;
let base = page_vram.raw();
for off in (0..PAGE_SIZE).step_by(8) {
window.try_write64(base + off, 0)?;
@@ -106,6 +111,7 @@ fn alloc_and_zero_page(mm: &GpuMm, level: PageTableLevel) -> Result<PreparedPtPa
/// the fence signalling critical path.
fn ensure_single_pte_path(
&self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
vfn: Vfn,
pt_pages: &mut RBTree<VramAddress, PreparedPtPage>,
@@ -113,7 +119,7 @@ fn ensure_single_pte_path(
let max_iter = 2 * M::PDE_LEVELS.len();
for _ in 0..max_iter {
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(dev)?;
let result = self
.walker
@@ -133,7 +139,7 @@ fn ensure_single_pte_path(
} => {
// Drop PRAMIN before allocation.
drop(window);
- let page = Self::alloc_and_zero_page(mm, level)?;
+ let page = Self::alloc_and_zero_page(dev, mm, level)?;
let node = RBTreeNode::new(install_addr, page, GFP_KERNEL)?;
let old = pt_pages.insert(node);
if old.is_some() {
@@ -160,6 +166,7 @@ fn ensure_single_pte_path(
/// per-VFN to prepare pages for all missing PDEs.
pub(super) fn prepare_map(
&self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
vfn_start: Vfn,
num_pages: usize,
@@ -175,7 +182,7 @@ pub(super) fn prepare_map(
for i in 0..num_pages {
let i_u64: u64 = i.into_safe_cast();
let vfn = Vfn::new(vfn_start.raw() + i_u64);
- self.ensure_single_pte_path(mm, vfn, pt_pages)?;
+ self.ensure_single_pte_path(dev, mm, vfn, pt_pages)?;
}
Ok(())
}
@@ -185,6 +192,7 @@ pub(super) fn prepare_map(
/// Drains `pt_pages` and moves allocations into `page_table_allocs`.
pub(super) fn install_mappings(
&self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
pt_pages: &mut RBTree<VramAddress, PreparedPtPage>,
page_table_allocs: &mut KVec<Pin<KBox<AllocatedBlocks>>>,
@@ -192,7 +200,7 @@ pub(super) fn install_mappings(
pfns: &[Pfn],
writable: bool,
) -> Result {
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(dev)?;
// Drain prepared PT pages, install all pending PDEs.
let mut cursor = pt_pages.cursor_front_mut();
@@ -239,14 +247,20 @@ pub(super) fn install_mappings(
drop(window);
// Flush TLB.
- mm.tlb().flush(self.pdb_addr)
+ mm.tlb().flush(dev, self.pdb_addr)
}
/// Invalidate PTEs for a range and flush TLB.
- pub(super) fn invalidate_ptes(&self, mm: &GpuMm, vfn_start: Vfn, num_pages: usize) -> Result {
+ pub(super) fn invalidate_ptes(
+ &self,
+ dev: &device::Device<device::Bound>,
+ mm: &GpuMm,
+ vfn_start: Vfn,
+ num_pages: usize,
+ ) -> Result {
let invalid_pte = M::Pte::invalid();
- let mut window = mm.pramin().get_window()?;
+ let mut window = mm.pramin().get_window(dev)?;
for i in 0..num_pages {
let i_u64: u64 = i.into_safe_cast();
let vfn = Vfn::new(vfn_start.raw() + i_u64);
@@ -265,7 +279,7 @@ pub(super) fn invalidate_ptes(&self, mm: &GpuMm, vfn_start: Vfn, num_pages: usiz
}
drop(window);
- mm.tlb().flush(self.pdb_addr)
+ mm.tlb().flush(dev, self.pdb_addr)
}
}
@@ -298,6 +312,7 @@ pub(in crate::mm) fn new(pdb_addr: VramAddress, version: MmuVersion) -> Self {
/// Prepare page table resources for a mapping.
pub(in crate::mm) fn prepare_map(
&self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
vfn_start: Vfn,
num_pages: usize,
@@ -306,13 +321,14 @@ pub(in crate::mm) fn prepare_map(
) -> Result {
pt_map_dispatch!(
self,
- prepare_map(mm, vfn_start, num_pages, page_table_allocs, pt_pages)
+ prepare_map(dev, mm, vfn_start, num_pages, page_table_allocs, pt_pages)
)
}
/// Install prepared PDEs and write PTEs, then flush TLB.
pub(in crate::mm) fn install_mappings(
&self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
pt_pages: &mut RBTree<VramAddress, PreparedPtPage>,
page_table_allocs: &mut KVec<Pin<KBox<AllocatedBlocks>>>,
@@ -322,17 +338,18 @@ pub(in crate::mm) fn install_mappings(
) -> Result {
pt_map_dispatch!(
self,
- install_mappings(mm, pt_pages, page_table_allocs, vfn_start, pfns, writable)
+ install_mappings(dev, mm, pt_pages, page_table_allocs, vfn_start, pfns, writable)
)
}
/// Invalidate PTEs for a range and flush TLB.
pub(in crate::mm) fn invalidate_ptes(
&self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
vfn_start: Vfn,
num_pages: usize,
) -> Result {
- pt_map_dispatch!(self, invalidate_ptes(mm, vfn_start, num_pages))
+ pt_map_dispatch!(self, invalidate_ptes(dev, mm, vfn_start, num_pages))
}
}
diff --git a/drivers/gpu/nova-core/mm/pagetable/walk.rs b/drivers/gpu/nova-core/mm/pagetable/walk.rs
index 89d4426bcf144..fedb8b4f33e58 100644
--- a/drivers/gpu/nova-core/mm/pagetable/walk.rs
+++ b/drivers/gpu/nova-core/mm/pagetable/walk.rs
@@ -36,7 +36,10 @@
use core::marker::PhantomData;
-use kernel::prelude::*;
+use kernel::{
+ device,
+ prelude::*, //
+};
use super::{
DualPdeOps,
@@ -168,8 +171,13 @@ pub(super) fn walk_pde_levels(
/// Walk to PTE for lookup only (no allocation).
///
/// Returns [`WalkResult::PageTableMissing`] if intermediate tables don't exist.
- pub(super) fn walk_to_pte_lookup(&self, mm: &GpuMm, vfn: Vfn) -> Result<WalkResult> {
- let mut window = mm.pramin().get_window()?;
+ pub(super) fn walk_to_pte_lookup(
+ &self,
+ dev: &device::Device<device::Bound>,
+ mm: &GpuMm,
+ vfn: Vfn,
+ ) -> Result<WalkResult> {
+ let mut window = mm.pramin().get_window(dev)?;
self.walk_to_pte_lookup_with_window(&mut window, vfn)
}
@@ -236,7 +244,12 @@ pub(in crate::mm) fn new(pdb_addr: VramAddress, version: MmuVersion) -> Self {
}
/// Walk to PTE for lookup.
- pub(in crate::mm) fn walk_to_pte(&self, mm: &GpuMm, vfn: Vfn) -> Result<WalkResult> {
- pt_walk_dispatch!(self, walk_to_pte_lookup(mm, vfn))
+ pub(in crate::mm) fn walk_to_pte(
+ &self,
+ dev: &device::Device<device::Bound>,
+ mm: &GpuMm,
+ vfn: Vfn,
+ ) -> Result<WalkResult> {
+ pt_walk_dispatch!(self, walk_to_pte_lookup(dev, mm, vfn))
}
}
diff --git a/drivers/gpu/nova-core/mm/pramin.rs b/drivers/gpu/nova-core/mm/pramin.rs
index f56d6c3d4e255..c16717a73ecba 100644
--- a/drivers/gpu/nova-core/mm/pramin.rs
+++ b/drivers/gpu/nova-core/mm/pramin.rs
@@ -75,11 +75,11 @@
};
use kernel::{
+ device,
devres::Devres,
io::Io,
new_mutex,
prelude::*,
- revocable::RevocableGuard,
sizes::{
SZ_1M,
SZ_64K, //
@@ -117,7 +117,7 @@ pub(crate) fn $name(&mut self, vram_offset: usize) -> Result<$ty> {
self.compute_window(vram_offset, ::core::mem::size_of::<$ty>())?;
if let Some(base) = new_base {
- regs::pramin_window_write_base(self.chipset.arch(), &self.bar, base)?;
+ regs::pramin_window_write_base(self.chipset.arch(), self.bar, base)?;
*self.state = base;
}
self.bar.$name(bar_offset)
@@ -134,7 +134,7 @@ pub(crate) fn $name(&mut self, vram_offset: usize, value: $ty) -> Result {
self.compute_window(vram_offset, ::core::mem::size_of::<$ty>())?;
if let Some(base) = new_base {
- regs::pramin_window_write_base(self.chipset.arch(), &self.bar, base)?;
+ regs::pramin_window_write_base(self.chipset.arch(), self.bar, base)?;
*self.state = base;
}
self.bar.$name(value, bar_offset)
@@ -169,11 +169,12 @@ impl Pramin {
/// `vram_region` specifies the valid VRAM address range.
pub(crate) fn new(
bar: Arc<Devres<Bar0>>,
+ dev: &device::Device<device::Bound>,
chipset: Chipset,
vram_region: Range<u64>,
) -> Result<impl PinInit<Self>> {
- let bar_access = bar.try_access().ok_or(ENODEV)?;
- let current_base = regs::pramin_window_read_base(chipset.arch(), &bar_access);
+ let bar_access = bar.access(dev)?;
+ let current_base = regs::pramin_window_read_base(chipset.arch(), bar_access);
Ok(pin_init!(Self {
bar,
@@ -192,8 +193,11 @@ fn vram_region(&self) -> &Range<u64> {
///
/// Returns a [`PraminWindow`] guard that provides VRAM read/write accessors.
/// The [`PraminWindow`] is exclusive and only one can exist at a time.
- pub(crate) fn get_window(&self) -> Result<PraminWindow<'_>> {
- let bar = self.bar.try_access().ok_or(ENODEV)?;
+ pub(crate) fn get_window<'a>(
+ &'a self,
+ dev: &'a device::Device<device::Bound>,
+ ) -> Result<PraminWindow<'a>> {
+ let bar = self.bar.access(dev)?;
let state = self.state.lock();
Ok(PraminWindow {
bar,
@@ -212,7 +216,7 @@ pub(crate) fn get_window(&self) -> Result<PraminWindow<'_>> {
/// Only one [`PraminWindow`] can exist at a time per [`Pramin`] instance (enforced by the
/// internal `MutexGuard`).
pub(crate) struct PraminWindow<'a> {
- bar: RevocableGuard<'a, Bar0>,
+ bar: &'a Bar0,
chipset: Chipset,
vram_region: Range<u64>,
state: MutexGuard<'a, u64>,
@@ -433,14 +437,15 @@ fn test_misaligned_access(
/// Run PRAMIN self-tests during boot if self-tests are enabled.
#[cfg(CONFIG_NOVA_MM_SELFTESTS)]
-pub(crate) fn run_self_test(dev: &kernel::device::Device, pramin: &Pramin) -> Result {
+pub(crate) fn run_self_test(pdev: &device::Device<device::Bound>, pramin: &Pramin) -> Result {
+ let dev = pdev.as_ref();
dev_info!(dev, "PRAMIN: Starting self-test...\n");
let vram_region = pramin.vram_region();
let base: usize = vram_region.start.into_safe_cast();
let base = base + SELFTEST_REGION_OFFSET;
let vram_end = vram_region.end;
- let mut win = pramin.get_window()?;
+ let mut win = pramin.get_window(pdev)?;
test_byte_readwrite(dev, &mut win, base)?;
test_u32_as_bytes(dev, &mut win, base)?;
diff --git a/drivers/gpu/nova-core/mm/tlb.rs b/drivers/gpu/nova-core/mm/tlb.rs
index 8d36e1552792d..53c6fe6084b81 100644
--- a/drivers/gpu/nova-core/mm/tlb.rs
+++ b/drivers/gpu/nova-core/mm/tlb.rs
@@ -11,17 +11,22 @@
//! ```ignore
//! use crate::mm::tlb::Tlb;
//!
-//! fn page_table_update(tlb: &Tlb, pdb_addr: VramAddress) -> Result<()> {
+//! fn page_table_update(
+//! dev: &device::Device<device::Bound>,
+//! tlb: &Tlb,
+//! pdb_addr: VramAddress,
+//! ) -> Result<()> {
//! // ... modify page tables ...
//!
//! // Flush TLB to make changes visible (polls for completion).
-//! tlb.flush(pdb_addr)?;
+//! tlb.flush(dev, pdb_addr)?;
//!
//! Ok(())
//! }
//! ```
use kernel::{
+ device,
devres::Devres,
io::poll::read_poll_timeout,
io::Io,
@@ -92,39 +97,29 @@ pub(super) fn new(bar: Arc<Devres<Bar0>>) -> impl PinInit<Self> {
/// This invalidates all TLB entries associated with the given PDB address.
/// Must be called after modifying page table entries to ensure the GPU sees
/// the updated mappings.
- pub(super) fn flush(&self, pdb_addr: VramAddress) -> Result {
+ pub(super) fn flush(
+ &self,
+ dev: &device::Device<device::Bound>,
+ pdb_addr: VramAddress,
+ ) -> Result {
let _guard = self.lock.lock();
+ let bar = self.bar.access(dev)?;
- // Broken into 2 phases with scopes (Write and Poll) to avoid holding
- // RevecablableGuard (and hence RCU read-side critical section) across
- // the read_poll_timeout() call that can sleep.
+ // Write PDB address.
+ bar.write_reg(regs::NV_TLB_FLUSH_PDB_LO::from_pdb_addr(pdb_addr.raw_u64()));
+ bar.write_reg(regs::NV_TLB_FLUSH_PDB_HI::from_pdb_addr(pdb_addr.raw_u64()));
- // Write phase — hold bar access briefly for register writes only.
- {
- let bar = self.bar.try_access().ok_or(ENODEV)?;
+ // Trigger flush.
+ bar.write_reg(
+ regs::NV_TLB_FLUSH_CTRL::zeroed()
+ .with_all_va(true)
+ .with_ack(TlbAckMode::None)
+ .with_trigger(true),
+ );
- // Write PDB address.
- bar.write_reg(regs::NV_TLB_FLUSH_PDB_LO::from_pdb_addr(pdb_addr.raw_u64()));
- bar.write_reg(regs::NV_TLB_FLUSH_PDB_HI::from_pdb_addr(pdb_addr.raw_u64()));
-
- // Trigger flush: invalidate all virtual addresses, require global
- // acknowledgment from all engines before completion. See
- // [`TlbAckMode::Globally`] for why this scope is used unconditionally.
- bar.write_reg(
- regs::NV_TLB_FLUSH_CTRL::zeroed()
- .with_all_va(true)
- .with_ack(TlbAckMode::None)
- .with_trigger(true),
- );
- }
-
- // Poll for completion — re-acquire bar access each iteration to avoid
- // holding the RCU read-side lock (via RevocableGuard) across sleep.
+ // Poll for completion.
read_poll_timeout(
- || {
- let bar = self.bar.try_access().ok_or(ENODEV)?;
- Ok(bar.read(regs::NV_TLB_FLUSH_CTRL))
- },
+ || Ok(bar.read(regs::NV_TLB_FLUSH_CTRL)),
|ctrl: ®s::NV_TLB_FLUSH_CTRL| !ctrl.trigger(),
Delta::ZERO,
Delta::from_secs(2),
diff --git a/drivers/gpu/nova-core/mm/vmm.rs b/drivers/gpu/nova-core/mm/vmm.rs
index 45da443211583..35caaed56007e 100644
--- a/drivers/gpu/nova-core/mm/vmm.rs
+++ b/drivers/gpu/nova-core/mm/vmm.rs
@@ -6,6 +6,7 @@
//! virtual address spaces (Channels, BAR1, BAR2).
use kernel::{
+ device,
gpu::buddy::AllocatedBlocks,
maple_tree::MapleTreeAlloc,
prelude::*,
@@ -207,8 +208,13 @@ fn free_vfn(&self, vfn: Vfn) {
}
/// Read the [`Pfn`] for a mapped [`Vfn`] if one is mapped.
- pub(super) fn read_mapping(&self, mm: &GpuMm, vfn: Vfn) -> Result<Option<Pfn>> {
- match self.pt_walk.walk_to_pte(mm, vfn)? {
+ pub(super) fn read_mapping(
+ &self,
+ dev: &device::Device<device::Bound>,
+ mm: &GpuMm,
+ vfn: Vfn,
+ ) -> Result<Option<Pfn>> {
+ match self.pt_walk.walk_to_pte(dev, mm, vfn)? {
WalkResult::Mapped { pfn, .. } => Ok(Some(pfn)),
WalkResult::Unmapped { .. } | WalkResult::PageTableMissing => Ok(None),
}
@@ -223,6 +229,7 @@ pub(super) fn read_mapping(&self, mm: &GpuMm, vfn: Vfn) -> Result<Option<Pfn>> {
/// to call outside the fence signalling critical path.
pub(crate) fn prepare_map(
&mut self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
num_pages: usize,
va_range: Option<Range<u64>>,
@@ -235,6 +242,7 @@ pub(crate) fn prepare_map(
let vfn_start = self.alloc_vfn_range(num_pages, va_range)?;
if let Err(e) = self.pt_map.prepare_map(
+ dev,
mm,
vfn_start,
num_pages,
@@ -257,6 +265,7 @@ pub(crate) fn prepare_map(
/// Installs all prepared PDEs and writes PTEs into the page table, then flushes TLB.
pub(crate) fn execute_map(
&mut self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
prepared: PreparedMapping,
pfns: &[Pfn],
@@ -275,6 +284,7 @@ pub(crate) fn execute_map(
_drop_guard.disarm();
if let Err(e) = self.pt_map.install_mappings(
+ dev,
mm,
&mut self.pt_pages,
&mut self.page_table_allocs,
@@ -300,6 +310,7 @@ pub(crate) fn execute_map(
/// [`Vmm::execute_map()`] will be called separately.
pub(crate) fn map_pages(
&mut self,
+ dev: &device::Device<device::Bound>,
mm: &GpuMm,
pfns: &[Pfn],
va_range: Option<Range<u64>>,
@@ -322,15 +333,20 @@ pub(crate) fn map_pages(
}
}
- let prepared = self.prepare_map(mm, pfns.len(), va_range)?;
- self.execute_map(mm, prepared, pfns, writable)
+ let prepared = self.prepare_map(dev, mm, pfns.len(), va_range)?;
+ self.execute_map(dev, mm, prepared, pfns, writable)
}
/// Unmap all pages in a [`MappedRange`] with a single TLB flush.
- pub(crate) fn unmap_pages(&mut self, mm: &GpuMm, range: MappedRange) -> Result {
+ pub(crate) fn unmap_pages(
+ &mut self,
+ dev: &device::Device<device::Bound>,
+ mm: &GpuMm,
+ range: MappedRange,
+ ) -> Result {
let result = self
.pt_map
- .invalidate_ptes(mm, range.vfn_start, range.num_pages);
+ .invalidate_ptes(dev, mm, range.vfn_start, range.num_pages);
// TODO: Internal page table pages (PDE, PTE pages) are still kept around.
// This is by design as repeated maps/unmaps will be fast. As a future TODO,
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] Documentation: adopt new coding style of type-aware kmalloc-family
From: Kees Cook @ 2026-04-21 17:25 UTC (permalink / raw)
To: Jonathan Corbet
Cc: Manuel Ebner, Shuah Khan, linux-doc, lrcu, linux-kernel,
workflows, linux-sound, rcu, linux-media
In-Reply-To: <87se8rw8df.fsf@trenco.lwn.net>
On Sun, Apr 19, 2026 at 04:29:48AM -0600, Jonathan Corbet wrote:
> Manuel Ebner <manuelebner@mailbox.org> writes:
>
> > Update the documentation to reflect new type-aware kmalloc-family as
> > suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
> >
> > ptr = kmalloc(sizeof(*ptr), gfp);
> > -> ptr = kmalloc_obj(*ptr, gfp);
> > ptr = kmalloc(sizeof(struct some_obj_name), gfp);
> > -> ptr = kmalloc_obj(*ptr, gfp);
> > ptr = kzalloc(sizeof(*ptr), gfp);
> > -> ptr = kzalloc_obj(*ptr, gfp);
> > ptr = kmalloc_array(count, sizeof(*ptr), gfp);
> > -> ptr = kmalloc_objs(*ptr, count, gfp);
> > ptr = kcalloc(count, sizeof(*ptr), gfp);
> > -> ptr = kzalloc_objs(*ptr, count, gfp);
> >
> > Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
>
> Just to be sure, did you write this patch yourself, or did you use some
> sort of coding assistant?
>
> Adding Kees, who did this work and might have something to add here.
>
> > ---
> > .../RCU/Design/Requirements/Requirements.rst | 6 +++---
> > Documentation/RCU/listRCU.rst | 2 +-
> > Documentation/RCU/whatisRCU.rst | 4 ++--
>
> This patch will surely need to be split up; the RCU folks, for example,
> will want to evaluate the change separately.
>
> > Documentation/core-api/kref.rst | 4 ++--
> > Documentation/core-api/list.rst | 4 ++--
> > Documentation/core-api/memory-allocation.rst | 4 ++--
> > Documentation/driver-api/mailbox.rst | 4 ++--
> > Documentation/driver-api/media/v4l2-fh.rst | 2 +-
> > Documentation/kernel-hacking/locking.rst | 4 ++--
> > Documentation/locking/locktypes.rst | 4 ++--
> > Documentation/process/coding-style.rst | 8 ++++----
> > .../sound/kernel-api/writing-an-alsa-driver.rst | 12 ++++++------
> > Documentation/spi/spi-summary.rst | 4 ++--
> > .../translations/it_IT/kernel-hacking/locking.rst | 4 ++--
> > .../translations/it_IT/locking/locktypes.rst | 4 ++--
> > .../translations/it_IT/process/coding-style.rst | 2 +-
> > .../translations/sp_SP/process/coding-style.rst | 2 +-
> > Documentation/translations/zh_CN/core-api/kref.rst | 4 ++--
> > .../translations/zh_CN/process/coding-style.rst | 2 +-
> > .../zh_CN/video4linux/v4l2-framework.txt | 2 +-
> > .../translations/zh_TW/process/coding-style.rst | 2 +-
> > 21 files changed, 42 insertions(+), 42 deletions(-)
> >
> > diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst
> > index b5cdbba3ec2e..faca5a9c8c12 100644
> > --- a/Documentation/RCU/Design/Requirements/Requirements.rst
> > +++ b/Documentation/RCU/Design/Requirements/Requirements.rst
> > @@ -206,7 +206,7 @@ non-\ ``NULL``, locklessly accessing the ``->a`` and ``->b`` fields.
> >
> > 1 bool add_gp_buggy(int a, int b)
> > 2 {
> > - 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
> > + 3 p = kmalloc_obj(*p, GFP_KERNEL);
>
> So you have not gone with the "implicit GFP_KERNEL" approach that Linus
> added. Given that, I assume, he wanted that to be the normal style, we
> should probably go with it.
Thank you for updating the documentation! Yes, please drop the "default"
GFP_KERNEL args in all these places. (Keep the non-GFP_KERNEL args; I
see at least GFP_ATOMIC in the docs.)
--
Kees Cook
^ permalink raw reply
* Re: [PATCH 0/2] Documentation/binfmt-misc.rst: Clarify "P" flag
From: Kees Cook @ 2026-04-21 17:29 UTC (permalink / raw)
To: Charlie Jenkins
Cc: Jonathan Corbet, Shuah Khan, linux-doc, linux-mm, linux-kernel
In-Reply-To: <20260419-binfmt_misc_doc_update_p-v1-0-757c12f33cc2@gmail.com>
On Sun, Apr 19, 2026 at 12:11:01AM -0400, Charlie Jenkins wrote:
> Improve the wording of the description of the "P" flag to explain that
> the interpreter gets the path to the file provided by execve and not the
> full path as well as documenting that AT_FLAGS can be read to see if the
> "P" flag is set.
Thanks for the clarifications! I'll get this into the execve tree once
the merge window is over. (I usually wait for -rc2 to be released.)
(Or maybe this should go via linux-doc? I should add this file to the
EXEC entry in MAINTAINERS...)
How did you happen across this mismatch(?weakness?) in the docs?
-Kees
--
Kees Cook
^ permalink raw reply
* Re: [PATCH 18/23] cpu/hotplug: Add a new cpuhp_offline_cb() API
From: Waiman Long @ 2026-04-21 17:29 UTC (permalink / raw)
To: Thomas Gleixner, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <87o6jcb84w.ffs@tglx>
On 4/21/26 12:17 PM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>> Add a new cpuhp_offline_cb() API that allows us to offline a set of
>> CPUs one-by-one, run the given callback function and then bring those
>> CPUs back online again while inhibiting any concurrent CPU hotplug
>> operations from happening.
> Please provide a properly structured change log which explains the
> context, the problem and the solution in separate paragraphs and this
> order. This is not new. It's documented...
>
>> This new API can be used to enable runtime adjustment of nohz_full and
>> isolcpus boot command line options. A new cpuhp_offline_cb_mode flag
>> is also added to signal that the system is in this offline callback
>> transient state so that some hotplug operations can be optimized out
>> if we choose to.
> We chose nothing.
>
>> +#include <linux/cpumask_types.h>
> What for? This header only needs a 'struct cpumask' forward declaration
> so that the compiler can handle the pointer argument, no?
>
>> +typedef int (*cpuhp_cb_t)(void *arg);
> You couldn't come up with a more generic name for this, right?
>
>> struct device;
>>
>> extern int lockdep_is_cpus_held(void);
>> @@ -29,6 +31,8 @@ void clear_tasks_mm_cpumask(int cpu);
>> int remove_cpu(unsigned int cpu);
>> int cpu_device_down(struct device *dev);
>> void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);
>> +int cpuhp_offline_cb(struct cpumask *mask, cpuhp_cb_t func, void *arg);
> Ditto.
>
>> +extern bool cpuhp_offline_cb_mode;
> Groan. The only users are in the cpusets code which invokes this muck
> and should therefore know what's going on, no?
>
>> #else /* CONFIG_HOTPLUG_CPU */
>>
>> @@ -43,6 +47,11 @@ static inline void cpu_hotplug_disable(void) { }
>> static inline void cpu_hotplug_enable(void) { }
>> static inline int remove_cpu(unsigned int cpu) { return -EPERM; }
>> static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
>> +static inline int cpuhp_offline_cb(struct cpumask *mask, cpuhp_cb_t func, void *arg)
>> +{
>> + return -EPERM;
> -EPERM?
>
>> +/**
>> + * cpuhp_offline_cb - offline CPUs, invoke callback function & online CPUs afterward
>> + * @mask: A mask of CPUs to be taken offline and then online
>> + * @func: A callback function to be invoked while the given CPUs are offline
>> + * @arg: Argument to be passed back to the callback function
>> + *
>> + * Return: 0 if successful, an error code otherwise
>> + */
>> +int cpuhp_offline_cb(struct cpumask *mask, cpuhp_cb_t func, void *arg)
>> +{
>> + int off_cpu, on_cpu, ret, ret2 = 0;
>> +
>> + if (WARN_ON_ONCE(cpumask_empty(mask) ||
>> + !cpumask_subset(mask, cpu_online_mask)))
>> + return -EINVAL;
> No line break required. You have 100 characters.
>
> But what's worse is that the access to cpu_online_mask is not protected
> against a concurrent CPU hotplug operation.
>
>> +
>> + pr_debug("%s: begin (CPU list = %*pbl)\n", __func__, cpumask_pr_args(mask));
> Tracing?
>
>> + lock_device_hotplug();
>> + cpuhp_offline_cb_mode = true;
>> + /*
>> + * If all offline operations succeed, off_cpu should become nr_cpu_ids.
>> + */
>> + for_each_cpu(off_cpu, mask) {
>> + ret = device_offline(get_cpu_device(off_cpu));
>> + if (unlikely(ret))
>> + break;
>> + }
>> + if (!ret)
>> + ret = func(arg);
>> +
>> + /* Bring previously offline CPUs back online */
>> + for_each_cpu(on_cpu, mask) {
>> + int retries = 0;
>> +
>> + if (on_cpu == off_cpu)
>> + break;
>> +
>> +retry:
>> + ret2 = device_online(get_cpu_device(on_cpu));
>> +
>> + /*
>> + * With the unlikely event that CPU hotplug is disabled while
>> + * this operation is in progress, we will need to wait a bit
>> + * for hotplug to hopefully be re-enabled again. If not, print
>> + * a warning and return the error.
>> + *
>> + * cpu_hotplug_disabled is supposed to be accessed while
>> + * holding the cpu_add_remove_lock mutex. So we need to
>> + * use the data_race() macro to access it here.
>> + */
>> + while ((ret2 == -EBUSY) && data_race(cpu_hotplug_disabled) &&
>> + (++retries <= 5)) {
>> + msleep(20);
>> + if (!data_race(cpu_hotplug_disabled))
>> + goto retry;
>> + }
>> + if (ret2) {
>> + pr_warn("%s: Failed to bring CPU %d back online!\n",
>> + __func__, on_cpu);
> Provide a proper text and not this silly __func__ thing.
>
>> + break;
>> + }
>> + }
> TBH. This is unreviewable gunk and the whole 'unlikely event that CPU
> hotplug is disabled' is just a lazy hack.
>
> All of this can be avoided including this made up callback function.
>
> It's not rocket science to provide:
>
> 1) A function which serializes against any other CPU hotplug
> related action.
>
> 2) A function which brings the CPUs in a given CPU mask down
>
> 3) A function which brings the CPUs in a given CPU mask up
>
> 4) A function which undoes #1
>
> Yeah I know, it's more work and not convoluted enough. But see below.
>
> That brings me to that other hack namely cpuhp_offline_cb_mode, which
> you self described as such in patch 21/23:
>
>> + /*
>> + * Hack: In cpuhp_offline_cb_mode, pretend all partitions are empty
>> + * to prevent unnecessary partition invalidation.
>> + */
>> + if (cpuhp_offline_cb_mode)
>> + return false;
>> +
> We are not merging hacks. End of story. But you knew that already, no?
>
> Let's take a step back and see what you really need to achieve:
>
> 1) Update tick_nohz_full_mask
> 2) Update the managed interrupt mask
> 3) Update CPU sets
>
> Independent of the direction of this update you need to ensure that the
> affected functionality keeps working correctly.
>
> You achieve that by bulk offlining the affected CPUs, invoking a magic
> callback and then bulk onlining the affected CPUs again, which requires
> that ill defined cpuhp_offline_cb_mode hackery and probably some more
> hacks all over the place.
>
> You can achieve the same by doing CPU by CPU operations in the right
> order without this mode hack, when you establish proper limitations for
> this:
>
> At no point in time it's allowed to empty a CPU set or a affected CPU
> mask, except when you completely undo the isolation of CPUs.
>
> That can be computed upfront w/o changing anything at all. Once the
> validity is established, the update can proceed. Or you can leave it
> to user space which can keep the pieces if it gets it wrong.
>
> That's a reasonable limitation as there is absolutely zero justification
> to support something like:
>
> housekeeping_cpus = [CPU 0], isolated_cpus = [CPU 1]
> ---> housekeeping_cpus = [CPU 1], isolated_cpus = [CPU 0]
>
> just because we can with enough horrible hacks.
>
> If you get that out of the way, then a CPU by CPU update becomes the
> obvious and simplest solution. The ordering constraints can be computed
> in user space upfront and there is no reason to do any of this in the
> kernel itself except for an eventual validation step. It might be a tad
> slower, but this is all but a hotpath operation.
>
> Just for the record. I suggested exactly this more than a year ago and
> it's still the right thing to do.
>
> And of course neither your cover letter nor any of the patches give a
> proper rationale why you think that your bulk hackery is better. For the
> very simple reason that there is no rationale at all.
>
> This bulk muck is doomed when your ultimate goal is to avoid the stop
> machine dance. With a per CPU update it is actually doable without more
> ill defined hacks all over the place.
>
> 1) Bring down the CPU to CPUHP_AP_SCHED_WAIT_EMPTY, which is the last
> state before stop machine is invoked.
>
> At that point:
>
> - no user space thread is running on the CPU anymore
>
> - everything related to this CPU has been shut down or moved
> elsewhere
>
> - interrupt managed device queues are quiesced if the CPU was
> the last online one in the queue affinity mask. If not the
> interrupt might still be affine to the CPU, but there is at
> least one other CPU available in the mask.
>
> 2) Update the tick NOHZ handover
>
> This can be done without going into stop machine by providing a
> hotplug callback right between CPUHP_AP_SMPBOOT_THREADS and
> CPUHP_AP_IRQ_AFFINITY_ONLINE.
>
> That's trivial enough to achieve and can work independently of
> NOHZ full.
>
> 3) Rework the affinity management, so that interrupt affinities can
> be reassigned in the CPUHP_AP_IRQ_AFFINITY_ONLINE state.
>
> That needs a lot of thoughts, but there is no real reason why it
> can't work.
>
> 4) Flip the housekeeping CPU masks in sched_cpu_wait_empty() after
> balance_hotplug_wait().
>
> 5) Bring the CPU online again.
>
> For #2 and #3 to work you need a separate CPU mask which avoids touching
> CPU online mask. For #3 this needs some more work to avoid reassigning the
> interrupts once sparse_irq_lock is dropped, but the bulk is achieved
> with the separate CPU mask.
>
> No?
Thanks for the great suggestions. I will certainly look into that.
We actually have a cpu_active_mask that will be cleared early in
sched_cpu_deactivate(). In the CPUHP_AP_SCHED_WAIT_EMPTY state, the CPU
will still have online bit set but the active bit will be cleared. Or we
could add another cpumask that can be used to indicate CPUs that have
reached CPUHP_AP_SCHED_WAIT_EMPTY or below if necessary.
Cheers,
Longman
^ permalink raw reply
* Re: [PATCH v2 00/16] fs,x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem
From: Reinette Chatre @ 2026-04-21 17:35 UTC (permalink / raw)
To: Babu Moger, Moger, Babu, corbet@lwn.net, tony.luck@intel.com,
Dave.Martin@arm.com, james.morse@arm.com, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com
Cc: skhan@linuxfoundation.org, x86@kernel.org, hpa@zytor.com,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kas@kernel.org, rick.p.edgecombe@intel.com,
akpm@linux-foundation.org, pmladek@suse.com,
rdunlap@infradead.org, dapeng1.mi@linux.intel.com,
kees@kernel.org, elver@google.com, paulmck@kernel.org,
lirongqing@baidu.com, safinaskar@gmail.com, fvdl@google.com,
seanjc@google.com, pawan.kumar.gupta@linux.intel.com,
xin@zytor.com, tiala@microsoft.com, chang.seok.bae@intel.com,
Lendacky, Thomas, elena.reshetova@intel.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-coco@lists.linux.dev, kvm@vger.kernel.org,
eranian@google.com, peternewman@google.com
In-Reply-To: <a46f4f2d-e3f1-454f-b94b-c54e14e45a69@amd.com>
Hi Babu,
On 4/21/26 9:46 AM, Babu Moger wrote:
> On 4/21/26 11:15, Reinette Chatre wrote:
>> On 4/21/26 8:08 AM, Babu Moger wrote:
>> It sounds like we are saying the same thing?
>> When considering all the sharp corners I agree that keeping kernel_mode_cpus/kernel_mode_cpuslist
>> seems most user friendly. When doing so there is no need to include CPU assignment in the global
>> files.
>
> Actually, I was talking about removing _per_cpu extension also as the per-CPU requirement is handled inside the group using kernel_mode_cpus/kernel_mode_cpuslist. It can be documented.
>
> global_assign_ctrl_assign_mon_per_cpu -> global_assign_ctrl_assign_mon
> global_assign_ctrl_inherit_mon_per_cpu -> global_assign_ctrl_inherit_mon
I see. The goal with this name choice was to distinguish a global mode that
additionally supports per-CPU assignment from a "true/pure" global mode that
does not support per-CPU assignment.
If resctrl ever needs to support such "true/pure" global mode that does
not support per-CPU assignment then resctrl will need to either come up with
a new mode that does not expose kernel_mode_cpus/kernel_mode_cpuslist or
make kernel_mode_cpus/kernel_mode_cpuslist read-only. The latter adds the
complication that user space can always change the mode of a file so resctrl
would need to add corner cases for that.
To me the "per_cpu" distinction is useful since it make it clear to user space
that even though this is a "global" configuration it additionally supports
per-CPU assignment for which user space can expect kernel_mode_cpus/kernel_mode_cpuslist
to exist and be writable. To me this makes the interface clear and intuitive.
>>>
>>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/
>>>
>>> Why do we still need to keep the "inherit_ctrl_and_mon"? By default all the groups in the system falls in this category it is not plza enabled group.
>>>
>>>
>>> System boots up with following options if PLZA is supported.
>>>
>>> # cat info/kernel_mode
>>> global_assign_ctrl_assign_mon_per_cpu
>>> global_assign_ctrl_inherit_mon_per_cpu
>>>
>>> No groups are associated with kernel mode at this point.
>>
>> To me it seems useful to be clear to user space on what the current mode is. If I understand correctly
>> above default scenario essentially means "inherit_ctrl_and_mon" but instead of adding it to this file
>> we will need to add documentation that describes to user space how this file should be interpreted.
>> It seems easier to me to just be clear via info/kernel_mode itself on what the current active mode is?
>>
>> I think something like below will be more intuitive and not need much additional
>> documentation to understand (I am just adding the "uninitialized" as an example to match text
>> printed in schemata file during pseudo-locking ... even if there is a group named "uninitialized"
>> the lack of "/" could be used to make it clear what this means?):
>>
>> # cat info/kernel_mode
>> [inherit_ctrl_and_mon]
>> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
>> global_assign_ctrl_inherit_mon_per_cpu:group=uninitialized
>>
>
> Sounds ok to me.
>
>
>> I also think an interface like this would be simpler for user space to use as it (user space) switches
>> between PLZA capable and non-PLZA capable systems since user space need not associate existence of
>> the file with some kernel mode state in addition to actual content of the file when it does exist.
>>
>> I assumed that info/kernel_mode can just always be made visible and not depend on PLZA
>> capable hardware. This means that on Intel and Arm this file can show:
>>
>> # cat info/kernel_mode
>> [inherit_ctrl_and_mon]
>>
>
> Yes. Sure.
>
>
>> For Intel this is accurate and also for Arm if I interpret the Arm implementation correctly
>> (see mpam_thread_switch()) in https://lore.kernel.org/lkml/20260313144617.3420416-7-ben.horgan@arm.com/
>>
>>>
>>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/" > info/kernel_mode
>>>
>>> # cat info/kernel_mode
>>> global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/
>>> global_assign_ctrl_inherit_mon_per_cpu
>>>
>>>
>>> # echo "global_assign_ctrl_inherit_mon_per_cpu:group=//" > info/kernel_mode
>>>
>>>
>>> # cat info/kernel_mode
>>> global_assign_ctrl_assign_mon_per_cpu
>>> global_assign_ctrl_inherit_mon_per_cpu:group=//
>>>
>>>
>>> How does this look?
>>
>> In addition to above I think it will be helpful to add a clear indication to user
>> space on what the current active mode is, for example, via the [] characters.
>
> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/" > info/kernel_mode
>
> # cat info/kernel_mode
> inherit_ctrl_and_mon
> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
> [global_assign_ctrl_assign_mon_per_cpu]:group=ctrl1/mon1/
>
> Something like this?
How about making it clear that the whole line/configuration is active, like below:
# cat info/kernel_mode
inherit_ctrl_and_mon
global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
[global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/]
>
> There is one problem here. The mode "inherit_ctrl_and_mon" listing not consistent with others.
It is difficult to predict what resctrl will be asked to support next. One possibility here is
to make it part of the original design that the first field is the "mode" and the following field
contains that mode's global properties of which there could be more than one. Above shows that
the two "global" modes have a single global property but we could just try to be safe with some
documentation that states there could be more.
Consider for example some hypothetical future where the file looks like:
# cat info/kernel_mode
inherit_ctrl_and_mon:some_unique_capability=true
global_assign_ctrl_assign_mon_per_cpu:group=uninitialized;other_property=val
[global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/]
To leave room for growth the file could start out by, for example, appending ":"
to "inherit_ctrl_and_mon" to indicate that there are no known properties yet? Something like
below. Would this be more consistent with the others?
# cat info/kernel_mode
inherit_ctrl_and_mon:
global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
[global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/]
Reinette
^ permalink raw reply
* Re: [PATCH v3 07/24] vfio/pci: Preserve vfio-pci device files across Live Update
From: David Matlack @ 2026-04-21 17:40 UTC (permalink / raw)
To: Alex Williamson, Bjorn Helgaas
Cc: Adithya Jayachandran, Alexander Graf, Alex Mastro, Andrew Morton,
Ankit Agrawal, Arnd Bergmann, Askar Safin, Borislav Petkov (AMD),
Chris Li, Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan,
Jason Gunthorpe, Jason Gunthorpe, Jonathan Corbet, Josh Hilke,
Kees Cook, Kevin Tian, kexec, kvm, Leon Romanovsky,
Leon Romanovsky, linux-doc, linux-kernel, linux-kselftest,
linux-mm, linux-pci, Li RongQing, Lukas Wunner, Marco Elver,
Michał Winiarski, Mike Rapoport, Parav Pandit,
Pasha Tatashin, Paul E. McKenney, Pawan Gupta,
Peter Zijlstra (Intel), Pranjal Shrivastava, Pratyush Yadav,
Raghavendra Rao Ananta, Randy Dunlap, Rodrigo Vivi,
Saeed Mahameed, Samiullah Khawaja, Shuah Khan, Vipin Sharma,
Vivek Kasireddy, William Tu, Yi Liu, Zhu Yanjun
In-Reply-To: <20260323235817.1960573-8-dmatlack@google.com>
On Mon, Mar 23, 2026 at 4:58 PM David Matlack <dmatlack@google.com> wrote:
> +static int vfio_pci_liveupdate_freeze(struct liveupdate_file_op_args *args)
> +{
> + struct vfio_device *device = vfio_device_from_file(args->file);
> + struct vfio_pci_core_device *vdev;
> + struct pci_dev *pdev;
> + int ret;
> +
> + vdev = container_of(device, struct vfio_pci_core_device, vdev);
> + pdev = vdev->pdev;
> +
> + guard(mutex)(&device->dev_set->lock);
> +
> + /*
> + * Userspace must disable interrupts on the device prior to freeze so
> + * that the device does not send any interrupts until new interrupt
> + * handlers have been established by the next kernel.
> + */
> + if (vdev->irq_type != VFIO_PCI_NUM_IRQS) {
> + pci_err(pdev, "Freeze failed! Interrupts are still enabled.\n");
> + return -EINVAL;
> + }
> +
> + ret = pci_load_saved_state(pdev, vdev->pci_saved_state);
> + if (ret)
> + return ret;
> +
> + vfio_pci_core_try_reset(vdev);
I think a call to pci_clear_master() is needed here to so the device
stops issuing memory transactions while VFIO is trying to resetting
it. Otherwise I see these timeouts when running
vfio_pci_liveupdate_kexec_test with Intel DSA: "timed out waiting for
pending transaction; performing function level reset anyway".
Sashiko also wondered if pci_clear_master() is needed to ensure that
the device has bus mastering disabled during the kexec but I don't
think that is actually an issue. vfio_pci_core_enable() makes sure
that vdev->pci_saved_state has bus mastering disabled, so
pci_restore_state() below here should guaranteed it is clear during
kexec.
https://sashiko.dev/#/patchset/20260323235817.1960573-1-dmatlack%40google.com?part=7
> + pci_restore_state(pdev);
> + return 0;
> }
^ permalink raw reply
* Re: [PATCH net-deletions] net: remove ax25 and amateur radio (hamradio) subsystem
From: Dan Cross @ 2026-04-21 17:47 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Jakub Kicinski, davem, netdev, edumazet, pabeni, andrew+netdev,
horms, corbet, skhan, federico.vaga, carlos.bilbao, avadhut.naik,
alexs, si.yanteng, dzm91, 2023002089, tsbogend, dsahern,
jani.nikula, mchehab+huawei, gregkh, jirislaby, tytso, herbert,
ebiggers, johannes.berg, geert, pablo, tglx, mashiro.chen, mingo,
dqfext, jreuter, sdf, pkshih, enelsonmoore, mkl, toke, kees,
jlayton, wangliang74, aha310510, takamitz, kuniyu, linux-doc,
linux-mips
In-Reply-To: <20260421101400.67545b20@phoenix.local>
On Tue, Apr 21, 2026 at 1:14 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Tue, 21 Apr 2026 12:17:23 -0400
> Dan Cross <crossd@gmail.com> wrote:
>
> > On Tue, Apr 21, 2026 at 9:55 AM Stephen Hemminger
> > <stephen@networkplumber.org> wrote:
> > > On Mon, 20 Apr 2026 19:18:23 -0700
> > > Jakub Kicinski <kuba@kernel.org> wrote:
> > > > Remove the amateur radio (AX.25, NET/ROM, ROSE) protocol implementation
> > > > and all associated hamradio device drivers from the kernel tree.
> > > > This set of protocols has long been a huge bug/syzbot magnet,
> > > > and since nobody stepped up to help us deal with the influx
> > > > of the AI-generated bug reports we need to move it out of tree
> > > > to protect our sanity.
> > > >
> > > > The code is moved to an out-of-tree repo:
> > > > https://github.com/linux-netdev/mod-orphan
> > > > if it's cleaned up and reworked there we can accept it back.
> > >
> > > It would be good if these protocols could be done in userspace
> > > or with BPF?
> >
> > Consensus for a userspace implementation is what folks on linux-hams
> > seem to be converging on.
> >
> > The amateur radio protocols are more or less specific to low-speed
> > links, they are not particularly coupled to anything else that
> > requires running in the kernel, and the main coupling point (IP over
> > AX.25) can be implemented via TAP/TUN.
> >
> > There are several popular packages that already implement AX.25 and
> > NET/ROM in user-space (for the interested, LinBPQ seems to be the
> > canonical example). The main missing piece is ROSE, but it is likely
> > easier to add that to an existing package, or potentially something
> > brand new, than keep it in the kernel.
> >
> > There's no compelling reason to keep these protocols in the kernel,
> > whether in-tree or out-of-tree; at least, one has not been
> > articulated.
>
> Thanks, my other concern is carrying support for these in ip commands.
> If not kernel based, then iproute2 doesn't need to worry.
Agreed.
If someone really wants mimic the existing output of those commands in
the context of a userspace implementation, they could write a wrapper
program that invokes the real thing, and extracts relevant information
from the ham protocol implementation, and interpolates it into the
output. It may be an imperfect simulation, but it's probably close
enough for most users.
- Dan C.
^ permalink raw reply
* [PATCH v2 0/3] Documentation: adopt new coding style of type-aware kmalloc-family
From: Manuel Ebner @ 2026-04-21 17:55 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook
Cc: linux-kernel, workflows, linux-sound, rcu, linux-media,
Manuel Ebner
Update the documentation to reflect new type-aware kmalloc-family as
suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
I have also thought about adding a few cases to checkpatch.pl, but this
will take me some time, and i don't know if i can do it.
[v1] -> [v2]:
put RCU/* in a seperate patch [Patch 2/3]
Omit optional argument (GFP_KERNEL) as suggested by https://lwn.net/Articles/1062856/
deprecated.rst: change the argument gfp to optional [Patch 3/3]
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
^ permalink raw reply
* Re: [PATCH] kbuild: document generation of offset header files
From: Nicolas Schier @ 2026-04-21 17:56 UTC (permalink / raw)
To: Piyush Patle
Cc: Nathan Chancellor, Jonathan Corbet, linux-kbuild, linux-doc,
Shuah Khan, Mark Rutland, Chen Pei, Randy Dunlap, Arnd Bergmann,
Masahiro Yamada, linux-kernel
In-Reply-To: <20260410221257.191517-1-piyushpatle228@gmail.com>
On Sat, Apr 11, 2026 at 03:42:54AM +0530, Piyush Patle wrote:
> Replace the placeholder reference with a description of how Kbuild
> generates offset header files such as include/generated/asm-offsets.h.
>
> Remove the corresponding TODO entry now that this is documented.
>
> Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
> ---
> Documentation/kbuild/makefiles.rst | 41 ++++++++++++++++++++++++------
> 1 file changed, 33 insertions(+), 8 deletions(-)
Looks good to me, thanks!
Reviewed-by: Nicolas Schier <nsc@kernel.org>
^ permalink raw reply
* [PATCH v2 1/3] Documentation: adopt new coding style of type-aware kmalloc-family
From: Manuel Ebner @ 2026-04-21 18:01 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc
Cc: Kees Cook, linux-kernel, workflows, linux-sound, linux-media,
Manuel Ebner
In-Reply-To: <20260421175516.224960-2-manuelebner@mailbox.org>
Update the documentation to reflect new type-aware kmalloc-family as
suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
ptr = kmalloc(sizeof(*ptr), gfp);
-> ptr = kmalloc_obj(*ptr);
ptr = kmalloc(sizeof(struct some_obj_name), gfp);
-> ptr = kmalloc_obj(*ptr);
ptr = kzalloc(sizeof(*ptr), gfp);
-> ptr = kzalloc_obj(*ptr);
ptr = kmalloc_array(count, sizeof(*ptr), gfp);
-> ptr = kmalloc_objs(*ptr, count);
ptr = kcalloc(count, sizeof(*ptr), gfp);
-> ptr = kzalloc_objs(*ptr, count);
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
---
Documentation/core-api/kref.rst | 4 ++--
Documentation/core-api/list.rst | 4 ++--
Documentation/core-api/memory-allocation.rst | 4 ++--
Documentation/driver-api/mailbox.rst | 4 ++--
Documentation/driver-api/media/v4l2-fh.rst | 2 +-
Documentation/kernel-hacking/locking.rst | 4 ++--
Documentation/locking/locktypes.rst | 4 ++--
Documentation/process/coding-style.rst | 8 ++++----
.../sound/kernel-api/writing-an-alsa-driver.rst | 12 ++++++------
Documentation/spi/spi-summary.rst | 4 ++--
.../translations/it_IT/kernel-hacking/locking.rst | 4 ++--
.../translations/it_IT/locking/locktypes.rst | 4 ++--
.../translations/it_IT/process/coding-style.rst | 2 +-
.../translations/sp_SP/process/coding-style.rst | 2 +-
Documentation/translations/zh_CN/core-api/kref.rst | 4 ++--
.../translations/zh_CN/process/coding-style.rst | 2 +-
.../zh_CN/video4linux/v4l2-framework.txt | 2 +-
.../translations/zh_TW/process/coding-style.rst | 2 +-
18 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/Documentation/core-api/kref.rst b/Documentation/core-api/kref.rst
index 8db9ff03d952..1c14c036699d 100644
--- a/Documentation/core-api/kref.rst
+++ b/Documentation/core-api/kref.rst
@@ -40,7 +40,7 @@ kref_init as so::
struct my_data *data;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
@@ -100,7 +100,7 @@ thread to process::
int rv = 0;
struct my_data *data;
struct task_struct *task;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
diff --git a/Documentation/core-api/list.rst b/Documentation/core-api/list.rst
index 241464ca0549..86cd0a1b77ea 100644
--- a/Documentation/core-api/list.rst
+++ b/Documentation/core-api/list.rst
@@ -112,7 +112,7 @@ list:
/* State 1 */
- grock = kzalloc(sizeof(*grock), GFP_KERNEL);
+ grock = kzalloc_obj(*grock);
if (!grock)
return -ENOMEM;
grock->name = "Grock";
@@ -123,7 +123,7 @@ list:
/* State 2 */
- dimitri = kzalloc(sizeof(*dimitri), GFP_KERNEL);
+ dimitri = kzalloc_obj(*dimitri);
if (!dimitri)
return -ENOMEM;
dimitri->name = "Dimitri";
diff --git a/Documentation/core-api/memory-allocation.rst b/Documentation/core-api/memory-allocation.rst
index 0f19dd524323..8379775f17d3 100644
--- a/Documentation/core-api/memory-allocation.rst
+++ b/Documentation/core-api/memory-allocation.rst
@@ -135,7 +135,7 @@ Selecting memory allocator
The most straightforward way to allocate memory is to use a function
from the kmalloc() family. And, to be on the safe side it's best to use
routines that set memory to zero, like kzalloc(). If you need to
-allocate memory for an array, there are kmalloc_array() and kcalloc()
+allocate memory for an array, there are kmalloc_objs() and kzalloc_objs()
helpers. The helpers struct_size(), array_size() and array3_size() can
be used to safely calculate object sizes without overflowing.
@@ -151,7 +151,7 @@ sizes, the alignment is guaranteed to be at least the largest power-of-two
divisor of the size.
Chunks allocated with kmalloc() can be resized with krealloc(). Similarly
-to kmalloc_array(): a helper for resizing arrays is provided in the form of
+to kmalloc_objs(): a helper for resizing arrays is provided in the form of
krealloc_array().
For large allocations you can use vmalloc() and vzalloc(), or directly
diff --git a/Documentation/driver-api/mailbox.rst b/Documentation/driver-api/mailbox.rst
index 463dd032b96c..4bcd73a99115 100644
--- a/Documentation/driver-api/mailbox.rst
+++ b/Documentation/driver-api/mailbox.rst
@@ -87,8 +87,8 @@ a message and a callback function to the API and return immediately).
struct async_pkt ap;
struct sync_pkt sp;
- dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
- dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
+ dc_sync = kzalloc_obj(*dc_sync);
+ dc_async = kzalloc_obj(*dc_async);
/* Populate non-blocking mode client */
dc_async->cl.dev = &pdev->dev;
diff --git a/Documentation/driver-api/media/v4l2-fh.rst b/Documentation/driver-api/media/v4l2-fh.rst
index a934caa483a4..38319130ebf5 100644
--- a/Documentation/driver-api/media/v4l2-fh.rst
+++ b/Documentation/driver-api/media/v4l2-fh.rst
@@ -42,7 +42,7 @@ Example:
...
- my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+ my_fh = kzalloc_obj(*my_fh);
...
diff --git a/Documentation/kernel-hacking/locking.rst b/Documentation/kernel-hacking/locking.rst
index dff0646a717b..d02e62367c4f 100644
--- a/Documentation/kernel-hacking/locking.rst
+++ b/Documentation/kernel-hacking/locking.rst
@@ -442,7 +442,7 @@ to protect the cache and all the objects within it. Here's the code::
{
struct object *obj;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
strscpy(obj->name, name, sizeof(obj->name));
@@ -517,7 +517,7 @@ which are taken away, and the ``+`` are lines which are added.
struct object *obj;
+ unsigned long flags;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
@@ -63,30 +64,33 @@
obj->id = id;
diff --git a/Documentation/locking/locktypes.rst b/Documentation/locking/locktypes.rst
index 37b6a5670c2f..ac1ad722a9e7 100644
--- a/Documentation/locking/locktypes.rst
+++ b/Documentation/locking/locktypes.rst
@@ -498,7 +498,7 @@ allocating memory. Thus, on a non-PREEMPT_RT kernel the following code
works perfectly::
raw_spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
But this code fails on PREEMPT_RT kernels because the memory allocator is
fully preemptible and therefore cannot be invoked from truly atomic
@@ -507,7 +507,7 @@ while holding normal non-raw spinlocks because they do not disable
preemption on PREEMPT_RT kernels::
spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
bit spinlocks
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst
index 35b381230f6e..a3bf75dc7c88 100644
--- a/Documentation/process/coding-style.rst
+++ b/Documentation/process/coding-style.rst
@@ -936,7 +936,7 @@ used.
---------------------
The kernel provides the following general purpose memory allocators:
-kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), and
+kmalloc(), kzalloc(), kmalloc_objs(), kzalloc_objs(), vmalloc(), and
vzalloc(). Please refer to the API documentation for further information
about them. :ref:`Documentation/core-api/memory-allocation.rst
<memory_allocation>`
@@ -945,7 +945,7 @@ The preferred form for passing a size of a struct is the following:
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
The alternative form where struct name is spelled out hurts readability and
introduces an opportunity for a bug when the pointer variable type is changed
@@ -959,13 +959,13 @@ The preferred form for allocating an array is the following:
.. code-block:: c
- p = kmalloc_array(n, sizeof(...), ...);
+ p = kmalloc_objs(*ptr, n, ...);
The preferred form for allocating a zeroed array is the following:
.. code-block:: c
- p = kcalloc(n, sizeof(...), ...);
+ p = kzalloc_objs(*ptr, n, ...);
Both forms check for overflow on the allocation size n * sizeof(...),
and return NULL if that occurred.
diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
index 895752cbcedd..12433612aa9c 100644
--- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
+++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
@@ -266,7 +266,7 @@ to details explained in the following section.
....
/* allocate a chip-specific data with zero filled */
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
if (chip == NULL)
return -ENOMEM;
@@ -628,7 +628,7 @@ After allocating a card instance via :c:func:`snd_card_new()`
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
.....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
The chip record should have the field to hold the card pointer at least,
@@ -747,7 +747,7 @@ destructor and PCI entries. Example code is shown first, below::
return -ENXIO;
}
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1737,7 +1737,7 @@ callback::
{
struct my_pcm_data *data;
....
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
substream->runtime->private_data = data;
....
}
@@ -3301,7 +3301,7 @@ You can then pass any pointer value to the ``private_data``. If you
assign private data, you should define a destructor, too. The
destructor function is set in the ``private_free`` field::
- struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
+ struct mydata *p = kmalloc_obj(*p);
hw->private_data = p;
hw->private_free = mydata_free;
@@ -3833,7 +3833,7 @@ chip data individually::
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
....
card->private_data = chip;
....
diff --git a/Documentation/spi/spi-summary.rst b/Documentation/spi/spi-summary.rst
index 6e21e6f86912..7ad6af76c247 100644
--- a/Documentation/spi/spi-summary.rst
+++ b/Documentation/spi/spi-summary.rst
@@ -249,7 +249,7 @@ And SOC-specific utility code might look something like::
{
struct mysoc_spi_data *pdata2;
- pdata2 = kmalloc(sizeof *pdata2, GFP_KERNEL);
+ pdata2 = kmalloc_obj(*pdata2);
*pdata2 = pdata;
...
if (n == 2) {
@@ -373,7 +373,7 @@ a bus (appearing under /sys/class/spi_master).
return -ENODEV;
/* get memory for driver's per-chip state */
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
+ chip = kzalloc(*chip);
if (!chip)
return -ENOMEM;
spi_set_drvdata(spi, chip);
diff --git a/Documentation/translations/it_IT/kernel-hacking/locking.rst b/Documentation/translations/it_IT/kernel-hacking/locking.rst
index 4c21cf60f775..acca89a3743a 100644
--- a/Documentation/translations/it_IT/kernel-hacking/locking.rst
+++ b/Documentation/translations/it_IT/kernel-hacking/locking.rst
@@ -462,7 +462,7 @@ e tutti gli oggetti che contiene. Ecco il codice::
{
struct object *obj;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
strscpy(obj->name, name, sizeof(obj->name));
@@ -537,7 +537,7 @@ sono quelle rimosse, mentre quelle ``+`` sono quelle aggiunte.
struct object *obj;
+ unsigned long flags;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
@@ -63,30 +64,33 @@
obj->id = id;
diff --git a/Documentation/translations/it_IT/locking/locktypes.rst b/Documentation/translations/it_IT/locking/locktypes.rst
index 1c7056283b9d..d5fa36aa05cc 100644
--- a/Documentation/translations/it_IT/locking/locktypes.rst
+++ b/Documentation/translations/it_IT/locking/locktypes.rst
@@ -488,7 +488,7 @@ o rwlock_t. Per esempio, la sezione critica non deve fare allocazioni di
memoria. Su un kernel non-PREEMPT_RT il seguente codice funziona perfettamente::
raw_spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
Ma lo stesso codice non funziona su un kernel PREEMPT_RT perché l'allocatore di
memoria può essere oggetto di prelazione e quindi non può essere chiamato in un
@@ -497,7 +497,7 @@ trattiene un blocco *non-raw* perché non disabilitano la prelazione sui kernel
PREEMPT_RT::
spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
bit spinlocks
diff --git a/Documentation/translations/it_IT/process/coding-style.rst b/Documentation/translations/it_IT/process/coding-style.rst
index c0dc786b8474..2a499412a2e3 100644
--- a/Documentation/translations/it_IT/process/coding-style.rst
+++ b/Documentation/translations/it_IT/process/coding-style.rst
@@ -943,7 +943,7 @@ Il modo preferito per passare la dimensione di una struttura è il seguente:
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
La forma alternativa, dove il nome della struttura viene scritto interamente,
peggiora la leggibilità e introduce possibili bachi quando il tipo di
diff --git a/Documentation/translations/sp_SP/process/coding-style.rst b/Documentation/translations/sp_SP/process/coding-style.rst
index 7d63aa8426e6..44c93d5f6beb 100644
--- a/Documentation/translations/sp_SP/process/coding-style.rst
+++ b/Documentation/translations/sp_SP/process/coding-style.rst
@@ -955,7 +955,7 @@ La forma preferida para pasar el tamaño de una estructura es la siguiente:
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
La forma alternativa donde se deletrea el nombre de la estructura perjudica
la legibilidad, y presenta una oportunidad para un error cuando se cambia
diff --git a/Documentation/translations/zh_CN/core-api/kref.rst b/Documentation/translations/zh_CN/core-api/kref.rst
index b9902af310c5..fcff01e99852 100644
--- a/Documentation/translations/zh_CN/core-api/kref.rst
+++ b/Documentation/translations/zh_CN/core-api/kref.rst
@@ -52,7 +52,7 @@ kref可以出现在数据结构体中的任何地方。
struct my_data *data;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
@@ -106,7 +106,7 @@ Kref规则
int rv = 0;
struct my_data *data;
struct task_struct *task;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
diff --git a/Documentation/translations/zh_CN/process/coding-style.rst b/Documentation/translations/zh_CN/process/coding-style.rst
index 5a342a024c01..55d5da974d89 100644
--- a/Documentation/translations/zh_CN/process/coding-style.rst
+++ b/Documentation/translations/zh_CN/process/coding-style.rst
@@ -813,7 +813,7 @@ Documentation/translations/zh_CN/core-api/memory-allocation.rst 。
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
另外一种传递方式中,sizeof 的操作数是结构体的名字,这样会降低可读性,并且可能
会引入 bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的 sizeof
diff --git a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
index f0be21a60a0f..ba43c5c4797c 100644
--- a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
@@ -799,7 +799,7 @@ int my_open(struct file *file)
...
- my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+ my_fh = kzalloc_obj(*my_fh);
...
diff --git a/Documentation/translations/zh_TW/process/coding-style.rst b/Documentation/translations/zh_TW/process/coding-style.rst
index e2ba97b3d8bb..63c78982a1af 100644
--- a/Documentation/translations/zh_TW/process/coding-style.rst
+++ b/Documentation/translations/zh_TW/process/coding-style.rst
@@ -827,7 +827,7 @@ Documentation/translations/zh_CN/core-api/memory-allocation.rst 。
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
另外一種傳遞方式中,sizeof 的操作數是結構體的名字,這樣會降低可讀性,並且可能
會引入 bug。有可能指針變量類型被改變時,而對應的傳遞給內存分配函數的 sizeof
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/3] Documentation: RCU: adopt new coding style of type-aware kmalloc-family
From: Manuel Ebner @ 2026-04-21 18:06 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc, rcu; +Cc: Kees Cook, Manuel Ebner
In-Reply-To: <20260421175516.224960-2-manuelebner@mailbox.org>
Update Documentation/RCU/* to reflect new type-aware kmalloc-family as
suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
ptr = kmalloc(sizeof(*ptr), gfp);
-> ptr = kmalloc_obj(*ptr);
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
---
Documentation/RCU/Design/Requirements/Requirements.rst | 6 +++---
Documentation/RCU/listRCU.rst | 2 +-
Documentation/RCU/whatisRCU.rst | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst
index b5cdbba3ec2e..faca5a9c8c12 100644
--- a/Documentation/RCU/Design/Requirements/Requirements.rst
+++ b/Documentation/RCU/Design/Requirements/Requirements.rst
@@ -206,7 +206,7 @@ non-\ ``NULL``, locklessly accessing the ``->a`` and ``->b`` fields.
1 bool add_gp_buggy(int a, int b)
2 {
- 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
+ 3 p = kmalloc_obj(*p);
4 if (!p)
5 return -ENOMEM;
6 spin_lock(&gp_lock);
@@ -228,7 +228,7 @@ their rights to reorder this code as follows:
1 bool add_gp_buggy_optimized(int a, int b)
2 {
- 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
+ 3 p = kmalloc_obj(*p);
4 if (!p)
5 return -ENOMEM;
6 spin_lock(&gp_lock);
@@ -264,7 +264,7 @@ shows an example of insertion:
1 bool add_gp(int a, int b)
2 {
- 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
+ 3 p = kmalloc_obj(*p);
4 if (!p)
5 return -ENOMEM;
6 spin_lock(&gp_lock);
diff --git a/Documentation/RCU/listRCU.rst b/Documentation/RCU/listRCU.rst
index d8bb98623c12..48c7272a4ccc 100644
--- a/Documentation/RCU/listRCU.rst
+++ b/Documentation/RCU/listRCU.rst
@@ -276,7 +276,7 @@ The RCU version of audit_upd_rule() is as follows::
list_for_each_entry(e, list, list) {
if (!audit_compare_rule(rule, &e->rule)) {
- ne = kmalloc(sizeof(*entry), GFP_ATOMIC);
+ ne = kmalloc_obj(*entry, GFP_ATOMIC);
if (ne == NULL)
return -ENOMEM;
audit_copy_rule(&ne->rule, &e->rule);
diff --git a/Documentation/RCU/whatisRCU.rst b/Documentation/RCU/whatisRCU.rst
index a1582bd653d1..770aab8ea36a 100644
--- a/Documentation/RCU/whatisRCU.rst
+++ b/Documentation/RCU/whatisRCU.rst
@@ -468,7 +468,7 @@ uses of RCU may be found in listRCU.rst and NMI-RCU.rst.
struct foo *new_fp;
struct foo *old_fp;
- new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL);
+ new_fp = kmalloc_obj(*new_fp);
spin_lock(&foo_mutex);
old_fp = rcu_dereference_protected(gbl_foo, lockdep_is_held(&foo_mutex));
*new_fp = *old_fp;
@@ -570,7 +570,7 @@ The foo_update_a() function might then be written as follows::
struct foo *new_fp;
struct foo *old_fp;
- new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL);
+ new_fp = kmalloc_obj(*new_fp);
spin_lock(&foo_mutex);
old_fp = rcu_dereference_protected(gbl_foo, lockdep_is_held(&foo_mutex));
*new_fp = *old_fp;
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/3] Documentation: deprecated.rst: kmalloc-family: mark argument as optional
From: Manuel Ebner @ 2026-04-21 18:09 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel
Cc: workflows, Manuel Ebner
In-Reply-To: <20260421175516.224960-2-manuelebner@mailbox.org>
put the optional argument (gfp) in square brackets
eg. ptr = kmalloc_obj(*ptr, gfp);
-> ptr = kmalloc_obj(*ptr, [gfp]);
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
---
Documentation/process/deprecated.rst | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index fed56864d036..b431993fd08e 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -392,12 +392,12 @@ allocations. For example, these open coded assignments::
become, respectively::
- ptr = kmalloc_obj(*ptr, gfp);
- ptr = kzalloc_obj(*ptr, gfp);
- ptr = kmalloc_objs(*ptr, count, gfp);
- ptr = kzalloc_objs(*ptr, count, gfp);
- ptr = kmalloc_flex(*ptr, flex_member, count, gfp);
- __auto_type ptr = kmalloc_obj(struct foo, gfp);
+ ptr = kmalloc_obj(*ptr, [gfp]);
+ ptr = kzalloc_obj(*ptr, [gfp]);
+ ptr = kmalloc_objs(*ptr, count, [gfp]);
+ ptr = kzalloc_objs(*ptr, count, [gfp]);
+ ptr = kmalloc_flex(*ptr, flex_member, count, [gfp]);
+ __auto_type ptr = kmalloc_obj(struct foo, [gfp]);
If `ptr->flex_member` is annotated with __counted_by(), the allocation
will automatically fail if `count` is larger than the maximum
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2 00/16] fs,x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem
From: Babu Moger @ 2026-04-21 18:19 UTC (permalink / raw)
To: Reinette Chatre, Moger, Babu, corbet@lwn.net, tony.luck@intel.com,
Dave.Martin@arm.com, james.morse@arm.com, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com
Cc: skhan@linuxfoundation.org, x86@kernel.org, hpa@zytor.com,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kas@kernel.org, rick.p.edgecombe@intel.com,
akpm@linux-foundation.org, pmladek@suse.com,
rdunlap@infradead.org, dapeng1.mi@linux.intel.com,
kees@kernel.org, elver@google.com, paulmck@kernel.org,
lirongqing@baidu.com, safinaskar@gmail.com, fvdl@google.com,
seanjc@google.com, pawan.kumar.gupta@linux.intel.com,
xin@zytor.com, tiala@microsoft.com, chang.seok.bae@intel.com,
Lendacky, Thomas, elena.reshetova@intel.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-coco@lists.linux.dev, kvm@vger.kernel.org,
eranian@google.com, peternewman@google.com
In-Reply-To: <0334ba64-71b3-40bd-8cce-9f0f119e7dc9@intel.com>
Hi Reinette,
On 4/21/26 12:35, Reinette Chatre wrote:
> Hi Babu,
>
> On 4/21/26 9:46 AM, Babu Moger wrote:
>> On 4/21/26 11:15, Reinette Chatre wrote:
>>> On 4/21/26 8:08 AM, Babu Moger wrote:
>
>>> It sounds like we are saying the same thing?
>>> When considering all the sharp corners I agree that keeping kernel_mode_cpus/kernel_mode_cpuslist
>>> seems most user friendly. When doing so there is no need to include CPU assignment in the global
>>> files.
>>
>> Actually, I was talking about removing _per_cpu extension also as the per-CPU requirement is handled inside the group using kernel_mode_cpus/kernel_mode_cpuslist. It can be documented.
>>
>> global_assign_ctrl_assign_mon_per_cpu -> global_assign_ctrl_assign_mon
>> global_assign_ctrl_inherit_mon_per_cpu -> global_assign_ctrl_inherit_mon
>
> I see. The goal with this name choice was to distinguish a global mode that
> additionally supports per-CPU assignment from a "true/pure" global mode that
> does not support per-CPU assignment.
>
> If resctrl ever needs to support such "true/pure" global mode that does
> not support per-CPU assignment then resctrl will need to either come up with
> a new mode that does not expose kernel_mode_cpus/kernel_mode_cpuslist or
> make kernel_mode_cpus/kernel_mode_cpuslist read-only. The latter adds the
> complication that user space can always change the mode of a file so resctrl
> would need to add corner cases for that.
>
> To me the "per_cpu" distinction is useful since it make it clear to user space
> that even though this is a "global" configuration it additionally supports
> per-CPU assignment for which user space can expect kernel_mode_cpus/kernel_mode_cpuslist
> to exist and be writable. To me this makes the interface clear and intuitive.
ok. Sure.
>
>>>>
>>>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/
>>>>
>>>> Why do we still need to keep the "inherit_ctrl_and_mon"? By default all the groups in the system falls in this category it is not plza enabled group.
>>>>
>>>>
>>>> System boots up with following options if PLZA is supported.
>>>>
>>>> # cat info/kernel_mode
>>>> global_assign_ctrl_assign_mon_per_cpu
>>>> global_assign_ctrl_inherit_mon_per_cpu
>>>>
>>>> No groups are associated with kernel mode at this point.
>>>
>>> To me it seems useful to be clear to user space on what the current mode is. If I understand correctly
>>> above default scenario essentially means "inherit_ctrl_and_mon" but instead of adding it to this file
>>> we will need to add documentation that describes to user space how this file should be interpreted.
>>> It seems easier to me to just be clear via info/kernel_mode itself on what the current active mode is?
>>>
>>> I think something like below will be more intuitive and not need much additional
>>> documentation to understand (I am just adding the "uninitialized" as an example to match text
>>> printed in schemata file during pseudo-locking ... even if there is a group named "uninitialized"
>>> the lack of "/" could be used to make it clear what this means?):
>>>
>>> # cat info/kernel_mode
>>> [inherit_ctrl_and_mon]
>>> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
>>> global_assign_ctrl_inherit_mon_per_cpu:group=uninitialized
>>>
>>
>> Sounds ok to me.
>>
>>
>>> I also think an interface like this would be simpler for user space to use as it (user space) switches
>>> between PLZA capable and non-PLZA capable systems since user space need not associate existence of
>>> the file with some kernel mode state in addition to actual content of the file when it does exist.
>>>
>>> I assumed that info/kernel_mode can just always be made visible and not depend on PLZA
>>> capable hardware. This means that on Intel and Arm this file can show:
>>>
>>> # cat info/kernel_mode
>>> [inherit_ctrl_and_mon]
>>>
>>
>> Yes. Sure.
>>
>>
>>> For Intel this is accurate and also for Arm if I interpret the Arm implementation correctly
>>> (see mpam_thread_switch()) in https://lore.kernel.org/lkml/20260313144617.3420416-7-ben.horgan@arm.com/
>>>
>>>>
>>>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/" > info/kernel_mode
>>>>
>>>> # cat info/kernel_mode
>>>> global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/
>>>> global_assign_ctrl_inherit_mon_per_cpu
>>>>
>>>>
>>>> # echo "global_assign_ctrl_inherit_mon_per_cpu:group=//" > info/kernel_mode
>>>>
>>>>
>>>> # cat info/kernel_mode
>>>> global_assign_ctrl_assign_mon_per_cpu
>>>> global_assign_ctrl_inherit_mon_per_cpu:group=//
>>>>
>>>>
>>>> How does this look?
>>>
>>> In addition to above I think it will be helpful to add a clear indication to user
>>> space on what the current active mode is, for example, via the [] characters.
>>
>> # echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/" > info/kernel_mode
>>
>> # cat info/kernel_mode
>> inherit_ctrl_and_mon
>> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
>> [global_assign_ctrl_assign_mon_per_cpu]:group=ctrl1/mon1/
>>
>> Something like this?
>
> How about making it clear that the whole line/configuration is active, like below:
>
> # cat info/kernel_mode
> inherit_ctrl_and_mon
> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized
> [global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/]
>
>
ok. Sure.
>>
>> There is one problem here. The mode "inherit_ctrl_and_mon" listing not consistent with others.
>
> It is difficult to predict what resctrl will be asked to support next. One possibility here is
> to make it part of the original design that the first field is the "mode" and the following field
> contains that mode's global properties of which there could be more than one. Above shows that
> the two "global" modes have a single global property but we could just try to be safe with some
> documentation that states there could be more.
>
> Consider for example some hypothetical future where the file looks like:
>
> # cat info/kernel_mode
> inherit_ctrl_and_mon:some_unique_capability=true
> global_assign_ctrl_assign_mon_per_cpu:group=uninitialized;other_property=val
> [global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/]
>
> To leave room for growth the file could start out by, for example, appending ":"
> to "inherit_ctrl_and_mon" to indicate that there are no known properties yet? Something like
> below. Would this be more consistent with the others?
To me, it might be clearer to simply document what the default mode is
when kernel mode is not enabled, and omit "inherit_ctrl_and_mon" from
the display.
That said, I’m fine with either approach.
Thanks
Babu
^ permalink raw reply
* Re: [PATCH v2 2/3] Documentation: RCU: adopt new coding style of type-aware kmalloc-family
From: Paul E. McKenney @ 2026-04-21 18:41 UTC (permalink / raw)
To: Manuel Ebner; +Cc: Jonathan Corbet, Shuah Khan, linux-doc, rcu, Kees Cook
In-Reply-To: <20260421180652.225394-2-manuelebner@mailbox.org>
On Tue, Apr 21, 2026 at 08:06:53PM +0200, Manuel Ebner wrote:
> Update Documentation/RCU/* to reflect new type-aware kmalloc-family as
> suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
>
> ptr = kmalloc(sizeof(*ptr), gfp);
> -> ptr = kmalloc_obj(*ptr);
>
> Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
> ---
> Documentation/RCU/Design/Requirements/Requirements.rst | 6 +++---
> Documentation/RCU/listRCU.rst | 2 +-
> Documentation/RCU/whatisRCU.rst | 4 ++--
> 3 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst
> index b5cdbba3ec2e..faca5a9c8c12 100644
> --- a/Documentation/RCU/Design/Requirements/Requirements.rst
> +++ b/Documentation/RCU/Design/Requirements/Requirements.rst
> @@ -206,7 +206,7 @@ non-\ ``NULL``, locklessly accessing the ``->a`` and ``->b`` fields.
>
> 1 bool add_gp_buggy(int a, int b)
> 2 {
> - 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
> + 3 p = kmalloc_obj(*p);
> 4 if (!p)
> 5 return -ENOMEM;
> 6 spin_lock(&gp_lock);
> @@ -228,7 +228,7 @@ their rights to reorder this code as follows:
>
> 1 bool add_gp_buggy_optimized(int a, int b)
> 2 {
> - 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
> + 3 p = kmalloc_obj(*p);
> 4 if (!p)
> 5 return -ENOMEM;
> 6 spin_lock(&gp_lock);
> @@ -264,7 +264,7 @@ shows an example of insertion:
>
> 1 bool add_gp(int a, int b)
> 2 {
> - 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
> + 3 p = kmalloc_obj(*p);
> 4 if (!p)
> 5 return -ENOMEM;
> 6 spin_lock(&gp_lock);
> diff --git a/Documentation/RCU/listRCU.rst b/Documentation/RCU/listRCU.rst
> index d8bb98623c12..48c7272a4ccc 100644
> --- a/Documentation/RCU/listRCU.rst
> +++ b/Documentation/RCU/listRCU.rst
> @@ -276,7 +276,7 @@ The RCU version of audit_upd_rule() is as follows::
>
> list_for_each_entry(e, list, list) {
> if (!audit_compare_rule(rule, &e->rule)) {
> - ne = kmalloc(sizeof(*entry), GFP_ATOMIC);
> + ne = kmalloc_obj(*entry, GFP_ATOMIC);
> if (ne == NULL)
> return -ENOMEM;
> audit_copy_rule(&ne->rule, &e->rule);
> diff --git a/Documentation/RCU/whatisRCU.rst b/Documentation/RCU/whatisRCU.rst
> index a1582bd653d1..770aab8ea36a 100644
> --- a/Documentation/RCU/whatisRCU.rst
> +++ b/Documentation/RCU/whatisRCU.rst
> @@ -468,7 +468,7 @@ uses of RCU may be found in listRCU.rst and NMI-RCU.rst.
> struct foo *new_fp;
> struct foo *old_fp;
>
> - new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL);
> + new_fp = kmalloc_obj(*new_fp);
> spin_lock(&foo_mutex);
> old_fp = rcu_dereference_protected(gbl_foo, lockdep_is_held(&foo_mutex));
> *new_fp = *old_fp;
> @@ -570,7 +570,7 @@ The foo_update_a() function might then be written as follows::
> struct foo *new_fp;
> struct foo *old_fp;
>
> - new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL);
> + new_fp = kmalloc_obj(*new_fp);
> spin_lock(&foo_mutex);
> old_fp = rcu_dereference_protected(gbl_foo, lockdep_is_held(&foo_mutex));
> *new_fp = *old_fp;
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH 18/23] cpu/hotplug: Add a new cpuhp_offline_cb() API
From: Thomas Gleixner @ 2026-04-21 18:43 UTC (permalink / raw)
To: Waiman Long, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <4a0ede3e-6e87-414f-a3a3-dd15c32f25ef@redhat.com>
On Tue, Apr 21 2026 at 13:29, Waiman Long wrote:
> On 4/21/26 12:17 PM, Thomas Gleixner wrote:
> Thanks for the great suggestions. I will certainly look into that.
>
> We actually have a cpu_active_mask that will be cleared early in
> sched_cpu_deactivate(). In the CPUHP_AP_SCHED_WAIT_EMPTY state, the CPU
> will still have online bit set but the active bit will be cleared. Or we
> could add another cpumask that can be used to indicate CPUs that have
> reached CPUHP_AP_SCHED_WAIT_EMPTY or below if necessary.
Right. Active mask is immediately cleared when a CPU goes down so that
the scheduler does not enqueue new tasks on it. But you can't use it for
interrupts because on CPU up the mask must be up to date when
irq_affinity_online_cpu() is invoked. The tick has the same constraints.
So for interrupts this should be handled in CPUHP_AP_IRQ_AFFINITY_ONLINE
both in the existing up and the new down callback. That can be a
interrupt core local CPU mask which is updated on the callbacks with the
sparse_irq_lock held.
Same for the tick handover magic.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v3 07/24] vfio/pci: Preserve vfio-pci device files across Live Update
From: Jason Gunthorpe @ 2026-04-21 18:44 UTC (permalink / raw)
To: David Matlack
Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jonathan Corbet,
Josh Hilke, Kees Cook, Kevin Tian, kexec, kvm, Leon Romanovsky,
Leon Romanovsky, linux-doc, linux-kernel, linux-kselftest,
linux-mm, linux-pci, Li RongQing, Lukas Wunner, Marco Elver,
Michał Winiarski, Mike Rapoport, Parav Pandit,
Pasha Tatashin, Paul E. McKenney, Pawan Gupta,
Peter Zijlstra (Intel), Pranjal Shrivastava, Pratyush Yadav,
Raghavendra Rao Ananta, Randy Dunlap, Rodrigo Vivi,
Saeed Mahameed, Samiullah Khawaja, Shuah Khan, Vipin Sharma,
Vivek Kasireddy, William Tu, Yi Liu, Zhu Yanjun
In-Reply-To: <CALzav=ehpWA=XchL+XLZuaYfYmBTPNWDYt1W3LFY5-6+US4E7w@mail.gmail.com>
On Tue, Apr 21, 2026 at 10:40:29AM -0700, David Matlack wrote:
> On Mon, Mar 23, 2026 at 4:58 PM David Matlack <dmatlack@google.com> wrote:
>
> > +static int vfio_pci_liveupdate_freeze(struct liveupdate_file_op_args *args)
> > +{
> > + struct vfio_device *device = vfio_device_from_file(args->file);
> > + struct vfio_pci_core_device *vdev;
> > + struct pci_dev *pdev;
> > + int ret;
> > +
> > + vdev = container_of(device, struct vfio_pci_core_device, vdev);
> > + pdev = vdev->pdev;
> > +
> > + guard(mutex)(&device->dev_set->lock);
> > +
> > + /*
> > + * Userspace must disable interrupts on the device prior to freeze so
> > + * that the device does not send any interrupts until new interrupt
> > + * handlers have been established by the next kernel.
> > + */
> > + if (vdev->irq_type != VFIO_PCI_NUM_IRQS) {
> > + pci_err(pdev, "Freeze failed! Interrupts are still enabled.\n");
> > + return -EINVAL;
> > + }
> > +
> > + ret = pci_load_saved_state(pdev, vdev->pci_saved_state);
> > + if (ret)
> > + return ret;
> > +
> > + vfio_pci_core_try_reset(vdev);
>
> I think a call to pci_clear_master() is needed here to so the device
> stops issuing memory transactions while VFIO is trying to resetting
> it.
That doesn't sound right, reset should always work..
Didn't look beyond this hunk but why is a function called 'freeze'
donig a reset anyhow?
> Sashiko also wondered if pci_clear_master() is needed to ensure that
> the device has bus mastering disabled during the kexec
Only devices that are not being preserved..
> think that is actually an issue. vfio_pci_core_enable() makes sure
> that vdev->pci_saved_state has bus mastering disabled, so
> pci_restore_state() below here should guaranteed it is clear during
> kexec.
.. and bus mastering should not be disabled on any device expecting to
be preserved ..
Jason
^ permalink raw reply
* Re: [PATCH V10 00/10] famfs: port into fuse
From: Joanne Koong @ 2026-04-21 18:59 UTC (permalink / raw)
To: Gregory Price
Cc: John Groves, David Hildenbrand (Arm), Darrick J. Wong,
Miklos Szeredi, Bernd Schubert, John Groves, Dan Williams,
Bernd Schubert, Alison Schofield, John Groves, Jonathan Corbet,
Shuah Khan, Vishal Verma, Dave Jiang, Matthew Wilcox, Jan Kara,
Alexander Viro, Christian Brauner, Randy Dunlap, Jeff Layton,
Amir Goldstein, Jonathan Cameron, Stefan Hajnoczi, Josef Bacik,
Bagas Sanjaya, Chen Linxuan, James Morse, Fuad Tabba,
Sean Christopherson, Shivank Garg, Ackerley Tng, Aravind Ramesh,
Ajay Joshi, venkataravis@micron.com, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, nvdimm@lists.linux.dev,
linux-cxl@vger.kernel.org, linux-fsdevel@vger.kernel.org, djbw
In-Reply-To: <aeeJ8Lgg2z0X-NC_@gourry-fedora-PF4VCD3F>
On Tue, Apr 21, 2026 at 7:30 AM Gregory Price <gourry@gourry.net> wrote:
>
> On Mon, Apr 20, 2026 at 08:12:17PM -0700, Joanne Koong wrote:
> > On Sun, Apr 19, 2026 at 5:27 PM Gregory Price <gourry@gourry.net> wrote:
> > >
> > > struct fuse_dax_fmap_ops {
> > > char name[FUSE_DAX_FMAP_OPS_NAME_LEN]; // 16 bytes
> > > int (*dax_fmap_parse)(struct fuse_dax_fmap_parse_ctx *ctx);
> >
> > Just a note for later, if the bpf approach gets pursued further:
> > instead of making this a dax specific ops, I think this needs to be
> > integrated interface-wise with Darrick's fuse-iomap work since he does
> > the same thing. I think dax_fmap_parse() could be renamed to something
> > like iomap_setup(), where userspace can use this to do any sort of
> > generic setup, whether that's mapping related or dax related or not.
> > In my mind, the dax vs non dax distinction is handled by the fuse
> > iomap plumbing that chooses which iomap entry points to call, but
> > beyond that, the callbacks and struct ops themselves should be
> > generic enough to be shared between the two.
> >
>
> I think this is reasonable. I'm not a FUSE wizard either, but I would
> presume the iomap_setup() process would just essentially be John's
> existing GET_FMAP / GET_DAXDEV code bundled.
>
> GET_DAXDEV happens lazily to save him the round-trips to userland if the
> DAXDEVs have already been seen previously. I think your proposal does
> in fact save him further round trips, and it would probably solve the
> performance impact he saw from porting to FUSE.
>
> > > And otherwise, imap_begin() works exactly as Joanne proposed, but with
> > > in-kernel cached data instead of the bpfmap.
> > >
> > > const struct dax_simple_meta *meta = (const struct dax_simple_meta *)
> > > bpf_fuse_dax_resolve_get_meta(ctx, 0, sizeof(*meta));
> >
> > another note for later, if the benchmarks prove promising and after
> > the LSF discussions we decide to go with this approach: imo we
> > could/should repurpose this into a generic
> > bpf_fuse_iomap_get_inode_meta() that returns a bounded pointer into
> > whatever opaque blob was cached on the inode during iomap_setup(),
> > where it'd be a generic kfunc serving both the dax and non-dax case
> > for any kind of mapping layout
> >
>
> Note that Christian Brauner just said he preferred not having dedicated
> bpf storage in struct inode [1].
>
> sans BPF, is there value in such a metadata blob existing?
>
> If there was a generic format, then I suppose the blob storage would not
> be BPF specific, it would just overload it (simple union).
I'm not sure if this addresses Christian's concerns or not, but the
blob would reside within struct fuse_inode not struct inode. I
definitely agree with him that this should not touch or add any infra
outside fuse.
I hadn't heard of bpf arenas until his comment. If the hashmap
overhead is too high for famfs, having a custom in-arena hash table
would be much faster I think, as it could be designed to require less
pointer chasing and avoid other overhead in the bpf hashmap
implementation, though now famfs would have to manage the data
structure and complexity itself.
Thanks,
Joanne
>
> [1] https://lore.kernel.org/linux-fsdevel/20260421-arsch-gelernt-e0b5bcd8a7ff@brauner/T/#m8fea90f5ed4a1b23bdc2563d978948b263b2030b
>
> ~Gregory
^ 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