* Re: [PATCH] riscv: Docs: fix unmatched quote warning
From: Randy Dunlap @ 2026-05-05 19:58 UTC (permalink / raw)
To: linux-kernel
Cc: Deepak Gupta, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, linux-riscv, Jonathan Corbet, Shuah Khan,
linux-doc
In-Reply-To: <20260406232304.1892528-1-rdunlap@infradead.org>
ping?
On 4/6/26 4:23 PM, Randy Dunlap wrote:
> 'make htmldocs' complains about ``prctrl` -- so add a second '`' to
> avoid the warning.
>
> Documentation/arch/riscv/zicfilp.rst:79: WARNING: Inline literal start-string without end-string. [docutils]
>
> Fixes: 08ee1559052b ("prctl: cfi: change the branch landing pad prctl()s to be more descriptive")
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
> ---
> Cc: Deepak Gupta <debug@rivosinc.com>
> Cc: Paul Walmsley <pjw@kernel.org>
> Cc: Palmer Dabbelt <palmer@dabbelt.com>
> Cc: Albert Ou <aou@eecs.berkeley.edu>
> Cc: Alexandre Ghiti <alex@ghiti.fr>
> Cc: linux-riscv@lists.infradead.org
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Shuah Khan <skhan@linuxfoundation.org>
> Cc: linux-doc@vger.kernel.org
>
> Documentation/arch/riscv/zicfilp.rst | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> --- linux-next-20260406.orig/Documentation/arch/riscv/zicfilp.rst
> +++ linux-next-20260406/Documentation/arch/riscv/zicfilp.rst
> @@ -78,7 +78,7 @@ the program.
>
> Per-task indirect branch tracking state can be monitored and
> controlled via the :c:macro:`PR_GET_CFI` and :c:macro:`PR_SET_CFI`
> -``prctl()` arguments (respectively), by supplying
> +``prctl()`` arguments (respectively), by supplying
> :c:macro:`PR_CFI_BRANCH_LANDING_PADS` as the second argument. These
> are architecture-agnostic, and will return -EINVAL if the underlying
> functionality is not supported.
>
--
~Randy
^ permalink raw reply
* Re: [PATCH v2 04/11] docs: maintainers_include: clean most SPHINXDIRS=process warnings
From: Randy Dunlap @ 2026-05-05 19:53 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Jonathan Corbet, Linux Doc Mailing List,
Mauro Carvalho Chehab
Cc: linux-kernel, rust-for-linux, Shuah Khan
In-Reply-To: <b57d83081c28aa52683b403f8836d098fcdd8530.1777987027.git.mchehab+huawei@kernel.org>
On 5/5/26 6:25 AM, Mauro Carvalho Chehab wrote:
> building docs with SPHINXDIRS=process is too noisy, as it
> generates lots of undefined refs. Fixing it is easy: just let
> linkify generate html URLs for the broken links when SPHINXDIRS
> is used.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Is this specific to SPHINXDIRS=process?
I don't see anything here checking for "process".
If this is process-specific, why?
Or is it just for SPHINXDIRS="<subdir(s)>"?
> ---
> Documentation/sphinx/maintainers_include.py | 44 +++++++++++++++------
> 1 file changed, 32 insertions(+), 12 deletions(-)
--
~Randy
^ permalink raw reply
* [PATCH] docs: pt_BR: update minimal software requirements in changes.rst
From: Daniel Pereira @ 2026-05-05 19:41 UTC (permalink / raw)
To: Jonathan Corbet; +Cc: linux-doc, Daniel Pereira
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 9439 bytes --]
Update the Brazilian Portuguese translation of changes.rst to align with
the latest English version.
Key changes include:
- Updated minimum versions for Rust (1.85.0), bindgen (0.71.1), and
pahole (1.22).
- Fixed ReST syntax for internal references (:ref:) and external links.
- Corrected formatting for tool names and config options using inline
code backticks.
- Synchronized technical descriptions for udev, kmod, and NFS-utils.
Signed-off-by: Daniel Pereira <danielmaraboo@gmail.com>
---
.../translations/pt_BR/process/changes.rst | 52 +++++++++----------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/Documentation/translations/pt_BR/process/changes.rst b/Documentation/translations/pt_BR/process/changes.rst
index 1964c1c93..642927bba 100644
--- a/Documentation/translations/pt_BR/process/changes.rst
+++ b/Documentation/translations/pt_BR/process/changes.rst
@@ -20,7 +20,8 @@ Requisitos Mínimos Atuais
Atualize para pelo menos estas revisões de software antes de pensar que
encontrou um bug! Se não tiver certeza de qual versão está executando atualmente
-, o comando sugerido deve lhe informar.
+, o comando sugerido deve lhe informar. Para uma lista dos programas em seu
+sistema, incluindo as versões, execute ./scripts/ver_linux.
Novamente, tenha em mente que esta lista pressupõe que você já possui um kernel
Linux em execução funcional. Além disso, nem todas as ferramentas são
@@ -32,16 +33,17 @@ PC Card por exemplo, provavelmente não precisará se preocupar com o pcmciautil
====================== =============== ========================================
GNU C 8.1 gcc --version
Clang/LLVM (optional) 15.0.0 clang --version
-Rust (optional) 1.78.0 rustc --version
-bindgen (optional) 0.65.1 bindgen --version
+Rust (optional) 1.85.0 rustc --version
+bindgen (optional) 0.71.1 bindgen --version
GNU make 4.0 make --version
bash 4.2 bash --version
binutils 2.30 ld -v
flex 2.5.35 flex --version
+gdb 7.2 gdb --version
bison 2.0 bison --version
-pahole 1.16 pahole --version
+pahole 1.22 pahole --version
util-linux 2.10o mount --version
-kmod 13 depmod -V
+kmod 13 kmod -V
e2fsprogs 1.41.4 e2fsck -V
jfsutils 1.1.3 fsck.jfs -V
xfsprogs 2.6.0 xfs_db -V
@@ -52,7 +54,7 @@ quota-tools 3.09 quota -V
PPP 2.4.0 pppd --version
nfs-utils 1.0.5 showmount --version
procps 3.2.0 ps --version
-udev 081 udevd --version
+udev 081 udevadm --version
grub 0.93 grub --version || grub-install --version
mcelog 0.6 mcelog --version
iptables 1.4.2 iptables -V
@@ -81,11 +83,11 @@ Clang/LLVM (opcional)
---------------------
A versão formal mais recente do clang e dos utilitários LLVM (de acordo com
-releases.llvm.org <https://releases.llvm.org>_) é suportada para a compilação
+`releases.llvm.org <https://releases.llvm.org>`_) é suportada para a compilação
de kernels. Versões anteriores não têm funcionamento garantido, e poderemos
remover do kernel soluções de contorno (workarounds) que eram utilizadas para
-suportar versões mais antigas. Por favor, veja a documentação adicional em:
-ref:Building Linux with Clang/LLVM <kbuild_llvm>.
+suportar versões mais antigas. Por favor, veja a documentação adicional em
+:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
Rust (opcional)
---------------
@@ -124,7 +126,7 @@ pkg-config
O sistema de compilação, a partir da versão 4.18, requer o pkg-config para
verificar as ferramentas kconfig instaladas e para determinar as configurações
-de flags para uso em make {g,x}config. Anteriormente, o pkg-config já era
+de flags para uso em 'make {g,x}config'. Anteriormente, o pkg-config já era
utilizado, mas não era verificado nem documentado.
Flex
@@ -145,7 +147,7 @@ pahole
Desde o Linux 5.2, se CONFIG_DEBUG_INFO_BTF estiver selecionado, o sistema de
compilação gera BTF (BPF Type Format) a partir do DWARF no vmlinux, e um pouco
-depois para os módulos do kernel também. Isso requer o pahole v1.16 ou superior.
+depois para os módulos do kernel também. Isso requer o pahole v1.22 ou superior.
Ele pode ser encontrado nos pacotes ``dwarves`` ou ``pahole`` das
distribuições, ou em https://fedorapeople.org/~acme/dwarves/.
@@ -153,8 +155,8 @@ distribuições, ou em https://fedorapeople.org/~acme/dwarves/.
Perl
----
-Você precisará do perl 5 e dos seguintes módulos: Getopt::Long,
-Getopt::Std, File::Basename e File::Find para compilar o kernel.
+Você precisará do perl 5 e dos seguintes módulos: ``Getopt::Long``,
+``Getopt::Std``, ``File::Basename`` e ``File::Find`` para compilar o kernel.
Python
------
@@ -191,14 +193,14 @@ gtags / GNU GLOBAL (optional)
-----------------------------
A compilação do kernel requer o GNU GLOBAL versão 6.6.5 ou superior para gerar
-arquivos de tags através de make gtags. Isso se deve ao uso da flag -C
-(--directory) pelo gtags.
+arquivos de tags através de make gtags. Isso se deve ao uso da flag ``-C
+(--directory)`` pelo ``gtags``.
mkimage
-------
Esta ferramenta é utilizada ao gerar uma Flat Image Tree (FIT), comumente usada
-em plataformas ARM. A ferramenta está disponível através do pacote u-boot-tools
+em plataformas ARM. A ferramenta está disponível através do pacote ``u-boot-tools``
ou pode ser compilada a partir do código-fonte do U-Boot. Veja as instruções em
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
@@ -225,13 +227,13 @@ A documentação das funções do Linux está migrando para a documentação emb
definições no código-fonte. Esses comentários podem ser combinados com arquivos
ReST no diretório Documentation/ para criar uma documentação enriquecida, que
pode então ser convertida para arquivos PostScript, HTML, LaTeX, ePUB e PDF.
-Para converter do formato ReST para o formato de sua escolha,você precisará do
+Para converter do formato ReST para o formato de sua escolha, você precisará do
Sphinx.
Util-linux
----------
-Novas versões do util-linux oferecem suporte no fdisk para discos maiores,
+Novas versões do util-linux oferecem suporte no ``fdisk`` para discos maiores,
suporte a novas opções para o mount, reconhecimento de mais tipos de partição e
outras funcionalidades interessantes. Você provavelmente vai querer atualizar.
@@ -240,23 +242,23 @@ Ksymoops
Se o impensável acontecer e o seu kernel sofrer um oops, você pode precisar da
ferramenta ksymoops para decodificá-lo, mas na maioria dos casos, não será
-necessário. É geralmente preferível compilar o kernel com CONFIG_KALLSYMS para
+necessário. É geralmente preferível compilar o kernel com ``CONFIG_KALLSYMS`` para
que ele produza dumps legíveis que possam ser usados no estado em que se
encontram (isso também gera uma saída melhor do que a do ksymoops).
-Se por algum motivo o seu kernel não for compilado com CONFIG_KALLSYMS e você
+Se por algum motivo o seu kernel não for compilado com ``CONFIG_KALLSYMS`` e você
não tiver como recompilar e reproduzir o oops com essa opção, você ainda poderá
decodificá-lo com o ksymoops.
Mkinitrd
--------
-Estas mudanças no layout da árvore de arquivos /lib/modules também exigem que o
+Estas mudanças no layout da árvore de arquivos ``/lib/modules`` também exigem que o
mkinitrd seja atualizado.
E2fsprogs
---------
-A versão mais recente do e2fsprogs corrige diversos bugs no fsck e no debugfs.
+A versão mais recente do ``e2fsprogs`` corrige diversos bugs no fsck e no debugfs.
Obviamente, é uma boa ideia atualizar.
JFSutils
@@ -270,8 +272,6 @@ utilitários estão disponíveis:
- ``mkfs.jfs`` - cria uma partição formatada em JFS.
-- Para o seu arquivo changes.rst, a tradução técnica adequada é:
-
Outros utilitários de sistema de arquivos também estão disponíveis neste pacote.
Xfsprogs
@@ -309,7 +309,7 @@ usando o udev, você poderá precisar de::
mknod /dev/cpu/microcode c 10 184
chmod 0644 /dev/cpu/microcode
-Se você não estiver usando o udev, você poderá precisar executar os comandos
+você poderá precisar executar os comandos
acima como root antes de poder usar isso. Você provavelmente também desejará
obter o utilitário de espaço de usuário ``microcode_ctl`` para utilizar em
conjunto com este driver.
@@ -318,7 +318,7 @@ udev
----
O udev é uma aplicação de espaço de usuário para popular o diretório /dev
-dinamicamente, apenas com entradas para dispositivos de fat presentes no
+dinamicamente, apenas com entradas para dispositivos de fato presentes no
sistema. O udev substitui a funcionalidade básica do devfs, permitindo ao mesmo
tempo a nomeação persistente de dispositivos.
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v9 00/22] Enable FRED with KVM VMX
From: H. Peter Anvin @ 2026-05-05 19:29 UTC (permalink / raw)
To: Andrew Cooper, Maciej Wieczor-Retman, Xin Li
Cc: David Woodhouse, linux-kernel, kvm, linux-doc,
Saenz Julienne, Nicolas, pbonzini, seanjc, corbet, tglx, mingo,
bp, dave.hansen, x86, luto, peterz, chao.gao, hch, sohil.mehta
In-Reply-To: <f4cb5f8e-caf5-4513-9538-edaaea20de2d@citrix.com>
On May 5, 2026 11:30:21 AM PDT, Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>On 05/05/2026 7:04 pm, Maciej Wieczor-Retman wrote:
>> Hello!
>>
>>
>> On 2026-04-23 at 15:56:54 -0700, Xin Li wrote:
>>>> On Apr 23, 2026, at 7:35 AM, David Woodhouse <dwmw2@infradead.org> wrote:
>>>> Here's one to get you started (untested as I haven't found suitable
>>>> hardware to test it on).
>>> Same here for me now :(
>> I ran David's selftest on a PTL laptop and ran into a couple of issues.
>>
>>>> From bd465aabebcb124e09a26fe9f4c861354febabe4 Mon Sep 17 00:00:00 2001
>>>> From: David Woodhouse <dwmw@amazon.co.uk>
>>>> Date: Thu, 23 Apr 2026 15:20:11 +0100
>>>> Subject: [PATCH] KVM: selftests: Add FRED event type classification test
>>>>
>>>> +static void __used fred_handler(struct fred_stack_frame *frame)
>>>> +{
>>>> + fred_ss_value = frame->ss;
>>>> + fred_saved_rip = frame->rip;
>>>> + fred_handler_called = true;
>>>> +}
>> fred_handler() has problems getting linked:
>>
>> /usr/bin/ld: /home/maciej/linux/tools/testing/selftests/kvm/x86/int1_fred_test.o: in function `fred_entrypoint_kernel':
>> int1_fred_test.c:(.text+0x104): undefined reference to `fred_handler'
>> collect2: error: ld returned 1 exit status
>>
>> I guess the .pushsection below makes it a different translation unit? Because
>> getting rid of the static keyword takes care of the problem for me.
>
>The problem is, being static, fred_handler() is eligible to be optimised
>away, because the compiler can't see that the asm() refers to it.
>
>Dropping static is the right fix to make.
>
>GCC 15 can now do references out of global asm() to identify the symbols
>they use, but it's going to be years before this capability is safe to
>use generally.
>
>>
>>>> +
>>>> +/*
>>>> + * FRED entry points. MSR_IA32_FRED_CONFIG points to the page-aligned
>>>> + * base. Ring 3 events enter at base+0, ring 0 events at base+0x100.
>>>> + * Since ICEBP executes in ring 0, the CPU enters at fred_entrypoint
>>>> + * + 256 = fred_entrypoint_kernel.
>>>> + */
>>>> +extern void fred_entrypoint(void);
>>>> +
>>>> +asm(
>>>> + ".pushsection .text\n"
>>>> + ".global fred_entrypoint\n"
>>>> + ".balign 4096\n"
>>>> +"fred_entrypoint:\n"
>>>> + /* Ring 3 entry — unused, no userspace in this test */
>>>> + "ud2\n"
>>>> + /* Pad to +256 for ring 0 entry */
>>>> + ".org fred_entrypoint + 256, 0xcc\n"
>>>> +"fred_entrypoint_kernel:\n"
>>>> + "movq %rsp, %rdi\n"
>>>> + "call fred_handler\n"
>>>> + ".byte 0xf2, 0x0f, 0x01, 0xca\n" /* ERETS */
>>>> + ".popsection\n"
>>>> +);
>>>> +
>> ...
>>>> +
>>>> + /* Test 1: ICEBP (INT1) — should be EVENT_TYPE_PRIV_SWEXC (5) */
>>>> + fred_handler_called = false;
>>>> + asm volatile("lea 1f(%%rip), %0\n\t"
>>>> + ".byte 0xf1\n\t"
>>>> + "1:" : "=r"(expected_rip) :: "memory");
>>>> + check_fred_event(expected_rip, DB_VECTOR, EVENT_TYPE_PRIV_SWEXC,
>>>> + "ICEBP");
>>>> + GUEST_SYNC(0);
>> The above event type test seems to fail and return 0x3 instead of 0x5:
>>
>> Random seed: 0x6b8b4567
>> Testing FRED event types with EPT fault on stack
>> ==== Test Assertion Failure ====
>> x86/int1_fred_test.c:120: event_type == expected_type
>> pid=16646 tid=16646 errno=4 - Interrupted system call
>> 1 0x0000000000413349: assert_on_unhandled_exception at processor.c:659
>> 2 0x0000000000407d36: _vcpu_run at kvm_util.c:1703
>> 3 (inlined by) vcpu_run at kvm_util.c:1714
>> 4 0x0000000000403104: main at int1_fred_test.c:207
>> 5 0x00007ff8d4c2a1c9: ?? ??:0
>> 6 0x00007ff8d4c2a28a: ?? ??:0
>> 7 0x0000000000403314: _start at ??:?
>> 0x3 != 0x5 (event_type != expected_type)
>>
>> after a little digging I think the issue could be this in arch/x86/kvm/x86.h:
>>
>> static inline bool kvm_exception_is_soft(unsigned int nr)
>> {
>> return (nr == BP_VECTOR) || (nr == OF_VECTOR);
>> }
>>
>> Since ICEBP(INT1) results in a DB_VECTOR it's not take into account and the
>> check fails. Then in vmx_inject_exception() INTR_TYPE_HARD_EXCEPTION is picked
>> which is 0x3 when decoded.
>
>That's a real bug then.
>
>> I think you'd need to add another check in vmx_inject_exception() to handle that
>> DB_VECTOR too. Simply changing the event type if the vector is of DB_VECTOR type
>> fixes that problem but then the selftest fails in other places (assert
>> fred_handler_called and saved rip vs expected_rip). I didn't yet have the time
>> to figure out what could be wrong there, maybe you would have more of an idea :)
>
>#DB is intercepted to mitigate CVE-2015-8104 (systemwide DoS). But, to
>start with, check that the test passes when #DB is not intercepted.
>That's the basecase for architectural behaviour.
>
>When #DB is intercepted, the type in EXIT_INTR_INFO needs preserving and
>forwarding into ENTRY_INTR_INFO, because that is what distinguishes an
>ICEBP #DB from other #DBs. There's no way of recovering this detail
>after the fact.
>
>On the injection side, some #DB's are traps and some are faults. ICEBP
>will have a fault-like VMExit but need trap semantics, so like other
>soft interrupts, need INSN_LEN adding to %rip. But, type=3 #DBs need to
>leave %rip unchanged.
>
>~Andrew
Also, a function that is accessed only from assembly should have the __visible annotation.
^ permalink raw reply
* Re: [PATCH v12 02/22] gpu: nova-core: gsp: Extract usable FB region from GSP
From: Joel Fernandes @ 2026-05-05 18:54 UTC (permalink / raw)
To: Alexandre Courbot
Cc: linux-kernel, Miguel Ojeda, Boqun Feng, Gary Guo, Bjorn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Dave Airlie, Daniel Almeida, dri-devel,
rust-for-linux, nova-gpu, Nikola Djukic, David Airlie, Boqun Feng,
John Hubbard, Alistair Popple, Timur Tabi, Edwin Peer,
Andrea Righi, Andy Ritger, Zhi Wang, Balbir Singh,
Philipp Stanner, alexeyi, Eliot Courtney, joel, linux-doc
In-Reply-To: <DI8AZQ06LCJR.1LDY75WJI77PM@nvidia.com>
On 5/2/2026 11:41 AM, Alexandre Courbot wrote:
> On Sun Apr 26, 2026 at 6:14 AM JST, Joel Fernandes wrote:
>> Add first_usable_fb_region() to GspStaticConfigInfo to extract the first
>> usable FB region from GSP's fbRegionInfoParams. Usable regions are those
>> that are not reserved or protected.
>>
>> The extracted region is stored in GetGspStaticInfoReply and exposed as
>> usable_fb_region field for use by the memory subsystem.
>>
>> Cc: Nikola Djukic <ndjukic@nvidia.com>
>> Reviewed-by: John Hubbard <jhubbard@nvidia.com>
>> Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
>> ---
>> drivers/gpu/nova-core/gsp/commands.rs | 11 ++++--
>> drivers/gpu/nova-core/gsp/fw/commands.rs | 45 +++++++++++++++++++++++-
>> 2 files changed, 52 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
>> index c89c7b57a751..d18abd8b5f04 100644
>> --- a/drivers/gpu/nova-core/gsp/commands.rs
>> +++ b/drivers/gpu/nova-core/gsp/commands.rs
>> @@ -4,6 +4,7 @@
>> array,
>> convert::Infallible,
>> ffi::FromBytesUntilNulError,
>> + ops::Range,
>> str::Utf8Error, //
>> };
>>
>> @@ -189,15 +190,18 @@ fn init(&self) -> impl Init<Self::Command, Self::InitError> {
>> }
>> }
>>
>> -/// The reply from the GSP to the [`GetGspInfo`] command.
>> +/// The reply from the GSP to the [`GetGspStaticInfo`] command.
>> pub(crate) struct GetGspStaticInfoReply {
>> gpu_name: [u8; 64],
>> + /// Usable FB (VRAM) region for driver memory allocation.
>> + #[expect(dead_code)]
>> + pub(crate) usable_fb_region: Range<u64>,
>> }
>>
>> impl MessageFromGsp for GetGspStaticInfoReply {
>> const FUNCTION: MsgFunction = MsgFunction::GetGspStaticInfo;
>> type Message = GspStaticConfigInfo;
>> - type InitError = Infallible;
>> + type InitError = Error;
>>
>> fn read(
>> msg: &Self::Message,
>> @@ -205,6 +209,7 @@ fn read(
>> ) -> Result<Self, Self::InitError> {
>> Ok(GetGspStaticInfoReply {
>> gpu_name: msg.gpu_name_str(),
>> + usable_fb_region: msg.first_usable_fb_region().ok_or(ENODEV)?,
>> })
>> }
>> }
>> @@ -233,7 +238,7 @@ pub(crate) fn gpu_name(&self) -> core::result::Result<&str, GpuNameError> {
>> }
>> }
>>
>> -/// Send the [`GetGspInfo`] command and awaits for its reply.
>> +/// Send the [`GetGspStaticInfo`] command and awaits for its reply.
>> pub(crate) fn get_gsp_info(cmdq: &Cmdq, bar: &Bar0) -> Result<GetGspStaticInfoReply> {
>> cmdq.send_command(bar, GetGspStaticInfo)
>> }
>> diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
>> index db46276430be..a34d29280430 100644
>> --- a/drivers/gpu/nova-core/gsp/fw/commands.rs
>> +++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
>> @@ -1,5 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0
>>
>> +use core::ops::Range;
>> +
>> use kernel::{
>> device,
>> pci,
>> @@ -10,7 +12,10 @@
>> }, //
>> };
>>
>> -use crate::gsp::GSP_PAGE_SIZE;
>> +use crate::{
>> + gsp::GSP_PAGE_SIZE,
>> + num::IntoSafeCast, //
>> +};
>>
>> use super::bindings;
>>
>> @@ -121,6 +126,44 @@ impl GspStaticConfigInfo {
>> pub(crate) fn gpu_name_str(&self) -> [u8; 64] {
>> self.0.gpuNameString
>> }
>> +
>> + /// Returns an iterator over valid FB regions from GSP firmware data.
>> + fn fb_regions(
>> + &self,
>> + ) -> impl Iterator<Item = &bindings::NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO> {
>> + let fb_info = &self.0.fbRegionInfoParams;
>> + fb_info
>> + .fbRegion
>> + .iter()
>> + .take(fb_info.numFBRegions.into_safe_cast())
>> + .filter(|reg| reg.limit >= reg.base)
>> + }
>> +
>> + /// Extracts the first usable FB region from GSP firmware data.
>> + ///
>> + /// Returns the first region suitable for driver memory allocation as a [`Range<u64>`].
>> + /// Usable regions are those that satisfy all the following properties:
>> + /// - Are not reserved for firmware internal use.
>> + /// - Are not protected (hardware-enforced access restrictions).
>> + /// - Support compression (can use GPU memory compression for bandwidth).
>
> "can use GPU memory compression for saving bandwidth" maybe?
Done.
>
>> + /// - Support ISO (isochronous memory for display requiring guaranteed bandwidth).
>> + ///
>> + /// TODO: Multiple discontinuous usable regions of RAM are possible in
>> + /// special cases. We need to support it.
>> + pub(crate) fn first_usable_fb_region(&self) -> Option<Range<u64>> {
>
> Let's be forward-thinking, and turn this method into
> `usable_fb_regions_iter`, returning an iterator. It is trivial to do
> (just turn `find_map` into `filter`), we will need it later, and for now
> the caller can just do `next()` to get the first region.
Done. Indeed, it does not add more LOC while supporting multiple regions.
thanks,
--
Joel Fernandes
^ permalink raw reply
* Re: [PATCH v5 11/13] ima: Support staging and deleting N measurements entries
From: steven chen @ 2026-05-05 18:43 UTC (permalink / raw)
To: Roberto Sassu, corbet, skhan, zohar, dmitry.kasatkin,
eric.snowberg, paul, jmorris, serge
Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
gregorylumen, nramas, Roberto Sassu, steven chen
In-Reply-To: <20260429160319.4162918-12-roberto.sassu@huaweicloud.com>
On 4/29/2026 9:03 AM, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> Add support for sending a value N between 1 and ULONG_MAX to the IMA
> original measurement interface. This value represents the number of
> measurements that should be deleted from the current measurements list. In
> this case, measurements are staged in an internal non-user visible list,
> and immediately deleted.
>
> This staging method allows the remote attestation agents to easily separate
> the measurements that were verified (staged and deleted) from those that
> weren't due to the race between taking a TPM quote and reading the
> measurements list.
>
> In order to minimize the locking time of ima_extend_list_mutex, deleting
> N entries is realized by doing a lockless walk in the current measurements
> list to determine the N-th entry to cut, to cut the current measurements
> list under the lock, and by deleting the excess entries after releasing the
> lock.
>
> Flushing the hash table is not supported for N entries, since it would
> require removing the N entries one by one from the hash table under the
> ima_extend_list_mutex lock, which would increase the locking time.
>
> The ima_extend_list_mutex lock is necessary in ima_dump_measurement_list()
> because ima_queue_delete_partial() uses __list_cut_position() to modify
> ima_measurements, for which no RCU-safe variant exists. For the staging
> with prompt flavor alone, list_replace_rcu() could have been used instead,
> but since both flavors share the same kexec serialization path, the mutex
> is required regardless.
This submit provides two ways for trimming logs:
Patch 9: stage and delete
This patch 11: stage and delete N
Both are doing the same thing in different ways
I think the best way is just keep the patch 11 for following reasons:
Kernel list lock time is minimum
Kernel code change will be much simpler (almost half gone)
User space processing for log trimming is much simpler
no need to maintain two lists (old and staged) in user space
No two lists seen from user space (same as before)
no staged list shown
Steven
> Link: https://github.com/linux-integrity/linux/issues/1
> Suggested-by: Steven Chen <chenste@linux.microsoft.com>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
> security/integrity/ima/Kconfig | 3 +++
> security/integrity/ima/ima.h | 1 +
> security/integrity/ima/ima_fs.c | 21 ++++++++++++++-
> security/integrity/ima/ima_kexec.c | 3 ++-
> security/integrity/ima/ima_queue.c | 43 ++++++++++++++++++++++++++++++
> 5 files changed, 69 insertions(+), 2 deletions(-)
>
> diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
> index 48c906793efb..4f4373859a4f 100644
> --- a/security/integrity/ima/Kconfig
> +++ b/security/integrity/ima/Kconfig
> @@ -341,6 +341,9 @@ config IMA_STAGING
> It allows user space to stage the measurements list for deletion and
> to delete the staged measurements after confirmation.
>
> + Or, alternatively, it allows user space to specify N measurements
> + entries to stage internally, so that they can be immediately deleted.
> +
> On kexec, staging is reverted and staged measurements are prepended
> to the current measurements list when measurements are copied to the
> secondary kernel.
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 4af66c1de4dc..9a741b33d524 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -320,6 +320,7 @@ struct ima_template_desc *lookup_template_desc(const char *name);
> bool ima_template_has_modsig(const struct ima_template_desc *ima_template);
> int ima_queue_stage(void);
> int ima_queue_staged_delete_all(void);
> +int ima_queue_delete_partial(unsigned long req_value);
> int ima_restore_measurement_entry(struct ima_template_entry *entry);
> int ima_restore_measurement_list(loff_t bufsize, void *buf);
> int ima_measurements_show(struct seq_file *m, void *v);
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 088d5a69aa92..6843dc203b54 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -28,6 +28,7 @@
> * Requests:
> * 'A\n': stage the entire measurements list
> * 'D\n': delete all staged measurements
> + * '[1, ULONG_MAX]\n' delete N measurements entries
> */
> #define STAGED_REQ_LENGTH 21
>
> @@ -312,6 +313,7 @@ static ssize_t _ima_measurements_write(struct file *file,
> loff_t *ppos, bool staged_interface)
> {
> char req[STAGED_REQ_LENGTH];
> + unsigned long req_value;
> int ret;
>
> if (*ppos > 0 || datalen < 2 || datalen > STAGED_REQ_LENGTH)
> @@ -339,7 +341,24 @@ static ssize_t _ima_measurements_write(struct file *file,
> ret = ima_queue_staged_delete_all();
> break;
> default:
> - ret = -EINVAL;
> + if (staged_interface)
> + return -EINVAL;
> +
> + if (ima_flush_htable) {
> + pr_debug("Deleting staged N measurements not supported when flushing the hash table is requested\n");
> + return -EINVAL;
> + }
> +
> + ret = kstrtoul(req, 10, &req_value);
> + if (ret < 0)
> + return ret;
> +
> + if (req_value == 0) {
> + pr_debug("Must delete at least one entry\n");
> + return -EINVAL;
> + }
> +
> + ret = ima_queue_delete_partial(req_value);
> }
>
> if (ret < 0)
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> index 064cfce0c318..e7bde3d917b2 100644
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -107,7 +107,8 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
> memset(&khdr, 0, sizeof(khdr));
> khdr.version = 1;
> /*
> - * It can race with ima_queue_stage() and ima_queue_staged_delete_all().
> + * It can race with ima_queue_stage(), ima_queue_staged_delete_all()
> + * and ima_queue_delete_partial().
> */
> mutex_lock(&ima_extend_list_mutex);
>
> diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
> index f5c18acfbc43..64c4fe73dd5f 100644
> --- a/security/integrity/ima/ima_queue.c
> +++ b/security/integrity/ima/ima_queue.c
> @@ -371,6 +371,49 @@ int ima_queue_staged_delete_all(void)
> return 0;
> }
>
> +int ima_queue_delete_partial(unsigned long req_value)
> +{
> + unsigned long req_value_copy = req_value;
> + unsigned long size_to_remove = 0, num_to_remove = 0;
> + LIST_HEAD(ima_measurements_trim);
> + struct ima_queue_entry *qe;
> + int ret = 0;
> +
> + /*
> + * Safe to walk without rcu_read_lock(): single-writer
> + * exclusion in ima_fs.c prevents any concurrent modification
> + * to ima_measurements during this walk.
> + */
> + list_for_each_entry_rcu(qe, &ima_measurements, later, true) {
> + size_to_remove += get_binary_runtime_size(qe->entry);
> + num_to_remove++;
> +
> + if (--req_value_copy == 0)
> + break;
> + }
> +
> + /* Not enough entries to delete. */
> + if (req_value_copy > 0)
> + return -ENOENT;
> +
> + mutex_lock(&ima_extend_list_mutex);
> + /*
> + * qe remains valid because ima_fs.c enforces single-writer exclusion.
> + */
> + __list_cut_position(&ima_measurements_trim, &ima_measurements,
> + &qe->later);
> +
> + atomic_long_sub(num_to_remove, &ima_num_entries[BINARY]);
> +
> + if (IS_ENABLED(CONFIG_IMA_KEXEC))
> + binary_runtime_size[BINARY] -= size_to_remove;
> +
> + mutex_unlock(&ima_extend_list_mutex);
> +
> + ima_queue_delete(&ima_measurements_trim, false);
> + return ret;
> +}
> +
> static void ima_queue_delete(struct list_head *head, bool flush_htable)
> {
> struct ima_queue_entry *qe, *qe_tmp;
^ permalink raw reply
* Re: [PATCH v9 00/22] Enable FRED with KVM VMX
From: Andrew Cooper @ 2026-05-05 18:30 UTC (permalink / raw)
To: Maciej Wieczor-Retman, Xin Li
Cc: Andrew Cooper, David Woodhouse, linux-kernel, kvm, linux-doc,
Saenz Julienne, Nicolas, pbonzini, seanjc, corbet, tglx, mingo,
bp, dave.hansen, x86, hpa, luto, peterz, chao.gao, hch,
sohil.mehta
In-Reply-To: <afojoHJSlqqm2Ges@wieczorr-mobl1.localdomain>
On 05/05/2026 7:04 pm, Maciej Wieczor-Retman wrote:
> Hello!
>
>
> On 2026-04-23 at 15:56:54 -0700, Xin Li wrote:
>>> On Apr 23, 2026, at 7:35 AM, David Woodhouse <dwmw2@infradead.org> wrote:
>>> Here's one to get you started (untested as I haven't found suitable
>>> hardware to test it on).
>> Same here for me now :(
> I ran David's selftest on a PTL laptop and ran into a couple of issues.
>
>>> From bd465aabebcb124e09a26fe9f4c861354febabe4 Mon Sep 17 00:00:00 2001
>>> From: David Woodhouse <dwmw@amazon.co.uk>
>>> Date: Thu, 23 Apr 2026 15:20:11 +0100
>>> Subject: [PATCH] KVM: selftests: Add FRED event type classification test
>>>
>>> +static void __used fred_handler(struct fred_stack_frame *frame)
>>> +{
>>> + fred_ss_value = frame->ss;
>>> + fred_saved_rip = frame->rip;
>>> + fred_handler_called = true;
>>> +}
> fred_handler() has problems getting linked:
>
> /usr/bin/ld: /home/maciej/linux/tools/testing/selftests/kvm/x86/int1_fred_test.o: in function `fred_entrypoint_kernel':
> int1_fred_test.c:(.text+0x104): undefined reference to `fred_handler'
> collect2: error: ld returned 1 exit status
>
> I guess the .pushsection below makes it a different translation unit? Because
> getting rid of the static keyword takes care of the problem for me.
The problem is, being static, fred_handler() is eligible to be optimised
away, because the compiler can't see that the asm() refers to it.
Dropping static is the right fix to make.
GCC 15 can now do references out of global asm() to identify the symbols
they use, but it's going to be years before this capability is safe to
use generally.
>
>>> +
>>> +/*
>>> + * FRED entry points. MSR_IA32_FRED_CONFIG points to the page-aligned
>>> + * base. Ring 3 events enter at base+0, ring 0 events at base+0x100.
>>> + * Since ICEBP executes in ring 0, the CPU enters at fred_entrypoint
>>> + * + 256 = fred_entrypoint_kernel.
>>> + */
>>> +extern void fred_entrypoint(void);
>>> +
>>> +asm(
>>> + ".pushsection .text\n"
>>> + ".global fred_entrypoint\n"
>>> + ".balign 4096\n"
>>> +"fred_entrypoint:\n"
>>> + /* Ring 3 entry — unused, no userspace in this test */
>>> + "ud2\n"
>>> + /* Pad to +256 for ring 0 entry */
>>> + ".org fred_entrypoint + 256, 0xcc\n"
>>> +"fred_entrypoint_kernel:\n"
>>> + "movq %rsp, %rdi\n"
>>> + "call fred_handler\n"
>>> + ".byte 0xf2, 0x0f, 0x01, 0xca\n" /* ERETS */
>>> + ".popsection\n"
>>> +);
>>> +
> ...
>>> +
>>> + /* Test 1: ICEBP (INT1) — should be EVENT_TYPE_PRIV_SWEXC (5) */
>>> + fred_handler_called = false;
>>> + asm volatile("lea 1f(%%rip), %0\n\t"
>>> + ".byte 0xf1\n\t"
>>> + "1:" : "=r"(expected_rip) :: "memory");
>>> + check_fred_event(expected_rip, DB_VECTOR, EVENT_TYPE_PRIV_SWEXC,
>>> + "ICEBP");
>>> + GUEST_SYNC(0);
> The above event type test seems to fail and return 0x3 instead of 0x5:
>
> Random seed: 0x6b8b4567
> Testing FRED event types with EPT fault on stack
> ==== Test Assertion Failure ====
> x86/int1_fred_test.c:120: event_type == expected_type
> pid=16646 tid=16646 errno=4 - Interrupted system call
> 1 0x0000000000413349: assert_on_unhandled_exception at processor.c:659
> 2 0x0000000000407d36: _vcpu_run at kvm_util.c:1703
> 3 (inlined by) vcpu_run at kvm_util.c:1714
> 4 0x0000000000403104: main at int1_fred_test.c:207
> 5 0x00007ff8d4c2a1c9: ?? ??:0
> 6 0x00007ff8d4c2a28a: ?? ??:0
> 7 0x0000000000403314: _start at ??:?
> 0x3 != 0x5 (event_type != expected_type)
>
> after a little digging I think the issue could be this in arch/x86/kvm/x86.h:
>
> static inline bool kvm_exception_is_soft(unsigned int nr)
> {
> return (nr == BP_VECTOR) || (nr == OF_VECTOR);
> }
>
> Since ICEBP(INT1) results in a DB_VECTOR it's not take into account and the
> check fails. Then in vmx_inject_exception() INTR_TYPE_HARD_EXCEPTION is picked
> which is 0x3 when decoded.
That's a real bug then.
> I think you'd need to add another check in vmx_inject_exception() to handle that
> DB_VECTOR too. Simply changing the event type if the vector is of DB_VECTOR type
> fixes that problem but then the selftest fails in other places (assert
> fred_handler_called and saved rip vs expected_rip). I didn't yet have the time
> to figure out what could be wrong there, maybe you would have more of an idea :)
#DB is intercepted to mitigate CVE-2015-8104 (systemwide DoS). But, to
start with, check that the test passes when #DB is not intercepted.
That's the basecase for architectural behaviour.
When #DB is intercepted, the type in EXIT_INTR_INFO needs preserving and
forwarding into ENTRY_INTR_INFO, because that is what distinguishes an
ICEBP #DB from other #DBs. There's no way of recovering this detail
after the fact.
On the injection side, some #DB's are traps and some are faults. ICEBP
will have a fault-like VMExit but need trap semantics, so like other
soft interrupts, need INSN_LEN adding to %rip. But, type=3 #DBs need to
leave %rip unchanged.
~Andrew
^ permalink raw reply
* Re: [PATCH 3/4] docs: admin-guide: clarify perf bench all behavior
From: Shuah Khan @ 2026-05-05 18:27 UTC (permalink / raw)
To: Cheng-Han Wu, Jonathan Corbet
Cc: Randy Dunlap, linux-doc, linux-kernel, Shuah Khan
In-Reply-To: <20260503101429.254394-4-hank20010209@gmail.com>
On 5/3/26 04:14, Cheng-Han Wu wrote:
> The workload tracing guide lists a fixed set of benchmarks for
> "perf bench all". This list is stale and can become outdated when
> perf adds, removes, or renames benchmark collections or individual
> benchmarks.
>
> Describe "perf bench all" as running all available benchmarks in the perf
> bench framework instead. Also document how to list the collections and
> benchmarks available on a given system.
>
> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
> ---
> .../admin-guide/workload-tracing.rst | 20 +++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
> index 43a3c8098654..c49c2a00a8b8 100644
> --- a/Documentation/admin-guide/workload-tracing.rst
> +++ b/Documentation/admin-guide/workload-tracing.rst
> @@ -243,13 +243,21 @@ which can help mitigate performance regressions. It also acts as a common
> benchmarking framework, enabling developers to easily create test cases,
> integrate transparently, and use performance-rich tooling.
>
> -"perf bench all" command runs the following benchmarks:
> +"perf bench all" runs all available benchmarks in the perf bench
> +framework. The exact set of benchmarks depends on the perf version and on
> +the features enabled when perf was built.
>
> - * sched/messaging
> - * sched/pipe
> - * syscall/basic
> - * mem/memcpy
> - * mem/memset
> +To list the benchmark collections available on the current system, run::
> +
> + perf bench
> +
> +To list benchmarks in a collection, run::
> +
> + perf bench <collection>
> +
> +For example, to list the benchmarks in the mem collection, run::
> +
> + perf bench mem
>
> What is stress-ng and how do we use it?
> =======================================
Looks to good to me.
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
thanks,
-- Shuah
^ permalink raw reply
* Re: [PATCH 2/4] docs: admin-guide: fix stress-ng command examples
From: Shuah Khan @ 2026-05-05 18:27 UTC (permalink / raw)
To: Cheng-Han Wu, Jonathan Corbet
Cc: Randy Dunlap, linux-doc, linux-kernel, Shuah Khan
In-Reply-To: <20260503101429.254394-3-hank20010209@gmail.com>
On 5/3/26 04:14, Cheng-Han Wu wrote:
> The workload tracing guide includes stress-ng command examples with a
> stray "command." word at the end. This makes the examples invalid if they
> are copied and run directly.
>
> Remove the stray word from the stress-ng example. Also use "--" in the
> perf record example to clearly separate perf record options from the
> workload command being recorded.
>
> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
> ---
> Documentation/admin-guide/workload-tracing.rst | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
> index 22cb05025ffc..43a3c8098654 100644
> --- a/Documentation/admin-guide/workload-tracing.rst
> +++ b/Documentation/admin-guide/workload-tracing.rst
> @@ -271,7 +271,7 @@ exercised:
>
> The following command runs the stressor::
>
> - stress-ng --netdev 1 -t 60 --metrics command.
> + stress-ng --netdev 1 -t 60 --metrics
>
> We can use the perf record command to record the events and information
> associated with a process. This command records the profiling data in the
> @@ -281,7 +281,7 @@ Using the following commands you can record the events associated with the
> netdev stressor, view the generated report perf.data and annotate the output
> to view the statistics of each instruction of the program::
>
> - perf record stress-ng --netdev 1 -t 60 --metrics command.
> + perf record -- stress-ng --netdev 1 -t 60 --metrics
> perf report
> perf annotate
>
Looks to good to me.
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
thanks,
-- Shuah
^ permalink raw reply
* Re: [PATCH 1/4] docs: admin-guide: fix typos in workload tracing guide
From: Shuah Khan @ 2026-05-05 18:26 UTC (permalink / raw)
To: Cheng-Han Wu, Jonathan Corbet
Cc: Randy Dunlap, linux-doc, linux-kernel, Shuah Khan
In-Reply-To: <20260503101429.254394-2-hank20010209@gmail.com>
On 5/3/26 04:14, Cheng-Han Wu wrote:
> Fix several typos in the workload tracing guide:
>
> - sys_opennat() -> sys_openat()
> - annotate the to view -> annotate the output to view
> - sys_getegid -> sys_getegid()
>
> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
> ---
> Documentation/admin-guide/workload-tracing.rst | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
> index 35963491b9f1..22cb05025ffc 100644
> --- a/Documentation/admin-guide/workload-tracing.rst
> +++ b/Documentation/admin-guide/workload-tracing.rst
> @@ -278,8 +278,8 @@ associated with a process. This command records the profiling data in the
> perf.data file in the same directory.
>
> Using the following commands you can record the events associated with the
> -netdev stressor, view the generated report perf.data and annotate the to
> -view the statistics of each instruction of the program::
> +netdev stressor, view the generated report perf.data and annotate the output
> +to view the statistics of each instruction of the program::
>
> perf record stress-ng --netdev 1 -t 60 --metrics command.
> perf report
> @@ -349,13 +349,13 @@ times each system call is invoked, and the corresponding Linux subsystem.
> +-------------------+-----------+-----------------+-------------------------+
> | geteuid | 1 | Process Mgmt. | sys_geteuid() |
> +-------------------+-----------+-----------------+-------------------------+
> -| getegid | 1 | Process Mgmt. | sys_getegid |
> +| getegid | 1 | Process Mgmt. | sys_getegid() |
> +-------------------+-----------+-----------------+-------------------------+
> | close | 49951 | Filesystem | sys_close() |
> +-------------------+-----------+-----------------+-------------------------+
> | pipe | 604 | Filesystem | sys_pipe() |
> +-------------------+-----------+-----------------+-------------------------+
> -| openat | 48560 | Filesystem | sys_opennat() |
> +| openat | 48560 | Filesystem | sys_openat() |
> +-------------------+-----------+-----------------+-------------------------+
> | fstat | 8338 | Filesystem | sys_fstat() |
> +-------------------+-----------+-----------------+-------------------------+
Looks to good to me.
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
thanks,
-- Shuah
^ permalink raw reply
* Re: [PATCH 01/14] kbuild: Bump minimum version of LLVM for building the kernel to 17.0.1
From: Daniel Pereira @ 2026-05-05 18:26 UTC (permalink / raw)
To: Nathan Chancellor, Bill Wendling, Justin Stitt, Nick Desaulniers,
linux-kernel, llvm, linux-kbuild, Jonathan Corbet, Shuah Khan,
linux-doc
In-Reply-To: <afoMRMnSQUwk1eaN@levanger>
On Tue, May 5, 2026 at 1:11 PM Nicolas Schier <nsc@kernel.org> wrote:
>
>> FTR: The translations
>>Documentation/translations/{it\_IT,pt\_BR}/process/changes.rst become now
>>even more outdated.
>
>>Acked-by: Nicolas Schier <nsc@kernel.org>
>
Hi Nicolas,
Just confirming that I will make the necessary corrections to the
changes.rst Portuguese translation (pt\_BR) in the next few days.
Thanks,
Daniel Pereira
Linux Kernel Maintainer pt\_BR
^ permalink raw reply
* Re: [PATCH v12 01/22] gpu: nova-core: gsp: Return GspStaticInfo from boot()
From: Joel Fernandes @ 2026-05-05 18:25 UTC (permalink / raw)
To: Alexandre Courbot
Cc: linux-kernel, Miguel Ojeda, Boqun Feng, Gary Guo, Bjorn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Dave Airlie, Daniel Almeida, dri-devel,
rust-for-linux, nova-gpu, Nikola Djukic, David Airlie, Boqun Feng,
John Hubbard, Alistair Popple, Timur Tabi, Edwin Peer,
Andrea Righi, Andy Ritger, Zhi Wang, Balbir Singh,
Philipp Stanner, alexeyi, Eliot Courtney, joel, linux-doc
In-Reply-To: <DI8AZLB2610U.10MNQ0IPV6NSL@nvidia.com>
On 5/2/2026 11:41 AM, Alexandre Courbot wrote:
> On Sun Apr 26, 2026 at 6:14 AM JST, Joel Fernandes wrote:
>> Refactor the GSP boot function to return GetGspStaticInfoReply.
>>
>> This enables access required for memory management initialization to:
>> - bar1_pde_base: BAR1 page directory base.
>> - bar2_pde_base: BAR2 page directory base.
>> - usable memory regions in video memory.
>>
>> Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
>> Reviewed-by: John Hubbard <jhubbard@nvidia.com>
>> Cc: Nikola Djukic <ndjukic@nvidia.com>
>> Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
>> ---
>> drivers/gpu/nova-core/gpu.rs | 8 ++++++--
>> drivers/gpu/nova-core/gsp/boot.rs | 12 ++++++++----
>> 2 files changed, 14 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
>> index 0f6fe9a1b955..f2a8915a1ff4 100644
>> --- a/drivers/gpu/nova-core/gpu.rs
>> +++ b/drivers/gpu/nova-core/gpu.rs
>> @@ -21,7 +21,10 @@
>> },
>> fb::SysmemFlush,
>> gfw,
>> - gsp::Gsp,
>> + gsp::{
>> + commands::GetGspStaticInfoReply,
>> + Gsp, //
>> + },
>> regs,
>> };
>>
>> @@ -238,6 +241,7 @@ pub(crate) struct Gpu {
>> /// GSP runtime data. Temporarily an empty placeholder.
>> #[pin]
>> gsp: Gsp,
>> + gsp_static_info: GetGspStaticInfoReply,
>
> A short doccomment would be nice, but otherwise this looks good.
I had added one before, but John suggested to drop it. I could add it back again
if all agree on what we want to do. I am Ok with either though I'd lean more to
the fact that its not necessary since it will basically read like the variable.
thanks.
^ permalink raw reply
* Re: [PATCH 4/4] docs: admin-guide: add IGNORE_DIRS example for cscope
From: Shuah Khan @ 2026-05-05 18:24 UTC (permalink / raw)
To: Cheng-Han Wu, Jonathan Corbet
Cc: Randy Dunlap, linux-doc, linux-kernel, Shuah Khan
In-Reply-To: <20260503101429.254394-5-hank20010209@gmail.com>
On 5/3/26 04:14, Cheng-Han Wu wrote:
> The workload tracing guide shows how to build a cscope database by
> running cscope command directly. The kernel build system also provides
> a cscope target, which supports IGNORE_DIRS for excluding directories
> from the generated database.
>
> Mention make cscope and show how to exclude Documentation/ as an example.
>
> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
> ---
> Documentation/admin-guide/workload-tracing.rst | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
> index c49c2a00a8b8..314e5f03474e 100644
> --- a/Documentation/admin-guide/workload-tracing.rst
> +++ b/Documentation/admin-guide/workload-tracing.rst
> @@ -202,6 +202,15 @@ database. To get out of this mode press ctrl+d. -p option is used to
> specify the number of file path components to display. -p10 is optimal
> for browsing kernel sources.
>
> +Alternatively, the kernel build system can generate the cscope database::
> +
> + make cscope
> +
> +To exclude directories from the generated database, pass IGNORE_DIRS to
> +the cscope target. For example, to exclude Documentation/, run::
> +
> + make IGNORE_DIRS="Documentation" cscope
> +
> What is perf and how do we use it?
> ==================================
>
Looks good to me.
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
thanks,
-- Shuah
^ permalink raw reply
* Re: [PATCH] Documentation: translations: Fix "Linux Torvalds" -> "Linus Torvalds"
From: Federico Vaga @ 2026-05-05 18:22 UTC (permalink / raw)
To: Jonathan Corbet
Cc: Wang Zihan, linux-doc, skhan, carlos.bilbao, avadhut.naik,
linux-kernel
In-Reply-To: <87ecjsef3c.fsf@trenco.lwn.net>
On Sun, May 03, 2026 at 08:35:03AM -0600, Jonathan Corbet wrote:
>Wang Zihan <jiyu03@qq.com> writes:
>
>> Fix the misspelling of Linus Torvalds' first name in Italian
>> and Spanish translations.
>>
>> Also fix "Linus Torvald" -> "Linus Torvalds" (missing 's') in
>> Italian translations.
>>
>> Found by Christian Marillat.
>>
>> Signed-off-by: Wang Zihan <jiyu03@qq.com>
>
>The fixes all seem good. It should have a proper Reported-by line,
>though, and it seems you didn't CC Christian on this email...?
Of course it is all good. Sorry for the typos
--
Federico Vaga
^ permalink raw reply
* Re: [PATCH v9 00/22] Enable FRED with KVM VMX
From: Maciej Wieczor-Retman @ 2026-05-05 18:04 UTC (permalink / raw)
To: Xin Li
Cc: David Woodhouse, linux-kernel, kvm, linux-doc, Andrew Cooper,
Saenz Julienne, Nicolas, pbonzini, seanjc, corbet, tglx, mingo,
bp, dave.hansen, x86, hpa, luto, peterz, chao.gao, hch,
sohil.mehta
In-Reply-To: <DADE0E58-DD8A-4206-BF54-1DA87864117D@zytor.com>
Hello!
On 2026-04-23 at 15:56:54 -0700, Xin Li wrote:
>> On Apr 23, 2026, at 7:35 AM, David Woodhouse <dwmw2@infradead.org> wrote:
>> Here's one to get you started (untested as I haven't found suitable
>> hardware to test it on).
>
>Same here for me now :(
I ran David's selftest on a PTL laptop and ran into a couple of issues.
>>
>> From bd465aabebcb124e09a26fe9f4c861354febabe4 Mon Sep 17 00:00:00 2001
>> From: David Woodhouse <dwmw@amazon.co.uk>
>> Date: Thu, 23 Apr 2026 15:20:11 +0100
>> Subject: [PATCH] KVM: selftests: Add FRED event type classification test
>>
>> +static void __used fred_handler(struct fred_stack_frame *frame)
>> +{
>> + fred_ss_value = frame->ss;
>> + fred_saved_rip = frame->rip;
>> + fred_handler_called = true;
>> +}
fred_handler() has problems getting linked:
/usr/bin/ld: /home/maciej/linux/tools/testing/selftests/kvm/x86/int1_fred_test.o: in function `fred_entrypoint_kernel':
int1_fred_test.c:(.text+0x104): undefined reference to `fred_handler'
collect2: error: ld returned 1 exit status
I guess the .pushsection below makes it a different translation unit? Because
getting rid of the static keyword takes care of the problem for me.
>> +
>> +/*
>> + * FRED entry points. MSR_IA32_FRED_CONFIG points to the page-aligned
>> + * base. Ring 3 events enter at base+0, ring 0 events at base+0x100.
>> + * Since ICEBP executes in ring 0, the CPU enters at fred_entrypoint
>> + * + 256 = fred_entrypoint_kernel.
>> + */
>> +extern void fred_entrypoint(void);
>> +
>> +asm(
>> + ".pushsection .text\n"
>> + ".global fred_entrypoint\n"
>> + ".balign 4096\n"
>> +"fred_entrypoint:\n"
>> + /* Ring 3 entry — unused, no userspace in this test */
>> + "ud2\n"
>> + /* Pad to +256 for ring 0 entry */
>> + ".org fred_entrypoint + 256, 0xcc\n"
>> +"fred_entrypoint_kernel:\n"
>> + "movq %rsp, %rdi\n"
>> + "call fred_handler\n"
>> + ".byte 0xf2, 0x0f, 0x01, 0xca\n" /* ERETS */
>> + ".popsection\n"
>> +);
>> +
...
>> +
>> + /* Test 1: ICEBP (INT1) — should be EVENT_TYPE_PRIV_SWEXC (5) */
>> + fred_handler_called = false;
>> + asm volatile("lea 1f(%%rip), %0\n\t"
>> + ".byte 0xf1\n\t"
>> + "1:" : "=r"(expected_rip) :: "memory");
>> + check_fred_event(expected_rip, DB_VECTOR, EVENT_TYPE_PRIV_SWEXC,
>> + "ICEBP");
>> + GUEST_SYNC(0);
The above event type test seems to fail and return 0x3 instead of 0x5:
Random seed: 0x6b8b4567
Testing FRED event types with EPT fault on stack
==== Test Assertion Failure ====
x86/int1_fred_test.c:120: event_type == expected_type
pid=16646 tid=16646 errno=4 - Interrupted system call
1 0x0000000000413349: assert_on_unhandled_exception at processor.c:659
2 0x0000000000407d36: _vcpu_run at kvm_util.c:1703
3 (inlined by) vcpu_run at kvm_util.c:1714
4 0x0000000000403104: main at int1_fred_test.c:207
5 0x00007ff8d4c2a1c9: ?? ??:0
6 0x00007ff8d4c2a28a: ?? ??:0
7 0x0000000000403314: _start at ??:?
0x3 != 0x5 (event_type != expected_type)
after a little digging I think the issue could be this in arch/x86/kvm/x86.h:
static inline bool kvm_exception_is_soft(unsigned int nr)
{
return (nr == BP_VECTOR) || (nr == OF_VECTOR);
}
Since ICEBP(INT1) results in a DB_VECTOR it's not take into account and the
check fails. Then in vmx_inject_exception() INTR_TYPE_HARD_EXCEPTION is picked
which is 0x3 when decoded.
I think you'd need to add another check in vmx_inject_exception() to handle that
DB_VECTOR too. Simply changing the event type if the vector is of DB_VECTOR type
fixes that problem but then the selftest fails in other places (assert
fred_handler_called and saved rip vs expected_rip). I didn't yet have the time
to figure out what could be wrong there, maybe you would have more of an idea :)
--
Kind regards
Maciej Wieczór-Retman
^ permalink raw reply
* Re: [PATCH v2 11/11] MAINTAINERS: use a URL for pin-init maintainer's profile entry
From: Miguel Ojeda @ 2026-05-05 18:04 UTC (permalink / raw)
To: Gary Guo
Cc: Mauro Carvalho Chehab, Benno Lossin, Jonathan Corbet,
Linux Doc Mailing List, linux-kernel, rust-for-linux,
Björn Roy Baron, Alice Ryhl, Andreas Hindborg, Boqun Feng,
Danilo Krummrich, Miguel Ojeda, Trevor Gross
In-Reply-To: <DIASHBBEIHQW.3EQSDUML6G3SB@garyguo.net>
On Tue, May 5, 2026 at 3:49 PM Gary Guo <gary@garyguo.net> wrote:
>
> This file is part of the bidirectional source sync.
>
> I think this file is still meaningful in its present location even if not
> rendered, so people touching the code would be able to see it and be aware. The
> presence of file is more visible than a P entry in the MAINTAINERS file.
>
> That said, if Miguel and/or Benno think it's fine to not have this file, I'm
> also okay with it being removed.
Yeah, I think it is fine to keep it, and it also has the advantage of
being always available.
(If we are keeping the parser change, then I am not sure we should
even change this, but it is not a big deal -- I wrote a comment in the
other patch about this).
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH v2 10/11] MAINTAINERS: make clearer about what's expected for "P" field
From: Miguel Ojeda @ 2026-05-05 18:02 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Jonathan Corbet, Linux Doc Mailing List, linux-kernel,
rust-for-linux
In-Reply-To: <921e5e6a074f9d8cf77483d73e6801f49254bbb8.1777987027.git.mchehab+huawei@kernel.org>
On Tue, May 5, 2026 at 3:32 PM Mauro Carvalho Chehab
<mchehab+huawei@kernel.org> wrote:
>
> extenal site. Make it clearer.
Typo.
> + patches to the given subsystem. This is either an in-tree .rst file,
Should this mention that the file should be within `Doc/`, due to the
requirement of the current system?
By the way, are we keeping the parser change to avoid breakage in case
someone does not follow this? Or should this be
ideally, an in-tree .rst file within Documentation/ for best rendering
or similar?
(Also, if the parser is changed, then I am ambivalent about changing
the `P:` to GitHub, since the local file is available by definition,
but GitHub may not... But it is fine either way!)
Thanks!
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH net-next v2 1/6] net: add netmem_tx modes that indicate dma capability
From: Harshitha Ramamurthy @ 2026-05-05 17:41 UTC (permalink / raw)
To: Bobby Eshleman
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
Joshua Washington, Saeed Mahameed, Tariq Toukan, Mark Bloch,
Leon Romanovsky, Alexander Duyck, kernel-team, Daniel Borkmann,
Nikolay Aleksandrov, Shuah Khan, netdev, linux-doc, linux-kernel,
linux-rdma, bpf, linux-kselftest, Stanislav Fomichev,
Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-1-56d52ac72fd4@meta.com>
On Mon, May 4, 2026 at 5:27 PM Bobby Eshleman <bobbyeshleman@gmail.com> wrote:
>
> From: Bobby Eshleman <bobbyeshleman@meta.com>
>
> Devices that support netmem TX previously set dev->netmem_tx = true.
> This was checked in validate_xmit_unreadable_skb() to drop unreadable
> skbs (skbs with dmabuf-backed frags) before they reach drivers that
> would mishandle them or devices that would not have the iommu mappings
> for them.
>
> Some virtual devices like netkit (or ifb) never DMA and never touch frag
> contents, as they essentially just forward the skb to another device.
> They are unable to forward unreadable skbs, however, because they fail
> to pass TX validation checks on dev->netmem_tx. This single bit flag
> doesn't give the TX validator enough information to differentiate
> devices that will attempt DMA on the unreadable skb and those that will
> simply route it untouched.
>
> This patch fixes this issue by adding an additional bit to netmem_tx, so
> that drivers can indicate 1) if they have netmem support, and 2) if they
> do, are they DMA-capable or not?
>
> Replace the boolean with a 2-bit enum:
>
> NETMEM_TX_NONE - no netmem TX support (drop unreadable skbs)
> NETMEM_TX_DMA - full support, device does DMA
> NETMEM_TX_NO_DMA - pass-through, device never DMAs
>
> Update drivers to reflect these definitions. NIC drivers use
> NETMEM_TX_DMA, and netkit uses NETMEM_TX_NO_DMA.
>
> Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
> ---
> Changes in v2:
> - Squash driver conversion patches (2-5) into patch 1 (Jakub)
> ---
> Documentation/networking/net_cachelines/net_device.rst | 2 +-
> Documentation/networking/netmem.rst | 8 +++++++-
> Documentation/translations/zh_CN/networking/netmem.rst | 7 ++++++-
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
> drivers/net/ethernet/google/gve/gve_main.c | 2 +-
> drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
> drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 2 +-
> drivers/net/netkit.c | 1 +
> include/linux/netdevice.h | 11 +++++++++--
> 9 files changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
> index 1c19bb7705df..c85784259544 100644
> --- a/Documentation/networking/net_cachelines/net_device.rst
> +++ b/Documentation/networking/net_cachelines/net_device.rst
> @@ -10,7 +10,7 @@ Type Name fastpath_tx_acce
> =================================== =========================== =================== =================== ===================================================================================
> unsigned_long:32 priv_flags read_mostly __dev_queue_xmit(tx)
> unsigned_long:1 lltx read_mostly HARD_TX_LOCK,HARD_TX_TRYLOCK,HARD_TX_UNLOCK(tx)
> -unsigned long:1 netmem_tx:1; read_mostly
> +unsigned long:2 netmem_tx:2; read_mostly
> char name[16]
> struct netdev_name_node* name_node
> struct dev_ifalias* ifalias
> diff --git a/Documentation/networking/netmem.rst b/Documentation/networking/netmem.rst
> index b63aded46337..217869d1108d 100644
> --- a/Documentation/networking/netmem.rst
> +++ b/Documentation/networking/netmem.rst
> @@ -95,4 +95,10 @@ Driver TX Requirements
> netdev@, or reach out to the maintainers and/or almasrymina@google.com for
> help adding the netmem API.
>
> -2. Driver should declare support by setting `netdev->netmem_tx = true`
> +2. Driver should declare support by setting `netdev->netmem_tx` to the
> + appropriate mode:
> +
> + - `NETMEM_TX_DMA`: for physical devices that perform DMA.
> +
> + - `NETMEM_TX_NO_DMA`: for virtual or passthrough devices that do
> + not DMA, but still support handling of netmem-backed skbs.
> diff --git a/Documentation/translations/zh_CN/networking/netmem.rst b/Documentation/translations/zh_CN/networking/netmem.rst
> index fe351a240f02..320f3eacf51b 100644
> --- a/Documentation/translations/zh_CN/networking/netmem.rst
> +++ b/Documentation/translations/zh_CN/networking/netmem.rst
> @@ -89,4 +89,9 @@ dma-mapping API 去处理。
> 使用某个还不存在的 netmem API,你可以自行添加并提交到 netdev@,也可以联系维护
> 人员或者发送邮件至 almasrymina@google.com 寻求帮助。
>
> -2. 驱动程序应通过设置 netdev->netmem_tx = true 来表明自身支持 netmem 功能。
> +2. 驱动程序应将 `netdev->netmem_tx` 设置为适当的模式:
> +
> + - `NETMEM_TX_DMA`:适用于执行 DMA 的物理设备。
> +
> + - `NETMEM_TX_NO_DMA`:适用于不执行 DMA 的虚拟或透传设备,但仍支持
> + 处理 netmem 支持的 skb。
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index 8c55874f44ca..ed9c22dc4a5a 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -17120,7 +17120,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops_unsupp;
> if (BNXT_SUPPORTS_QUEUE_API(bp))
> dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops;
> - dev->netmem_tx = true;
> + dev->netmem_tx = NETMEM_TX_DMA;
>
> rc = register_netdev(dev);
> if (rc)
> diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
> index 424d973c97f2..dd2b8f087163 100644
> --- a/drivers/net/ethernet/google/gve/gve_main.c
> +++ b/drivers/net/ethernet/google/gve/gve_main.c
> @@ -2894,7 +2894,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> goto abort_with_wq;
>
> if (!gve_is_gqi(priv) && !gve_is_qpl(priv))
> - dev->netmem_tx = true;
> + dev->netmem_tx = NETMEM_TX_DMA;
Acked-by: Harshitha Ramamurthy <hramamurthy@google.com>
>
> err = register_netdev(dev);
> if (err)
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> index 5a46870c4b74..fc49aae38807 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> @@ -5924,7 +5924,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
>
> netdev->priv_flags |= IFF_UNICAST_FLT;
>
> - netdev->netmem_tx = true;
> + netdev->netmem_tx = NETMEM_TX_DMA;
>
> netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
> mlx5e_set_xdp_feature(priv);
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> index c406a3b56b37..138e522ef9b9 100644
> --- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> +++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> @@ -752,7 +752,7 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
> netdev->netdev_ops = &fbnic_netdev_ops;
> netdev->stat_ops = &fbnic_stat_ops;
> netdev->queue_mgmt_ops = &fbnic_queue_mgmt_ops;
> - netdev->netmem_tx = true;
> + netdev->netmem_tx = NETMEM_TX_DMA;
>
> fbnic_set_ethtool_ops(netdev);
>
> diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c
> index 5e2eecc3165d..0ad6a806d7d5 100644
> --- a/drivers/net/netkit.c
> +++ b/drivers/net/netkit.c
> @@ -466,6 +466,7 @@ static void netkit_setup(struct net_device *dev)
> dev->priv_flags |= IFF_NO_QUEUE;
> dev->priv_flags |= IFF_DISABLE_NETPOLL;
> dev->lltx = true;
> + dev->netmem_tx = NETMEM_TX_NO_DMA;
>
> dev->netdev_ops = &netkit_netdev_ops;
> dev->ethtool_ops = &netkit_ethtool_ops;
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 0e1e581efc5a..11d68e75eb4f 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1788,6 +1788,12 @@ enum netdev_stat_type {
> NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */
> };
>
> +enum netmem_tx_mode {
> + NETMEM_TX_NONE, /* no netmem TX support */
> + NETMEM_TX_DMA, /* DMA-capable netmem TX (real HW) */
> + NETMEM_TX_NO_DMA, /* no DMA, e.g. passthrough for virtual devs */
> +};
> +
> enum netdev_reg_state {
> NETREG_UNINITIALIZED = 0,
> NETREG_REGISTERED, /* completed register_netdevice */
> @@ -1809,7 +1815,8 @@ enum netdev_reg_state {
> * @lltx: device supports lockless Tx. Deprecated for real HW
> * drivers. Mainly used by logical interfaces, such as
> * bonding and tunnels
> - * @netmem_tx: device support netmem_tx.
> + * @netmem_tx: device netmem TX mode (NETMEM_TX_NONE, NETMEM_TX_DMA,
> + * or NETMEM_TX_NO_DMA).
> *
> * @name: This is the first field of the "visible" part of this structure
> * (i.e. as seen by users in the "Space.c" file). It is the name
> @@ -2132,7 +2139,7 @@ struct net_device {
> struct_group(priv_flags_fast,
> unsigned long priv_flags:32;
> unsigned long lltx:1;
> - unsigned long netmem_tx:1;
> + unsigned long netmem_tx:2;
> );
> const struct net_device_ops *netdev_ops;
> const struct header_ops *header_ops;
>
> --
> 2.52.0
>
^ permalink raw reply
* [PATCH v17 11/11] Documentation: cxl: Document CXL protocol error handling
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
Add Documentation/driver-api/cxl/linux/protocol-error-handling.rst
describing the end-to-end CXL protocol error path: AER ingress, the
AER-CXL kfifo handoff, the cxl_core consumer worker, RCD/RCH special
cases, severity policy, trace events, and a source code map.
This documents the architecture introduced by the preceding patches in
this series.
This was generated by claude-opus-4.7.
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Documentation/driver-api/cxl/index.rst | 1 +
.../cxl/linux/protocol-error-handling.rst | 440 ++++++++++++++++++
2 files changed, 441 insertions(+)
create mode 100644 Documentation/driver-api/cxl/linux/protocol-error-handling.rst
diff --git a/Documentation/driver-api/cxl/index.rst b/Documentation/driver-api/cxl/index.rst
index 3dfae1d310ca..6861b2e5726a 100644
--- a/Documentation/driver-api/cxl/index.rst
+++ b/Documentation/driver-api/cxl/index.rst
@@ -42,6 +42,7 @@ that have impacts on each other. The docs here break up configurations steps.
linux/dax-driver
linux/memory-hotplug
linux/access-coordinates
+ linux/protocol-error-handling
.. toctree::
:maxdepth: 2
diff --git a/Documentation/driver-api/cxl/linux/protocol-error-handling.rst b/Documentation/driver-api/cxl/linux/protocol-error-handling.rst
new file mode 100644
index 000000000000..4d6f33f0ed31
--- /dev/null
+++ b/Documentation/driver-api/cxl/linux/protocol-error-handling.rst
@@ -0,0 +1,440 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============================
+CXL Protocol Error Handling
+==============================
+
+This document describes how the kernel detects, classifies, dispatches,
+logs, and recovers from CXL protocol errors signaled through the PCIe
+Advanced Error Reporting (AER) interface. It covers both Virtual
+Hierarchy (VH) topologies (Root Ports, Upstream/Downstream Switch
+Ports, and Endpoints) and Restricted CXL Host (RCH) topologies
+(Root Complex Event Collectors driving Restricted CXL Devices).
+
+It is intended for kernel developers maintaining or extending
+``drivers/pci/pcie/aer*.c``, ``drivers/cxl/core/ras.c``, and the
+related plumbing in ``include/linux/aer.h``.
+
+
+Background
+==========
+
+A CXL device reports protocol-layer failures (CXL.cachemem RAS) as
+PCIe AER **Internal Errors**: ``PCI_ERR_COR_INTERNAL`` for correctable
+events and ``PCI_ERR_UNC_INTN`` for uncorrectable events. From the AER
+core's point of view these look like ordinary PCIe AER messages, but
+their semantics are CXL-specific: the actual fault information lives
+in CXL RAS capability registers, not in the PCIe AER status registers.
+
+Historically, native CXL.cachemem RAS handling was implemented only
+for CXL Endpoints and for RCH Downstream Ports. CXL Root Ports,
+Upstream Switch Ports, and Downstream Switch Ports were not covered.
+This left the kernel unable to log or react to protocol errors
+signaled by switch components.
+
+The unified CXL protocol error path closes that gap by routing every
+CXL Internal Error through a single producer/consumer pipeline shared
+by all CXL device types.
+
+
+Architecture overview
+=====================
+
+CXL protocol error handling is implemented as a distinct error plane
+layered on top of the existing PCIe AER infrastructure. The two planes
+are kept separate:
+
+* The **PCIe AER plane** continues to handle native PCIe errors
+ (Receiver overflows, malformed TLPs, completion timeouts, and so
+ on). This is unchanged.
+
+* The **CXL protocol error plane** owns CXL Internal Errors. The AER
+ core forwards them to ``cxl_core`` via a dedicated kfifo; ``cxl_core``
+ then dispatches to CE/UE handlers and drives the recovery and
+ panic policy.
+
+The boundary between the two planes is ``is_cxl_error()`` in
+``drivers/pci/pcie/aer_cxl_vh.c``, which inspects ``info->is_cxl``
+(set from ``pcie_is_cxl()``) together with the PCIe device type and
+the AER status word. When ``is_cxl_error()`` returns true the event
+is enqueued into the AER-CXL kfifo; otherwise the event flows through
+``pci_aer_handle_error()`` as before.
+
+The pipeline has three layers:
+
+1. **Producer** (``aer_cxl_vh.c``, ``aer_cxl_rch.c``) - runs in AER
+ IRQ/threaded context, classifies, clears the AER CE status, and
+ enqueues ``struct cxl_proto_err_work_data``.
+2. **Queue** - the AER-CXL kfifo plus a backing ``struct work_struct``.
+3. **Consumer** (``cxl_core/ras.c``) - workqueue-context worker that
+ resolves the CXL Port topology and dispatches to CE/UE handlers.
+
+
+Topologies
+==========
+
+Two topologies are supported, and both feed the same kfifo.
+
+Virtual Hierarchy (VH)
+----------------------
+
+A standard CXL VH consists of a CXL Root Port (RP), an optional CXL
+Upstream Switch Port (USP), one or more CXL Downstream Switch Ports
+(DSPs), and CXL Endpoints (EPs) attached to the DSPs. Each component
+is a regular PCIe device with a CXL DVSEC and a CXL RAS capability,
+and it raises Internal Errors directly to the AER subsystem via the
+RP's MSI/MSI-X interrupt.
+
+The VH producer is ``cxl_forward_error()`` in
+``drivers/pci/pcie/aer_cxl_vh.c``.
+
+Restricted CXL Host (RCH)
+-------------------------
+
+In the RCH topology, a Root Complex Event Collector (RCEC) aggregates
+errors from one or more Restricted CXL Devices (RCDs) attached as
+Root Complex Integrated Endpoints. The RCEC delivers the AER
+interrupt; the AER driver iterates the RCDs beneath it.
+
+The RCH producer is ``cxl_rch_handle_error_iter()`` in
+``drivers/pci/pcie/aer_cxl_rch.c``. For each RCD it finds, it calls
+``cxl_forward_error()`` (the same producer helper used by the VH
+path), so RCH events end up in the same AER-CXL kfifo as VH events.
+
+
+End-to-end flow
+===============
+
+The diagram below shows the full path from an AER interrupt through
+producer classification, kfifo handoff, and consumer dispatch.
+
+.. code-block:: text
+
+ +-------------------------------------------------------------------------+
+ | CXL Internal Error Packet Flow |
+ | From PCIe AER Interrupt to CXL Protocol Error Handling and Logging |
+ +-------------------------------------------------------------------------+
+
+ CXL device (RP / USP / DSP / EP / RCD) raises AER Internal Error
+ (correctable PCI_ERR_COR_INTERNAL or uncorrectable PCI_ERR_UNC_INTN)
+ |
+ v
+ +-------------------------------------------------------------+
+ | PCIe Root Port AER MSI/MSI-X interrupt fires |
+ +-------------------------------------------------------------+
+ |
+ ============= drivers/pci/pcie/aer.c (AER core) =============
+ |
+ v
+ +---------------------------------+
+ | aer_irq() / aer_isr() | (top + threaded handler)
+ +---------------------------------+
+ |
+ v
+ +---------------------------------+
+ | aer_isr_one_error() |
+ | aer_isr_one_error_type() |
+ +---------------------------------+
+ |
+ v
+ +------------------------------------------+
+ | aer_get_device_error_info() |
+ | - reads PCI_ERR_COR_STATUS |
+ | - reads PCI_ERR_UNCOR_STATUS (*if RP/ |
+ | RCEC/DSP, or non-fatal severity) |
+ | - sets info->is_cxl = pcie_is_cxl(dev) |
+ +------------------------------------------+
+ |
+ v
+ +---------------------------------+
+ | handle_error_source(dev, info) |
+ +---------------------------------+
+ | |
+ | is_cxl_error() +---> pci_aer_handle_error()
+ | (CXL device + Internal) (native PCIe AER path,
+ v not covered here)
+ +-------------------------------------------------------------+
+ | Topology dispatch within AER core: |
+ | |
+ | - VH topology (RP / USP / DSP / EP) |
+ | -> drivers/pci/pcie/aer_cxl_vh.c |
+ | |
+ | - RCH topology (RCEC iterates RCDs under it) |
+ | -> drivers/pci/pcie/aer_cxl_rch.c |
+ +-------------------------------------------------------------+
+ | |
+ | VH path RCH path (RCEC AER)
+ v v
+ ============= aer_cxl_vh.c (VH ============= aer_cxl_rch.c (RCH
+ producer) ============= producer) ==========
+ | |
+ v v
+ +-----------------------------+ +-------------------------------+
+ | cxl_forward_error(pdev,info)| | cxl_rch_handle_error_iter() |
+ | - if AER_CORRECTABLE: | | - iterate each RCD pdev |
+ | clear PCI_ERR_COR_STATUS| | beneath the RCEC |
+ | - pci_dev_get(pdev) | | - call cxl_forward_error() |
+ | - build cxl_proto_err_ | | for each RCD |
+ | work_data | | (same producer helper as |
+ | { pdev, severity } | | the VH path uses) |
+ | - kfifo_in_spinlocked(...) | +-------------------------------+
+ | - schedule_work(...) | |
+ +-----------------------------+ |
+ | |
+ +-----------------+---------------------------+
+ |
+ v
+ +--------------------------+
+ | AER-CXL kfifo |
+ | (work_struct) |
+ +--------------------------+
+ |
+ v
+ ============= drivers/cxl/core/ras.c (consumer worker) =======
+ |
+ v
+ +-------------------------------------------------------------+
+ | cxl_proto_err_work_fn() (workqueue handler) |
+ | for_each_cxl_proto_err(&wd, __cxl_proto_err_work_fn) |
+ +-------------------------------------------------------------+
+ |
+ v
+ +-------------------------------------------------------------+
+ | __cxl_proto_err_work_fn(wd) |
+ | port = find_cxl_port_by_dev(&pdev->dev, &dport) |
+ | cxl_handle_proto_error(pdev, port, dport, severity) |
+ | pci_dev_put(pdev) |
+ +-------------------------------------------------------------+
+ |
+ v
+ +-------------------------------------------------------------+
+ | cxl_handle_proto_error() |
+ +-------------------------------------------------------------+
+ | |
+ pci_pcie_type == pci_pcie_type !=
+ PCI_EXP_TYPE_RC_END PCI_EXP_TYPE_RC_END
+ (RCD Endpoint) (VH: RP/USP/DSP/EP)
+ | |
+ v |
+ +-------------------------------------+ |
+ | cxl_handle_rdport_errors(pdev) | |
+ | - process RCH Downstream Port's | |
+ | RAS register block first | |
+ | - cxl_handle_cor_ras() for CE | |
+ | - cxl_handle_ras() for UE | |
+ | (log only; does NOT panic) | |
+ +-------------------------------------+ |
+ | |
+ +--------------------+-----------------------+
+ |
+ v
+ +-----------------------------+
+ | severity == AER_CORRECTABLE |
+ +-----------------------------+
+ | |
+ yes no
+ v v
+ +----------------------+ +-------------------------+
+ | cxl_handle_cor_ras() | | cxl_do_recovery() |
+ | - emit cxl_aer_ | | (described below) |
+ | correctable_ | +-------------------------+
+ | error trace |
+ | pcie_clear_device_ |
+ | status() |
+ +----------------------+
+
+ +-------------------------------+
+ | cxl_do_recovery() |
+ | if pci_dev_is_disconnected: |
+ | panic("CXL cachemem err.") |
+ | |
+ | ue = cxl_handle_ras() |
+ | -> emit |
+ | cxl_aer_uncorrectable_ |
+ | error trace event |
+ | |
+ | if (ue): |
+ | panic("CXL cachemem err.") |
+ | |
+ | pcie_clear_device_status() |
+ | pci_aer_clear_nonfatal_status|
+ | pci_aer_clear_fatal_status |
+ +-------------------------------+
+
+
+Severity policy
+===============
+
+The kernel's response to a CXL protocol error depends on the AER
+severity reported by the device and on the result of inspecting the
+CXL RAS registers.
+
+Correctable Error (CE)
+----------------------
+
+* The AER driver clears ``PCI_ERR_COR_STATUS`` in the producer
+ (``cxl_forward_error()``) before enqueue, so the device is
+ acknowledged even if the consumer drops the event.
+* The consumer's ``cxl_handle_cor_ras()`` reads and clears the CXL
+ RAS correctable status and emits a ``cxl_aer_correctable_error``
+ trace event.
+* No recovery action is taken.
+
+Uncorrectable Error (UE), non-fatal
+-----------------------------------
+
+* The producer enqueues the event without clearing the AER UCE
+ status.
+* The consumer enters ``cxl_do_recovery()``.
+* ``cxl_handle_ras()`` reads the CXL RAS uncorrectable status and
+ emits a ``cxl_aer_uncorrectable_error`` trace event.
+* If ``cxl_handle_ras()`` returns true (a CXL RAS UE bit was set),
+ the kernel panics with ``"CXL cachemem error."``. CXL.cachemem
+ traffic cannot be safely recovered in software once corruption is
+ observed; continuing risks silent data loss across all devices in
+ an interleaved HDM region.
+* If ``cxl_handle_ras()`` returns false (no CXL RAS bit set, i.e.
+ the AER UCE was a PCIe-side issue rather than a CXL.cachemem
+ issue), the AER UCE status is cleared and execution continues.
+
+Uncorrectable Error (UE), fatal
+-------------------------------
+
+Fatal severity follows the same recovery path as non-fatal in
+``cxl_do_recovery()``, with one important caveat: the AER core only
+reads ``PCI_ERR_UNCOR_STATUS`` for Root Ports, RCECs, Downstream
+Ports, or non-fatal severities (see ``aer_get_device_error_info()``
+in ``drivers/pci/pcie/aer.c``). For a fatal UE signaled by an
+upstream component, PCI config reads to the source device are
+expected to fail, so ``UNCOR_STATUS`` is never retrieved and
+``info->status`` stays zero.
+
+The practical consequence: a fatal UE on an Upstream Switch Port or
+Endpoint is **not** classified as a CXL error by ``is_cxl_error()``.
+It falls through to ``pci_aer_handle_error()`` and is processed by
+the standard AER recovery flow. Only the CXL trace events emitted by
+the AER core (``aer_event``) appear; the CXL-specific
+``cxl_aer_uncorrectable_error`` event is not emitted on this path.
+
+Disconnect during recovery
+--------------------------
+
+``cxl_do_recovery()`` checks ``pci_dev_is_disconnected(pdev)`` before
+touching the RAS registers. A device disconnecting during an
+uncorrectable error event is itself unrecoverable, particularly when
+the device backs an interleaved HDM region; in that case the kernel
+panics directly rather than returning ``~0u`` from the readl() and
+masking the cause.
+
+
+RCD/RCH special cases
+=====================
+
+RCD Endpoint flow
+-----------------
+
+When ``cxl_handle_proto_error()`` sees ``pci_pcie_type(pdev) ==
+PCI_EXP_TYPE_RC_END`` (i.e. an RCD Endpoint), it calls
+``cxl_handle_rdport_errors()`` first. This processes the RAS state
+of the RCH Downstream Port that hosts the RCD before falling through
+to the common CE/UE dispatch on the RCD Endpoint itself.
+
+The RCH Downstream Port's RAS UE is **logged only**: it emits the
+trace event but does not panic. The panic decision is taken on the
+RCD Endpoint's own RAS in ``cxl_do_recovery()``.
+
+This split mirrors the structure of an RCH topology: the RCH dport
+is functionally a CXL infrastructure component (similar to a switch
+port), while the RCD itself is the actual CXL.cachemem source whose
+corruption drives the recovery decision.
+
+RCH ingress aggregation
+-----------------------
+
+RCH errors do not arrive on a per-RCD interrupt. The RCEC is the AER
+source, and the AER driver drives ``cxl_rch_handle_error_iter()`` to
+walk each RCD beneath it and forward an event per RCD through the
+shared kfifo. From the consumer's point of view, RCH-originated
+events are indistinguishable from VH events.
+
+
+Trace events
+============
+
+Two unified trace events are emitted from ``cxl_handle_cor_ras()``
+and ``cxl_handle_ras()`` and are used by every CXL device type and
+both topologies:
+
+* ``cxl_aer_correctable_error`` - emitted when a CXL RAS CE bit is
+ set; carries the human-readable status string.
+* ``cxl_aer_uncorrectable_error`` - emitted when a CXL RAS UE bit is
+ set; carries both the current status and the first-error pointer.
+
+Common fields:
+
+* ``device=<PCI BDF>`` - the source device (always a PCI BDF, even
+ for RCH paths where the trace was historically a memdev name).
+* ``host=<bridge>`` - the parent host bridge or PCI host BDF.
+* ``serial=<u64>`` - the device serial from ``pci_get_dsn()``.
+
+The ``device`` field replaces the older ``memdev`` field that earlier
+revisions emitted on Endpoint events. Userspace consumers
+(rasdaemon's ``ras-cxl-handler.c``) need a corresponding update to
+read the new field name.
+
+
+Source code map
+===============
+
+============================================ ==============================
+File Role
+============================================ ==============================
+``drivers/pci/pcie/aer.c`` AER core; receives the IRQ,
+ builds ``aer_err_info``,
+ dispatches to either the CXL
+ path (``is_cxl_error()``) or
+ ``pci_aer_handle_error()``.
+``drivers/pci/pcie/aer_cxl_vh.c`` VH producer; provides
+ ``is_cxl_error()``,
+ ``cxl_forward_error()``, the
+ AER-CXL kfifo, and the
+ consumer registration
+ helpers.
+``drivers/pci/pcie/aer_cxl_rch.c`` RCH producer; iterates RCDs
+ under an RCEC and forwards
+ each via
+ ``cxl_forward_error()``.
+``drivers/cxl/core/ras.c`` Consumer; defines
+ ``cxl_proto_err_work_fn()``,
+ ``cxl_handle_proto_error()``,
+ ``cxl_handle_rdport_errors()``,
+ ``cxl_do_recovery()``,
+ ``cxl_handle_cor_ras()`` and
+ ``cxl_handle_ras()``.
+``include/linux/aer.h`` Public declarations:
+ ``struct cxl_proto_err_work_data``,
+ ``cxl_proto_err_fn_t``,
+ ``cxl_register_proto_err_work()``
+ and ``for_each_cxl_proto_err()``.
+============================================ ==============================
+
+
+Limitations and future work
+===========================
+
+* **USP/EP fatal UCE is not classified as CXL.** As described under
+ `Severity policy`_, the AER core never retrieves
+ ``PCI_ERR_UNCOR_STATUS`` in this scenario, so ``is_cxl_error()``
+ cannot tag the event as CXL. The event is handled by the AER path
+ only. Resolving this requires either an AER-core change to attempt
+ a config read with link-validity gating, or a separate CXL-side
+ notification mechanism for upstream-signaled fatal events.
+* **User-defined status masks** are not yet supported. All CE and UE
+ status bits are reported as they appear in the RAS register.
+* **Port traversing in cxl_do_recovery()** is not yet implemented; a
+ CXL UE today is reported and acted on at the source device only,
+ not propagated to ancestor ports.
+* The RCH producer (``aer_cxl_rch.c``) currently lives under
+ ``drivers/pci/pcie/`` for historical reasons. Moving it to
+ ``drivers/cxl/core/ras_rch.c`` is on the roadmap.
+
--
2.34.1
^ permalink raw reply related
* [PATCH v17 10/11] PCI/CXL: Mask/Unmask CXL protocol errors
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
CXL protocol errors are not enabled for all CXL devices after boot. They
must be enabled in order to process CXL protocol errors. Provide matching
teardown helpers so the masks are restored when a CXL Port or Downstream
Port goes away.
Add pci_aer_mask_internal_errors() as the symmetric counterpart to
pci_aer_unmask_internal_errors() and export both for the cxl_core module.
Introduce cxl_unmask_proto_interrupts() and cxl_mask_proto_interrupts()
in cxl_core to wrap the PCI helpers with the dev_is_pci() and
pcie_aer_is_native() gating CXL needs. Both helpers tolerate a NULL
@dev so teardown callers do not have to special-case it.
Wire cxl_unmask_proto_interrupts() into the success path of
cxl_dport_map_ras() and devm_cxl_port_ras_setup() so the unmask only
runs when the RAS register block was actually mapped. Pair each unmask
with a devm_add_action_or_reset() registration of
cxl_mask_proto_interrupts() scoped to the cxl_port device. The mask is
then restored when the cxl_port device releases its devres. This
applies to Endpoints, Upstream Switch Ports, Downstream Switch Ports,
and Root Ports.
Co-developed-by: Dan Williams <djbw@kernel.org>
Signed-off-by: Dan Williams <djbw@kernel.org>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v16->v17:
- Drop redundant cxl_mask_proto_interrupts() calls from unregister_port()
and cxl_dport_remove(); the devres action registered alongside the unmask
is the sole mask path.
- Update title
- Remove unnecessary check for aer_capabilities
- Gate cxl_unmask_proto_interrupts() on pcie_aer_is_native()
- Add pci_aer_mask_internal_errors() and cxl_mask_proto_interrupts()
- Only unmask on successful cxl_map_component_regs()
- NULL-check @dev in cxl_{un,}mask_proto_interrupts()
- Drop static and declare in core/core.h
Change in v15 -> v16:
- None
Change in v14 -> v15:
- None
Changes in v13->v14:
- Update commit title's prefix (Bjorn)
Changes in v12->v13:
- Add dev and dev_is_pci() NULL checks in cxl_unmask_proto_interrupts() (Terry)
- Add Dave Jiang's and Ben's review-by
Changes in v11->v12:
- None
---
drivers/cxl/core/core.h | 4 +++
drivers/cxl/core/ras.c | 63 ++++++++++++++++++++++++++++++++++++++---
drivers/pci/pcie/aer.c | 25 ++++++++++++++++
include/linux/aer.h | 2 ++
4 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 2c7387506dfb..ff39985d363f 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -190,6 +190,8 @@ void cxl_dport_map_rch_aer(struct cxl_dport *dport);
void cxl_disable_rch_root_ints(struct cxl_dport *dport);
void cxl_handle_rdport_errors(struct pci_dev *pdev);
void devm_cxl_dport_ras_setup(struct cxl_dport *dport);
+void cxl_unmask_proto_interrupts(struct device *dev);
+void cxl_mask_proto_interrupts(struct device *dev);
#else
static inline int cxl_ras_init(void)
{
@@ -207,6 +209,8 @@ static inline void cxl_dport_map_rch_aer(struct cxl_dport *dport) { }
static inline void cxl_disable_rch_root_ints(struct cxl_dport *dport) { }
static inline void cxl_handle_rdport_errors(struct pci_dev *pdev) { }
static inline void devm_cxl_dport_ras_setup(struct cxl_dport *dport) { }
+static inline void cxl_unmask_proto_interrupts(struct device *dev) { }
+static inline void cxl_mask_proto_interrupts(struct device *dev) { }
#endif /* CONFIG_CXL_RAS */
int cxl_gpf_port_setup(struct cxl_dport *dport);
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index a98ce0f412ad..b45e2b539b5f 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -66,16 +66,59 @@ static void cxl_cper_prot_err_work_fn(struct work_struct *work)
}
static DECLARE_WORK(cxl_cper_prot_err_work, cxl_cper_prot_err_work_fn);
+void cxl_unmask_proto_interrupts(struct device *dev)
+{
+ struct pci_dev *pdev;
+
+ if (!dev || !dev_is_pci(dev))
+ return;
+
+ pdev = to_pci_dev(dev);
+ if (!pcie_aer_is_native(pdev))
+ return;
+
+ pci_aer_unmask_internal_errors(pdev);
+}
+
+void cxl_mask_proto_interrupts(struct device *dev)
+{
+ struct pci_dev *pdev;
+
+ if (!dev || !dev_is_pci(dev))
+ return;
+
+ pdev = to_pci_dev(dev);
+ if (!pcie_aer_is_native(pdev))
+ return;
+
+ pci_aer_mask_internal_errors(pdev);
+}
+
+static void cxl_mask_proto_irqs(void *dev)
+{
+ cxl_mask_proto_interrupts(dev);
+}
+
static void cxl_dport_map_ras(struct cxl_dport *dport)
{
struct cxl_register_map *map = &dport->reg_map;
struct device *dev = dport->dport_dev;
- if (!map->component_map.ras.valid)
+ if (!map->component_map.ras.valid) {
dev_dbg(dev, "RAS registers not found\n");
- else if (cxl_map_component_regs(map, &dport->regs.component,
- BIT(CXL_CM_CAP_CAP_ID_RAS)))
+ return;
+ }
+
+ if (cxl_map_component_regs(map, &dport->regs.component,
+ BIT(CXL_CM_CAP_CAP_ID_RAS))) {
dev_dbg(dev, "Failed to map RAS capability.\n");
+ return;
+ }
+
+ cxl_unmask_proto_interrupts(dev);
+ if (devm_add_action_or_reset(dport_to_host(dport),
+ cxl_mask_proto_irqs, dev))
+ dev_warn(dev, "failed to register CXL proto-irq mask cleanup\n");
}
/**
@@ -109,6 +152,7 @@ EXPORT_SYMBOL_NS_GPL(devm_cxl_dport_rch_ras_setup, "CXL");
void devm_cxl_port_ras_setup(struct cxl_port *port)
{
struct cxl_register_map *map = &port->reg_map;
+ struct device *dev;
if (!map->component_map.ras.valid) {
dev_dbg(&port->dev, "RAS registers not found\n");
@@ -117,8 +161,19 @@ void devm_cxl_port_ras_setup(struct cxl_port *port)
map->host = &port->dev;
if (cxl_map_component_regs(map, &port->regs,
- BIT(CXL_CM_CAP_CAP_ID_RAS)))
+ BIT(CXL_CM_CAP_CAP_ID_RAS))) {
dev_dbg(&port->dev, "Failed to map RAS capability\n");
+ return;
+ }
+
+ dev = is_cxl_endpoint(port) ? port->uport_dev->parent : port->uport_dev;
+ if (!dev_is_pci(dev))
+ return;
+
+ cxl_unmask_proto_interrupts(dev);
+ if (devm_add_action_or_reset(&port->dev, cxl_mask_proto_irqs, dev))
+ dev_warn(&port->dev,
+ "Failed to register CXL proto-irq mask cleanup\n");
}
EXPORT_SYMBOL_NS_GPL(devm_cxl_port_ras_setup, "CXL");
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index b9c6c7b97217..eaa36fe0eb31 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1151,6 +1151,31 @@ void pci_aer_unmask_internal_errors(struct pci_dev *dev)
*/
EXPORT_SYMBOL_FOR_MODULES(pci_aer_unmask_internal_errors, "cxl_core");
+/**
+ * pci_aer_mask_internal_errors - mask internal errors
+ * @dev: pointer to the pci_dev data structure
+ *
+ * Mask internal errors in the Uncorrectable and Correctable Error
+ * Mask registers.
+ *
+ * Note: AER must be enabled and supported by the device which must be
+ * checked in advance, e.g. with pcie_aer_is_native().
+ */
+void pci_aer_mask_internal_errors(struct pci_dev *dev)
+{
+ int aer = dev->aer_cap;
+ u32 mask;
+
+ pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &mask);
+ mask |= PCI_ERR_UNC_INTN;
+ pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, mask);
+
+ pci_read_config_dword(dev, aer + PCI_ERR_COR_MASK, &mask);
+ mask |= PCI_ERR_COR_INTERNAL;
+ pci_write_config_dword(dev, aer + PCI_ERR_COR_MASK, mask);
+}
+EXPORT_SYMBOL_FOR_MODULES(pci_aer_mask_internal_errors, "cxl_core");
+
/**
* pci_aer_handle_error - handle logging error into an event log
* @dev: pointer to pci_dev data structure of error source device
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 979ed2f9fd38..c52db62d4c7e 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -71,6 +71,7 @@ int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
void pci_aer_clear_fatal_status(struct pci_dev *dev);
int pcie_aer_is_native(struct pci_dev *dev);
void pci_aer_unmask_internal_errors(struct pci_dev *dev);
+void pci_aer_mask_internal_errors(struct pci_dev *dev);
#else
static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{
@@ -79,6 +80,7 @@ static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
static inline void pci_aer_unmask_internal_errors(struct pci_dev *dev) { }
+static inline void pci_aer_mask_internal_errors(struct pci_dev *dev) { }
#endif
#ifdef CONFIG_CXL_RAS
--
2.34.1
^ permalink raw reply related
* [PATCH v17 09/11] cxl: Update Endpoint AER uncorrectable handler
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
The CXL cxl_core driver now implements protocol RAS support. PCI
uncorrectable (UCE) protocol errors, however, continue to be reported via
the AER capability and must still be handled by a PCI error recovery callback.
UCE handling is required to provide direction for recovery.
Replace the existing cxl_error_detected() callback in cxl/pci.c with a new
cxl_pci_error_detected() implementation that handles uncorrectable AER PCI
protocol errors.
The handler decides solely based on the pci_channel_state_t parameter and
does not access PCIe AER capability registers from .error_detected, matching
the pattern used by other drivers including the NVMe and ixgbe drivers.
CXL.cachemem-corrupting protocol errors are routed separately through the
AER-CXL kfifo to cxl_handle_proto_error(), so cxl_pci does not need to
second-guess the AER core's classification.
claude-opus-4.7 was used for research on PCI error state transitions and
requirements.
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v16->v17:
- Rename pci_error_handlers struct instance to cxl_pci_error_handlers to
avoid shadowing the struct type tag.
- Restore scoped_guard(device) and dev->driver check around AER read.
- NULL-check find_cxl_port_by_dev() before deref of port->uport_dev.
- Updated commit message. (Terry)
- Add scope cleanup for port variable in cxl_pci_error_detected() (Terry)
- Drop cxl_uncor_aer_present(), rely on AER state
Changes in v15->v16:
- Update commit message (DaveJ)
- s/cxl_handle_aer()/cxl_uncor_aer_present()/g (Jonathan)
- cxl_uncor_aer_present(): Leave original result calculation based on
if a UCE is present and the provided state (Terry)
- Add call to pci_print_aer(). AER fails to log because is upstream
link (Terry)
Changes in v14->v15:
- Update commit message and title. Added Bjorn's ack.
- Move CE and UCE handling logic here
Changes in v13->v14:
- Add Dave Jiang's review-by
- Update commit message & headline (Bjorn)
- Refactor cxl_port_error_detected()/cxl_port_cor_error_detected() to
one line (Jonathan)
- Remove cxl_walk_port() (Dan)
- Remove cxl_pci_drv_bound(). Check for 'is_cxl' parent port is
sufficient (Dan)
- Remove device_lock_if()
- Combined CE and UCE here (Terry)
Changes in v12->v13:
- Move get_pci_cxl_host_dev() and cxl_handle_proto_error() to Dequeue
patch (Terry)
- Remove EP case in cxl_get_ras_base(), not used. (Terry)
- Remove check for dport->dport_dev (Dave)
- Remove whitespace (Terry)
Changes in v11->v12:
- Add call to cxl_pci_drv_bound() in cxl_handle_proto_error() and
pci_to_cxl_dev()
- Change cxl_error_detected() -> cxl_cor_error_detected()
- Remove NULL variable assignments
- Replace bus_find_device() with find_cxl_port_by_uport() for upstream
port searches.
Changes in v10->v11:
- None
---
drivers/cxl/core/ras.c | 43 ++++++++++++++++--------------------------
drivers/cxl/cxlpci.h | 8 ++++----
drivers/cxl/pci.c | 6 +++---
3 files changed, 23 insertions(+), 34 deletions(-)
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 5cc4087c2807..a98ce0f412ad 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -253,38 +253,27 @@ bool cxl_handle_ras(struct device *dev, u64 serial, void __iomem *ras_base)
return true;
}
-pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
{
- struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
- struct cxl_memdev *cxlmd = cxlds->cxlmd;
- struct device *dev = &cxlmd->dev;
- bool ue;
+ struct cxl_dport *dport;
+ struct cxl_port *port __free(put_cxl_port) =
+ find_cxl_port_by_dev(&pdev->dev, &dport);
+ struct cxl_memdev *cxlmd;
+ struct device *dev;
- scoped_guard(device, dev) {
- if (!dev->driver) {
- dev_warn(&pdev->dev,
- "%s: memdev disabled, abort error handling\n",
- dev_name(dev));
- return PCI_ERS_RESULT_DISCONNECT;
- }
+ if (!port)
+ return PCI_ERS_RESULT_DISCONNECT;
- /*
- * A frozen channel indicates an impending reset which is fatal to
- * CXL.mem operation, and will likely crash the system. On the off
- * chance the situation is recoverable dump the status of the RAS
- * capability registers and bounce the active state of the memdev.
- */
- ue = cxl_handle_ras(&cxlds->cxlmd->dev, pci_get_dsn(pdev),
- cxlmd->endpoint->regs.ras);
- }
+ cxlmd = to_cxl_memdev(port->uport_dev);
+ dev = &cxlmd->dev;
switch (state) {
case pci_channel_io_normal:
- if (ue) {
- device_release_driver(dev);
- return PCI_ERS_RESULT_NEED_RESET;
- }
+ /*
+ * Non-fatal CXL protocol errors are handled asynchronously
+ * by the AER-CXL kfifo worker (cxl_proto_err_work_fn).
+ */
return PCI_ERS_RESULT_CAN_RECOVER;
case pci_channel_io_frozen:
dev_warn(&pdev->dev,
@@ -299,7 +288,7 @@ pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
}
return PCI_ERS_RESULT_NEED_RESET;
}
-EXPORT_SYMBOL_NS_GPL(cxl_error_detected, "CXL");
+EXPORT_SYMBOL_NS_GPL(cxl_pci_error_detected, "CXL");
static void cxl_handle_proto_error(struct pci_dev *pdev, struct cxl_port *port,
struct cxl_dport *dport, int severity)
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index 06c46adcf0f6..8aeb80a4e573 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -89,13 +89,13 @@ struct cxl_dev_state;
void read_cdat_data(struct cxl_port *port);
#ifdef CONFIG_CXL_RAS
-pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state);
+pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state);
void devm_cxl_dport_rch_ras_setup(struct cxl_dport *dport);
void devm_cxl_port_ras_setup(struct cxl_port *port);
#else
-static inline pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+static inline pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
{
return PCI_ERS_RESULT_NONE;
}
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 5eb64ced0de5..6459f94f8fa8 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1000,8 +1000,8 @@ static void cxl_reset_done(struct pci_dev *pdev)
}
}
-static const struct pci_error_handlers cxl_error_handlers = {
- .error_detected = cxl_error_detected,
+static const struct pci_error_handlers cxl_pci_error_handlers = {
+ .error_detected = cxl_pci_error_detected,
.slot_reset = cxl_slot_reset,
.resume = cxl_error_resume,
.reset_done = cxl_reset_done,
@@ -1011,7 +1011,7 @@ static struct pci_driver cxl_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = cxl_mem_pci_tbl,
.probe = cxl_pci_probe,
- .err_handler = &cxl_error_handlers,
+ .err_handler = &cxl_pci_error_handlers,
.dev_groups = cxl_rcd_groups,
.driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
--
2.34.1
^ permalink raw reply related
* [PATCH v17 08/11] cxl: Remove Endpoint AER correctable handler
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
CXL drivers no longer need their own correctable PCI AER handler. The
PCIe AER correctable status is logged and cleared by the AER driver,
and CXL RAS correctable status is now logged and cleared via the new
common CXL protocol error flow: cxl_handle_proto_error() invokes
cxl_handle_cor_ras() for VH Endpoints, and dispatches to
cxl_handle_rdport_errors() for RCDs (which calls cxl_handle_cor_ras()
with the RCH dport's RAS register block). Both paths are reached via
the AER-CXL kfifo, so the .cor_error_detected callback in the CXL PCI
driver is redundant.
Remove cxl_cor_error_detected() and drop the .cor_error_detected entry
from cxl_pci's pci_error_handlers.
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v16->v17:
- Update commit message
- Add Reviewed-by from Jonathan and DaveJ
Changes in v15->v16:
- None
Changes in v14->v15:
- Remove cxl_pci_cor_error_detected(). Is not needed. AER is logged
in the AER driver. (Dan)
- Update commit message (Terry)
Changes in v13->v14:
- New commit
- Change cxl_cor_error_detected() parameter to &pdev->dev device from
memdev device. (Terry)
- Updated commit message (Terry)
---
drivers/cxl/core/ras.c | 20 --------------------
drivers/cxl/cxlpci.h | 3 ---
drivers/cxl/pci.c | 1 -
3 files changed, 24 deletions(-)
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 1f1dd20623f6..5cc4087c2807 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -253,26 +253,6 @@ bool cxl_handle_ras(struct device *dev, u64 serial, void __iomem *ras_base)
return true;
}
-void cxl_cor_error_detected(struct pci_dev *pdev)
-{
- struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
- struct cxl_memdev *cxlmd = cxlds->cxlmd;
- struct device *dev = &cxlds->cxlmd->dev;
-
- scoped_guard(device, dev) {
- if (!dev->driver) {
- dev_warn(&pdev->dev,
- "%s: memdev disabled, abort error handling\n",
- dev_name(dev));
- return;
- }
-
- cxl_handle_cor_ras(&cxlds->cxlmd->dev, pci_get_dsn(pdev),
- cxlmd->endpoint->regs.ras);
- }
-}
-EXPORT_SYMBOL_NS_GPL(cxl_cor_error_detected, "CXL");
-
pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
index b826eb53cf7b..06c46adcf0f6 100644
--- a/drivers/cxl/cxlpci.h
+++ b/drivers/cxl/cxlpci.h
@@ -89,14 +89,11 @@ struct cxl_dev_state;
void read_cdat_data(struct cxl_port *port);
#ifdef CONFIG_CXL_RAS
-void cxl_cor_error_detected(struct pci_dev *pdev);
pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
pci_channel_state_t state);
void devm_cxl_dport_rch_ras_setup(struct cxl_dport *dport);
void devm_cxl_port_ras_setup(struct cxl_port *port);
#else
-static inline void cxl_cor_error_detected(struct pci_dev *pdev) { }
-
static inline pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index bace662dc988..5eb64ced0de5 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1004,7 +1004,6 @@ static const struct pci_error_handlers cxl_error_handlers = {
.error_detected = cxl_error_detected,
.slot_reset = cxl_slot_reset,
.resume = cxl_error_resume,
- .cor_error_detected = cxl_cor_error_detected,
.reset_done = cxl_reset_done,
};
--
2.34.1
^ permalink raw reply related
* [PATCH v17 07/11] PCI/CXL: Add RCH support to CXL handlers
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
Restricted CXL Host (RCH) error handling is a separate path from the
new CXL Port error handling flow. Fold RCH error handling into the
Port flow so both share a common entry point.
Update cxl_rch_handle_error_iter() to forward RCH protocol errors
through the AER-CXL kfifo.
Update cxl_handle_proto_error() to dispatch RCH errors via
cxl_handle_rdport_errors(). cxl_handle_rdport_errors() handles both
correctable and uncorrectable RCH protocol errors.
Behavior change: an RCD uncorrectable CXL RAS error now panics via
cxl_do_recovery(). Before this patch the RCH path returned
PCI_ERS_RESULT_NEED_RESET via cxl_pci's err_handler. After this patch
the same condition panics. This matches the panic policy added in the
common CXL Port protocol error flow. CXL.cachemem traffic cannot be
safely recovered from an uncorrectable protocol error in software.
Change cxl_handle_rdport_errors() to take a PCI device instead of a
CXL device state, matching the new caller context. The error trace events
emitted from this path now report device=<PCI BDF> instead of device=<memN>,
matching the rest of the unified CXL trace events. Userspace consumers keyed
off the memdev name need to map the PCI BDF back to a memdev.
Include the RCD Endpoint serial number in RCH log messages so the RCH
can be associated with its RCD.
Remove the cxlds->rcd check from cxl_cor_error_detected() and
cxl_error_detected(). RCH errors are now forwarded by
cxl_rch_handle_error_iter() through the AER-CXL kfifo to
cxl_handle_proto_error(), so cxl_pci's err_handler no longer sees
them.
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v16->v17:
- Drop now-dead cxlds->rcd branches from cxl_{cor_,}error_detected().
- Drop duplicate subject line from commit body.
- Document panic-on-uncorrectable behavior change for RCD path.
- Document trace event device-name change (memN -> PCI BDF) for RCH path.
- Rewrite cxl_handle_proto_error() RC_END comment to clarify RCD/RCH shared
interrupt relationship
- Rewrite commit message
Changes in v16:
- New commit
---
drivers/cxl/core/core.h | 4 ++--
drivers/cxl/core/ras.c | 14 +++++++++-----
drivers/cxl/core/ras_rch.c | 8 +++-----
drivers/pci/pcie/aer_cxl_rch.c | 17 +----------------
4 files changed, 15 insertions(+), 28 deletions(-)
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index bc36cd1575a4..2c7387506dfb 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -188,7 +188,7 @@ void cxl_handle_cor_ras(struct device *dev, u64 serial,
void __iomem *ras_base);
void cxl_dport_map_rch_aer(struct cxl_dport *dport);
void cxl_disable_rch_root_ints(struct cxl_dport *dport);
-void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds);
+void cxl_handle_rdport_errors(struct pci_dev *pdev);
void devm_cxl_dport_ras_setup(struct cxl_dport *dport);
#else
static inline int cxl_ras_init(void)
@@ -205,7 +205,7 @@ static inline void cxl_handle_cor_ras(struct device *dev, u64 serial,
void __iomem *ras_base) { }
static inline void cxl_dport_map_rch_aer(struct cxl_dport *dport) { }
static inline void cxl_disable_rch_root_ints(struct cxl_dport *dport) { }
-static inline void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds) { }
+static inline void cxl_handle_rdport_errors(struct pci_dev *pdev) { }
static inline void devm_cxl_dport_ras_setup(struct cxl_dport *dport) { }
#endif /* CONFIG_CXL_RAS */
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 0a552d5a236e..1f1dd20623f6 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -267,9 +267,6 @@ void cxl_cor_error_detected(struct pci_dev *pdev)
return;
}
- if (cxlds->rcd)
- cxl_handle_rdport_errors(cxlds);
-
cxl_handle_cor_ras(&cxlds->cxlmd->dev, pci_get_dsn(pdev),
cxlmd->endpoint->regs.ras);
}
@@ -292,8 +289,6 @@ pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_DISCONNECT;
}
- if (cxlds->rcd)
- cxl_handle_rdport_errors(cxlds);
/*
* A frozen channel indicates an impending reset which is fatal to
* CXL.mem operation, and will likely crash the system. On the off
@@ -329,6 +324,15 @@ EXPORT_SYMBOL_NS_GPL(cxl_error_detected, "CXL");
static void cxl_handle_proto_error(struct pci_dev *pdev, struct cxl_port *port,
struct cxl_dport *dport, int severity)
{
+ /*
+ * An RC_END device is an RCD (Restricted CXL Device). Its AER
+ * interrupt is shared with the RCH Downstream Port, so handle RCH
+ * Downstream Port protocol errors first before processing the RCD's
+ * own errors. See CXL spec r3.1 s12.2.
+ */
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END)
+ cxl_handle_rdport_errors(pdev);
+
if (severity == AER_CORRECTABLE) {
cxl_handle_cor_ras(&pdev->dev, pci_get_dsn(pdev),
to_ras_base(port, dport));
diff --git a/drivers/cxl/core/ras_rch.c b/drivers/cxl/core/ras_rch.c
index 61835fbafc0f..cbd02cabefbc 100644
--- a/drivers/cxl/core/ras_rch.c
+++ b/drivers/cxl/core/ras_rch.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2025 AMD Corporation. All rights reserved. */
-#include <linux/types.h>
#include <linux/aer.h>
#include "cxl.h"
#include "core.h"
@@ -95,9 +94,8 @@ static bool cxl_rch_get_aer_severity(struct aer_capability_regs *aer_regs,
return false;
}
-void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds)
+void cxl_handle_rdport_errors(struct pci_dev *pdev)
{
- struct pci_dev *pdev = to_pci_dev(cxlds->dev);
struct aer_capability_regs aer_regs;
struct cxl_dport *dport;
int severity;
@@ -115,9 +113,9 @@ void cxl_handle_rdport_errors(struct cxl_dev_state *cxlds)
pci_print_aer(pdev, severity, &aer_regs);
if (severity == AER_CORRECTABLE)
- cxl_handle_cor_ras(&cxlds->cxlmd->dev, pci_get_dsn(pdev),
+ cxl_handle_cor_ras(&pdev->dev, pci_get_dsn(pdev),
dport->regs.ras);
else
- cxl_handle_ras(&cxlds->cxlmd->dev, pci_get_dsn(pdev),
+ cxl_handle_ras(&pdev->dev, pci_get_dsn(pdev),
dport->regs.ras);
}
diff --git a/drivers/pci/pcie/aer_cxl_rch.c b/drivers/pci/pcie/aer_cxl_rch.c
index e471eefec9c4..83142eac0cab 100644
--- a/drivers/pci/pcie/aer_cxl_rch.c
+++ b/drivers/pci/pcie/aer_cxl_rch.c
@@ -37,26 +37,11 @@ static bool cxl_error_is_native(struct pci_dev *dev)
static int cxl_rch_handle_error_iter(struct pci_dev *dev, void *data)
{
struct aer_err_info *info = (struct aer_err_info *)data;
- const struct pci_error_handlers *err_handler;
if (!is_cxl_mem_dev(dev) || !cxl_error_is_native(dev))
return 0;
- guard(device)(&dev->dev);
-
- err_handler = dev->driver ? dev->driver->err_handler : NULL;
- if (!err_handler)
- return 0;
-
- if (info->severity == AER_CORRECTABLE) {
- if (err_handler->cor_error_detected)
- err_handler->cor_error_detected(dev);
- } else if (err_handler->error_detected) {
- if (info->severity == AER_NONFATAL)
- err_handler->error_detected(dev, pci_channel_io_normal);
- else if (info->severity == AER_FATAL)
- err_handler->error_detected(dev, pci_channel_io_frozen);
- }
+ cxl_forward_error(dev, info);
return 0;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v17 06/11] PCI: Establish common CXL Port protocol error flow
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
Add CXL Port protocol error handling callbacks to unify detection,
logging, and recovery across CXL Ports and Endpoints. Establish a
common flow for correctable and uncorrectable CXL protocol errors.
RCH Downstream Port error handling is added in a following patch.
Add cxl_handle_proto_error() to dispatch correctable and uncorrectable
errors through the CXL RAS helpers. Add cxl_do_recovery() to coordinate
uncorrectable recovery. Panic via panic() on any uncorrectable CXL RAS
error. CXL.cachemem traffic cannot be safely recovered from an
uncorrectable protocol error in software, so panic regardless of the
AER severity reported. Gate error handling on the port driver being
bound to avoid processing errors on disabled devices.
Panic explicitly on pci_dev_is_disconnected() before accessing the RAS
registers. A CXL device disconnecting during an uncorrectable error event
is itself unrecoverable, particularly for devices in interleaved HDM
regions. Relying on the status readl() returning ~0u to trip the existing
panic path leaves the cause ambiguous.
The panic policy applies to the RAS register block of the device whose
error triggered the recovery: Root/Downstream Port RAS for VH Ports,
Endpoint Port RAS for VH Endpoints and RCDs. Upstream RCH Downstream
Port RAS UEs handled via cxl_handle_rdport_errors() are logged only, as
before this series. Only the RCD Endpoint's own RAS UE drives the panic.
Add to_ras_base() to centralize the RAS base lookup. It selects
dport->regs.ras for Root/Downstream Ports and port->regs.ras for
Upstream Ports and Endpoints.
Export pcie_clear_device_status() and pci_aer_clear_fatal_status() so
cxl_core can clear PCIe/AER state during recovery.
Wire the AER core to the kfifo in this commit by adding the
is_cxl_error() switch in handle_error_source() alongside the consumer
registration. This way the producer and consumer go live in the same
commit, so CXL errors are not silently dropped during bisect.
The correctable AER status is cleared by the producer in
cxl_forward_error().
Co-developed-by: Dan Williams <djbw@kernel.org>
Signed-off-by: Dan Williams <djbw@kernel.org>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
---
Changes in v16->v17:
- get_cxl_port() -> find_cxl_port_by_dev()
- Simplified find_cxl_port_by_dev()
- Replace and remove cxl_serial_number() w/ pci_get_dsn()
- cxl_get_ras_base() -> to_ras_base()
- Drop dependency on PCI_ERS_RESULT_PANIC; cxl_do_recovery() panics
directly. (PANIC enum patch dropped from series.)
- Clarify panic semantics: panic on any uncorrectable CXL RAS error, not
only AER-FATAL severities.
- Drop the redundant PCI_ERR_COR_STATUS RMW in cxl_handle_proto_error();
cxl_forward_error() already acks the correctable AER status.
- Add is_cxl_error() switch in handle_error_source() here, paired with the
kfifo consumer registration, to keep each commit bisect-safe.
- Drop pcie_aer_is_native() guard in cxl_do_recovery() (always native).
- Swap order with the "Limit" patch for bisectability w/ cxl_ras_exit()
- Reword for "any uncorrectable" CXL RAS error panics.
- Restore log messages for port-not-found and port-unbound cases.
- Whitespace cleanup (Jonathan)
- Update to get_cxl_port() documentation (Terry)
- Fix __cxl_proto_err_work_fn() to return 0 for transient errors.
- Drop !port check in cxl_do_recovery(), caller already validated
- Fix kerneldoc @pdev -> @dev in find_cxl_port_by_dev()
- Fix missing space in pr_err_ratelimited()
- Add disconnect check before access
- Made pcie_clear_device_status() and pci_aer_clear_fatal_status()
EXPORT_SYMBOL_FOR_MODULES("cxl_core") (Dan)
- Move find_cxl_port_by_dport() and find_cxl_port_by_uport()
de-staticisation and core.h declarations from the rename patch to
here, where the first cross-file callers in find_cxl_port_by_dev()
land.
Changes in v15->v16:
- get_ras_base(), initialize dport to NULL (Jonathan)
- Remove guard(device)(&cxlmd->dev) (Jonathan)
- Fix dev_warns() (Jonathan)
- Remove comment in cxl_port_error_detected() (Dan)
- Update switch-case brackets to follow clang-format (Dan)
- Add PCI_EXP_TYPE_RC_END for cxl_get_ras_base() (Terry)
- Add NULL port check in cxl_serial_number() (Terry)
Changes in v14->v15:
- Update commit message and title. Added Bjorn's ack.
- Move CE and UCE handling logic here
Changes in v13->v14:
- Add Dave Jiang's review-by
- Update commit message & headline (Bjorn)
- Refactor cxl_port_error_detected()/cxl_port_cor_error_detected() to
one line (Jonathan)
- Remove cxl_walk_port() (Dan)
- Remove cxl_pci_drv_bound(). Check for 'is_cxl' parent port is
sufficient (Dan)
- Remove device_lock_if()
- Combined CE and UCE here (Terry)
Changes in v12->v13:
- Move get_pci_cxl_host_dev() and cxl_handle_proto_error() to Dequeue
patch (Terry)
- Remove EP case in cxl_get_ras_base(), not used. (Terry)
- Remove check for dport->dport_dev (Dave)
- Remove whitespace (Terry)
Changes in v11->v12:
- Add call to cxl_pci_drv_bound() in cxl_handle_proto_error() and
pci_to_cxl_dev()
- Change cxl_error_detected() -> cxl_cor_error_detected()
- Remove NULL variable assignments
- Replace bus_find_device() with find_cxl_port_by_uport() for upstream
port searches.
Changes in v10->v11:
- None
---
drivers/cxl/core/core.h | 3 +
drivers/cxl/core/port.c | 6 +-
drivers/cxl/core/ras.c | 139 +++++++++++++++++++++++++++++++---
drivers/pci/pci.c | 1 +
drivers/pci/pci.h | 2 -
drivers/pci/pcie/aer.c | 6 +-
drivers/pci/pcie/aer_cxl_vh.c | 9 ++-
include/linux/aer.h | 2 +
include/linux/pci.h | 2 +
9 files changed, 152 insertions(+), 18 deletions(-)
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index 132ac9c1ebf4..bc36cd1575a4 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -210,6 +210,9 @@ static inline void devm_cxl_dport_ras_setup(struct cxl_dport *dport) { }
#endif /* CONFIG_CXL_RAS */
int cxl_gpf_port_setup(struct cxl_dport *dport);
+struct cxl_port *find_cxl_port_by_dport(struct device *dport_dev,
+ struct cxl_dport **dport);
+struct cxl_port *find_cxl_port_by_uport(struct device *uport_dev);
struct cxl_hdm;
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index b35a9016fc81..bf417a6aeade 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1398,8 +1398,8 @@ static struct cxl_port *__find_cxl_port_by_dport(struct cxl_find_port_ctx *ctx)
* Return a 'struct cxl_port' with an elevated reference if found. Use
* __free(put_cxl_port) to release.
*/
-static struct cxl_port *find_cxl_port_by_dport(struct device *dport_dev,
- struct cxl_dport **dport)
+struct cxl_port *find_cxl_port_by_dport(struct device *dport_dev,
+ struct cxl_dport **dport)
{
struct cxl_find_port_ctx ctx = {
.dport_dev = dport_dev,
@@ -1594,7 +1594,7 @@ static int match_port_by_uport(struct device *dev, const void *data)
* Function takes a device reference on the port device. Caller should do a
* put_device() when done.
*/
-static struct cxl_port *find_cxl_port_by_uport(struct device *uport_dev)
+struct cxl_port *find_cxl_port_by_uport(struct device *uport_dev)
{
struct device *dev;
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 9193dac4e507..0a552d5a236e 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -66,17 +66,6 @@ static void cxl_cper_prot_err_work_fn(struct work_struct *work)
}
static DECLARE_WORK(cxl_cper_prot_err_work, cxl_cper_prot_err_work_fn);
-int cxl_ras_init(void)
-{
- cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
- return 0;
-}
-
-void cxl_ras_exit(void)
-{
- cxl_cper_unregister_prot_err_work();
-}
-
static void cxl_dport_map_ras(struct cxl_dport *dport)
{
struct cxl_register_map *map = &dport->reg_map;
@@ -133,6 +122,67 @@ void devm_cxl_port_ras_setup(struct cxl_port *port)
}
EXPORT_SYMBOL_NS_GPL(devm_cxl_port_ras_setup, "CXL");
+/**
+ * find_cxl_port_by_dev - Use @dev as hint to do a _by_dport or _by_uport lookup
+ * @dev: generic device that may either be a companion of port or target dport
+ * @dport: output parameter; set to the matched dport for dport-class
+ * lookups (Root Port, Downstream Port), NULL otherwise.
+ *
+ * Return a 'struct cxl_port' with an elevated reference if found. Use
+ * __free(put_cxl_port) to release.
+ */
+static struct cxl_port *find_cxl_port_by_dev(struct device *dev, struct cxl_dport **dport)
+{
+ struct pci_dev *pdev;
+
+ *dport = NULL;
+ if (!dev_is_pci(dev))
+ return NULL;
+
+ pdev = to_pci_dev(dev);
+
+ switch (pci_pcie_type(pdev)) {
+ case PCI_EXP_TYPE_ROOT_PORT:
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ return find_cxl_port_by_dport(dev, dport);
+ case PCI_EXP_TYPE_UPSTREAM:
+ case PCI_EXP_TYPE_ENDPOINT:
+ case PCI_EXP_TYPE_RC_END:
+ return find_cxl_port_by_uport(dev);
+ }
+
+ return NULL;
+}
+
+static void __iomem *to_ras_base(struct cxl_port *port, struct cxl_dport *dport)
+{
+ if (!port)
+ return NULL;
+
+ if (dport)
+ return dport->regs.ras;
+
+ return port->regs.ras;
+}
+
+static void cxl_do_recovery(struct pci_dev *pdev, struct cxl_port *port, struct cxl_dport *dport)
+{
+ struct device *dev = &pdev->dev;
+ bool ue;
+
+ if (pci_dev_is_disconnected(pdev))
+ panic("CXL cachemem error: device disconnected during UE recovery");
+
+ ue = cxl_handle_ras(dev, pci_get_dsn(pdev),
+ to_ras_base(port, dport));
+ if (ue)
+ panic("CXL cachemem error.");
+
+ pcie_clear_device_status(pdev);
+ pci_aer_clear_nonfatal_status(pdev);
+ pci_aer_clear_fatal_status(pdev);
+}
+
void cxl_handle_cor_ras(struct device *dev, u64 serial, void __iomem *ras_base)
{
void __iomem *addr;
@@ -275,3 +325,70 @@ pci_ers_result_t cxl_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_NEED_RESET;
}
EXPORT_SYMBOL_NS_GPL(cxl_error_detected, "CXL");
+
+static void cxl_handle_proto_error(struct pci_dev *pdev, struct cxl_port *port,
+ struct cxl_dport *dport, int severity)
+{
+ if (severity == AER_CORRECTABLE) {
+ cxl_handle_cor_ras(&pdev->dev, pci_get_dsn(pdev),
+ to_ras_base(port, dport));
+ pcie_clear_device_status(pdev);
+ } else {
+ cxl_do_recovery(pdev, port, dport);
+ }
+}
+
+static int __cxl_proto_err_work_fn(struct cxl_proto_err_work_data *wd)
+{
+ struct cxl_dport *dport;
+ struct cxl_port *port __free(put_cxl_port) =
+ find_cxl_port_by_dev(&wd->pdev->dev, &dport);
+
+ if (!port) {
+ dev_err_ratelimited(&wd->pdev->dev,
+ "Failed to find parent port device in CXL topology\n");
+ return 0;
+ }
+
+ /*
+ * Hold the port device lock and verify a driver is bound before
+ * handling errors. Protects against NULL deref if an error is
+ * dispatched before probe completion or after driver removal.
+ */
+ guard(device)(&port->dev);
+ if (!port->dev.driver) {
+ dev_err_ratelimited(&port->dev,
+ "Port device is unbound, abort error handling\n");
+ return 0;
+ }
+
+ cxl_handle_proto_error(wd->pdev, port, dport, wd->severity);
+
+ return 0;
+}
+
+static void cxl_proto_err_work_fn(struct work_struct *work)
+{
+ struct cxl_proto_err_work_data wd;
+ int rc;
+
+ rc = for_each_cxl_proto_err(&wd, __cxl_proto_err_work_fn);
+ if (rc)
+ pr_err_ratelimited("Failed to handle the CXL error (%d)\n", rc);
+}
+
+static DECLARE_WORK(cxl_proto_err_work, cxl_proto_err_work_fn);
+
+int cxl_ras_init(void)
+{
+ cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
+ cxl_register_proto_err_work(&cxl_proto_err_work);
+
+ return 0;
+}
+
+void cxl_ras_exit(void)
+{
+ cxl_cper_unregister_prot_err_work();
+ cxl_unregister_proto_err_work();
+}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8f7cfcc00090..e4b225dd6075 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2245,6 +2245,7 @@ void pcie_clear_device_status(struct pci_dev *dev)
PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED |
PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_URD);
}
+EXPORT_SYMBOL_FOR_MODULES(pcie_clear_device_status, "cxl_core");
#endif
/**
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4a14f88e543a..29e588f5289e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -265,7 +265,6 @@ void pci_refresh_power_state(struct pci_dev *dev);
int pci_power_up(struct pci_dev *dev);
void pci_disable_enabled_device(struct pci_dev *dev);
int pci_finish_runtime_suspend(struct pci_dev *dev);
-void pcie_clear_device_status(struct pci_dev *dev);
void pcie_clear_root_pme_status(struct pci_dev *dev);
bool pci_check_pme_status(struct pci_dev *dev);
void pci_pme_wakeup_bus(struct pci_bus *bus);
@@ -1296,7 +1295,6 @@ void pci_restore_aer_state(struct pci_dev *dev);
static inline void pci_no_aer(void) { }
static inline void pci_aer_init(struct pci_dev *d) { }
static inline void pci_aer_exit(struct pci_dev *d) { }
-static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
static inline int pci_aer_clear_status(struct pci_dev *dev) { return -EINVAL; }
static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL; }
static inline void pci_save_aer_state(struct pci_dev *dev) { }
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index c5bce25df51c..b9c6c7b97217 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -295,6 +295,7 @@ void pci_aer_clear_fatal_status(struct pci_dev *dev)
if (status)
pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_STATUS, status);
}
+EXPORT_SYMBOL_FOR_MODULES(pci_aer_clear_fatal_status, "cxl_core");
/**
* pci_aer_raw_clear_status - Clear AER error registers.
@@ -1186,7 +1187,10 @@ static void pci_aer_handle_error(struct pci_dev *dev, struct aer_err_info *info)
static void handle_error_source(struct pci_dev *dev, struct aer_err_info *info)
{
cxl_rch_handle_error(dev, info);
- pci_aer_handle_error(dev, info);
+ if (is_cxl_error(dev, info))
+ cxl_forward_error(dev, info);
+ else
+ pci_aer_handle_error(dev, info);
pci_dev_put(dev);
}
diff --git a/drivers/pci/pcie/aer_cxl_vh.c b/drivers/pci/pcie/aer_cxl_vh.c
index c0fea2c2b9bc..3c54c1647417 100644
--- a/drivers/pci/pcie/aer_cxl_vh.c
+++ b/drivers/pci/pcie/aer_cxl_vh.c
@@ -45,8 +45,15 @@ bool is_cxl_error(struct pci_dev *pdev, struct aer_err_info *info)
if (!info || !info->is_cxl)
return false;
- if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT)
+ switch (pci_pcie_type(pdev)) {
+ case PCI_EXP_TYPE_ENDPOINT:
+ case PCI_EXP_TYPE_ROOT_PORT:
+ case PCI_EXP_TYPE_UPSTREAM:
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ break;
+ default:
return false;
+ }
return is_aer_internal_error(info);
}
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 78841cf4268c..979ed2f9fd38 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -68,6 +68,7 @@ typedef int (*cxl_proto_err_fn_t)(struct cxl_proto_err_work_data *wd);
#if defined(CONFIG_PCIEAER)
int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
+void pci_aer_clear_fatal_status(struct pci_dev *dev);
int pcie_aer_is_native(struct pci_dev *dev);
void pci_aer_unmask_internal_errors(struct pci_dev *dev);
#else
@@ -75,6 +76,7 @@ static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{
return -EINVAL;
}
+static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { }
static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
static inline void pci_aer_unmask_internal_errors(struct pci_dev *dev) { }
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..39a386871bcb 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1941,8 +1941,10 @@ static inline void pci_hp_unignore_link_change(struct pci_dev *pdev) { }
#ifdef CONFIG_PCIEAER
bool pci_aer_available(void);
+void pcie_clear_device_status(struct pci_dev *dev);
#else
static inline bool pci_aer_available(void) { return false; }
+static inline void pcie_clear_device_status(struct pci_dev *dev) { }
#endif
bool pci_ats_disabled(void);
--
2.34.1
^ permalink raw reply related
* [PATCH v17 05/11] cxl: Limit CXL-CPER kfifo registration functions scope
From: Terry Bowman @ 2026-05-05 17:30 UTC (permalink / raw)
To: dave, jic23, dave.jiang, alison.schofield, djbw, bhelgaas,
shiju.jose, ming.li, Smita.KoralahalliChannabasappa, rrichter,
dan.carpenter, PradeepVineshReddy.Kodamati, lukas,
Benjamin.Cheatham, sathyanarayanan.kuppuswamy, vishal.l.verma,
alucerop, ira.weiny, corbet, rafael, xueshuai, linux-cxl
Cc: linux-kernel, linux-pci, linux-acpi, linux-doc, terry.bowman
In-Reply-To: <20260505173029.2718246-1-terry.bowman@amd.com>
From: Dan Williams <djbw@kernel.org>
Some CPER functions used by CXL drivers are exported using the
EXPORT_SYMBOL_NS_GPL(fn, ns) macro. This doesn't provide compile time
enforcement or visibility of the consumers.
This can be improved by using EXPORT_SYMBOL_FOR_MODULES() instead.
EXPORT_SYMBOL_FOR_MODULES() explicitly names the modules that can access
the function. This provides more precise control and visibility of symbol
exposure than the namespace macro. It also provides compile time checking.
To improve control and clarity, update cxl_cper_register_prot_err_work(),
cxl_cper_unregister_prot_err_work(), and cxl_cper_prot_err_kfifo_get()
to use EXPORT_SYMBOL_FOR_MODULES(). Also, update the register and unregister
functions to return void type.
Update the CPER kfifo unregister to cancel work while using
synchronization.
Co-developed-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Dan Williams <djbw@kernel.org>
---
Changes in v16->v17:
- Split from v16 02/10 ("Update unregistration for AER-CXL and
CPER-CXL kfifos"); AER-CXL half folded into v17 01/10.
- Convert exports to EXPORT_SYMBOL_FOR_MODULES("cxl_core").
- Change register/unregister return type from int to void.
- Drop work_struct argument from cxl_cper_unregister_prot_err_work();
it now cancels its own work.
- Remove now-redundant cancel_work_sync() from cxl_ras_exit().
- Add WARN_ONCE() in cxl_cper_register_prot_err_work() for
double-registration.
---
drivers/acpi/apei/ghes.c | 27 ++++++++++++++-------------
drivers/cxl/core/ras.c | 6 +++---
include/cxl/event.h | 10 ++++------
3 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 3236a3ce79d6..dd0a073af93c 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -778,33 +778,34 @@ static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
#endif
}
-int cxl_cper_register_prot_err_work(struct work_struct *work)
+void cxl_cper_register_prot_err_work(struct work_struct *work)
{
- if (cxl_cper_prot_err_work)
- return -EINVAL;
-
guard(spinlock)(&cxl_cper_prot_err_work_lock);
+ WARN_ONCE(cxl_cper_prot_err_work,
+ "CPER-CXL kfifo consumer already registered\n");
cxl_cper_prot_err_work = work;
- return 0;
}
-EXPORT_SYMBOL_NS_GPL(cxl_cper_register_prot_err_work, "CXL");
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_register_prot_err_work, "cxl_core");
-int cxl_cper_unregister_prot_err_work(struct work_struct *work)
+void cxl_cper_unregister_prot_err_work(void)
{
- if (cxl_cper_prot_err_work != work)
- return -EINVAL;
+ struct work_struct *work;
- guard(spinlock)(&cxl_cper_prot_err_work_lock);
+ spin_lock(&cxl_cper_prot_err_work_lock);
+ work = cxl_cper_prot_err_work;
cxl_cper_prot_err_work = NULL;
- return 0;
+ spin_unlock(&cxl_cper_prot_err_work_lock);
+
+ if (work)
+ cancel_work_sync(work);
}
-EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_prot_err_work, "CXL");
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_unregister_prot_err_work, "cxl_core");
int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
{
return kfifo_get(&cxl_cper_prot_err_fifo, wd);
}
-EXPORT_SYMBOL_NS_GPL(cxl_cper_prot_err_kfifo_get, "CXL");
+EXPORT_SYMBOL_FOR_MODULES(cxl_cper_prot_err_kfifo_get, "cxl_core");
/* Room for 8 entries for each of the 4 event log queues */
#define CXL_CPER_FIFO_DEPTH 32
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c
index 56611da8357a..9193dac4e507 100644
--- a/drivers/cxl/core/ras.c
+++ b/drivers/cxl/core/ras.c
@@ -68,13 +68,13 @@ static DECLARE_WORK(cxl_cper_prot_err_work, cxl_cper_prot_err_work_fn);
int cxl_ras_init(void)
{
- return cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
+ cxl_cper_register_prot_err_work(&cxl_cper_prot_err_work);
+ return 0;
}
void cxl_ras_exit(void)
{
- cxl_cper_unregister_prot_err_work(&cxl_cper_prot_err_work);
- cancel_work_sync(&cxl_cper_prot_err_work);
+ cxl_cper_unregister_prot_err_work();
}
static void cxl_dport_map_ras(struct cxl_dport *dport)
diff --git a/include/cxl/event.h b/include/cxl/event.h
index ff97fea718d2..51acedb0d683 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -289,8 +289,8 @@ struct cxl_cper_prot_err_work_data {
int cxl_cper_register_work(struct work_struct *work);
int cxl_cper_unregister_work(struct work_struct *work);
int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd);
-int cxl_cper_register_prot_err_work(struct work_struct *work);
-int cxl_cper_unregister_prot_err_work(struct work_struct *work);
+void cxl_cper_register_prot_err_work(struct work_struct *work);
+void cxl_cper_unregister_prot_err_work(void);
int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd);
#else
static inline int cxl_cper_register_work(struct work_struct *work)
@@ -306,13 +306,11 @@ static inline int cxl_cper_kfifo_get(struct cxl_cper_work_data *wd)
{
return 0;
}
-static inline int cxl_cper_register_prot_err_work(struct work_struct *work)
+static inline void cxl_cper_register_prot_err_work(struct work_struct *work)
{
- return 0;
}
-static inline int cxl_cper_unregister_prot_err_work(struct work_struct *work)
+static inline void cxl_cper_unregister_prot_err_work(void)
{
- return 0;
}
static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
{
--
2.34.1
^ permalink raw reply related
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