From: Chenghao Duan duanchenghao@kylinos.cn
[ Upstream commit 9bdc1ab5e4ce6f066119018d8f69631a46f9c5a0 ]
This patch allows the LoongArch BPF JIT to handle recoverable memory access errors generated by BPF_PROBE_MEM* instructions.
When a BPF program performs memory access operations, the instructions it executes may trigger ADEM exceptions. The kernel’s built-in BPF exception table mechanism (EX_TYPE_BPF) will generate corresponding exception fixup entries in the JIT compilation phase; however, the architecture-specific trap handling function needs to proactively call the common fixup routine to achieve exception recovery.
do_ade(): fix EX_TYPE_BPF memory access exceptions for BPF programs, ensure safe execution.
Relevant test cases: illegal address access tests in module_attach and subprogs_extable of selftests/bpf.
Signed-off-by: Chenghao Duan duanchenghao@kylinos.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis of LoongArch Exception Fixup Commit
### 1. COMMIT MESSAGE ANALYSIS
The subject "LoongArch: Enable exception fixup for specific ADE subcode" and message clearly indicate this is a **bug fix** for BPF exception handling. Key phrases: - "handle recoverable memory access errors generated by BPF_PROBE_MEM* instructions" - "fix EX_TYPE_BPF memory access exceptions for BPF programs, ensure safe execution" - References specific failing test cases (module_attach, subprogs_extable in selftests/bpf)
### 2. CODE CHANGE ANALYSIS
The change is in `do_ade()` (Address alignment exception handler):
```c + unsigned int esubcode = FIELD_GET(CSR_ESTAT_ESUBCODE, regs->csr_estat); + + if ((esubcode == EXSUBCODE_ADEM) && fixup_exception(regs)) + goto out; ```
**The bug mechanism:** - BPF programs using `BPF_PROBE_MEM*` instructions may intentionally access invalid memory addresses - The BPF JIT properly creates exception table entries (EX_TYPE_BPF) during compilation - However, the LoongArch `do_ade()` handler was NOT calling `fixup_exception()` to check these entries - Result: Instead of graceful recovery, the kernel dies (`die_if_kernel`) or sends SIGBUS
**The fix mechanism:** - Checks for ADEM (Address Exception - Memory) subcode specifically - Calls `fixup_exception()` to look up the exception table - If a fixup exists, recovers gracefully via the `goto out` path - Falls back to original behavior if no fixup is found
This follows the same pattern used by other architectures (x86, arm64) for handling BPF exception recovery.
### 3. CLASSIFICATION
This is a **bug fix**, not a new feature: - The BPF exception table mechanism already exists - The `fixup_exception()` infrastructure already exists - This completes incomplete exception handling that was causing crashes
### 4. SCOPE AND RISK ASSESSMENT
**Size:** Very small - 5 lines added - 1 file modified - Single architecture affected (LoongArch only)
**Risk:** LOW - Conservative change with explicit fallback to original behavior - Uses well-established kernel infrastructure (`fixup_exception`, `FIELD_GET`) - Only affects specific ADEM exception subcode - No changes to hot paths for non-exception cases
### 5. USER IMPACT
**Affected users:** LoongArch systems running BPF programs that probe memory (bpftrace, BPF-based tracing/security tools)
**Severity:** HIGH for affected users - Without fix: Kernel panic or SIGBUS when BPF probes invalid memory - BPF_PROBE_MEM is designed for safe memory probing; without this, it's broken on LoongArch
### 6. STABILITY INDICATORS
- Signed-off-by from LoongArch maintainer (Huacai Chen) - indicates proper review - Specific test cases mentioned (suggests it was tested) - The change follows patterns well-established in other architectures
### 7. DEPENDENCY CHECK
The fix is standalone, requiring only: - LoongArch architecture support (5.19+) - LoongArch BPF JIT with exception table support - These prerequisites should exist in stable trees that have LoongArch
### SUMMARY
**Meets stable kernel criteria:** 1. ✅ **Obviously correct:** Standard pattern used by other architectures 2. ✅ **Fixes a real bug:** BPF programs crash/panic on memory probe operations 3. ✅ **Important issue:** Kernel crashes/panics are severe 4. ✅ **Small and contained:** 5 lines, single file, single architecture 5. ✅ **No new features:** Uses existing infrastructure, just enables proper behavior 6. ✅ **Low risk:** Fallback to original behavior when no fixup exists
**Risk vs Benefit:** - Risk: Minimal - architecture-specific, conservative, well-tested pattern - Benefit: High - fixes kernel crashes for LoongArch BPF users
This is a small, surgical fix to LoongArch exception handling that enables proper BPF exception recovery. Without it, BPF programs using probe_mem operations will cause kernel panics on LoongArch. The fix follows patterns already used by other architectures and has minimal risk.
**YES**
arch/loongarch/kernel/traps.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index da5926fead4a..8e51ce004572 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -535,10 +535,15 @@ asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr) asmlinkage void noinstr do_ade(struct pt_regs *regs) { irqentry_state_t state = irqentry_enter(regs); + unsigned int esubcode = FIELD_GET(CSR_ESTAT_ESUBCODE, regs->csr_estat); + + if ((esubcode == EXSUBCODE_ADEM) && fixup_exception(regs)) + goto out;
die_if_kernel("Kernel ade access", regs); force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)regs->csr_badvaddr);
+out: irqentry_exit(regs, state); }