Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
"Here is a (hopefully) final round of arm64 fixes for 6.12 that address
some user-visible floating point register corruption. Both of the
Marks have been working on this for a couple of weeks and we've ended
up in a position where SVE is solid but SME still has enough pending
issues that the most pragmatic solution for the release and stable
backports is to disable the feature. Yes, it's a shame, but the
hardware is rare as hen's teeth at the moment and we're better off
getting back to a known good state before fixing it all properly.
We're also improving the selftests for 6.13 to help avoid merging
broken code in the future.

Anyway, the good news is that we're removing a lot more code than
we're adding.

Summary:

- Fix handling of SVE traps from userspace on preemptible kernels
when converting the saved floating point state into SVE state.

- Remove broken support for the SMCCCv1.3 "SVE discard hint"
optimisation.

- Disable SME support, as the current support code suffers from
numerous issues around signal delivery, ptrace access and
context-switch which can lead to user-visible corruption of the
register state"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: Kconfig: Make SME depend on BROKEN for now
arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint
arm64/sve: Discard stale CPU state when handling SVE traps

+8 -65
+1
arch/arm64/Kconfig
··· 2214 2214 bool "ARM Scalable Matrix Extension support" 2215 2215 default y 2216 2216 depends on ARM64_SVE 2217 + depends on BROKEN 2217 2218 help 2218 2219 The Scalable Matrix Extension (SME) is an extension to the AArch64 2219 2220 execution state which utilises a substantial subset of the SVE
+1
arch/arm64/kernel/fpsimd.c
··· 1367 1367 } else { 1368 1368 fpsimd_to_sve(current); 1369 1369 current->thread.fp_type = FP_STATE_SVE; 1370 + fpsimd_flush_task_state(current); 1370 1371 } 1371 1372 } 1372 1373
+3 -32
arch/arm64/kernel/smccc-call.S
··· 7 7 8 8 #include <asm/asm-offsets.h> 9 9 #include <asm/assembler.h> 10 - #include <asm/thread_info.h> 11 - 12 - /* 13 - * If we have SMCCC v1.3 and (as is likely) no SVE state in 14 - * the registers then set the SMCCC hint bit to say there's no 15 - * need to preserve it. Do this by directly adjusting the SMCCC 16 - * function value which is already stored in x0 ready to be called. 17 - */ 18 - SYM_FUNC_START(__arm_smccc_sve_check) 19 - 20 - ldr_l x16, smccc_has_sve_hint 21 - cbz x16, 2f 22 - 23 - get_current_task x16 24 - ldr x16, [x16, #TSK_TI_FLAGS] 25 - tbnz x16, #TIF_FOREIGN_FPSTATE, 1f // Any live FP state? 26 - tbnz x16, #TIF_SVE, 2f // Does that state include SVE? 27 - 28 - 1: orr x0, x0, ARM_SMCCC_1_3_SVE_HINT 29 - 30 - 2: ret 31 - SYM_FUNC_END(__arm_smccc_sve_check) 32 - EXPORT_SYMBOL(__arm_smccc_sve_check) 33 10 34 11 .macro SMCCC instr 35 - stp x29, x30, [sp, #-16]! 36 - mov x29, sp 37 - alternative_if ARM64_SVE 38 - bl __arm_smccc_sve_check 39 - alternative_else_nop_endif 40 12 \instr #0 41 - ldr x4, [sp, #16] 13 + ldr x4, [sp] 42 14 stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] 43 15 stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] 44 - ldr x4, [sp, #24] 16 + ldr x4, [sp, #8] 45 17 cbz x4, 1f /* no quirk structure */ 46 18 ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] 47 19 cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 48 20 b.ne 1f 49 21 str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] 50 - 1: ldp x29, x30, [sp], #16 51 - ret 22 + 1: ret 52 23 .endm 53 24 54 25 /*
-4
drivers/firmware/smccc/smccc.c
··· 16 16 static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE; 17 17 18 18 bool __ro_after_init smccc_trng_available = false; 19 - u64 __ro_after_init smccc_has_sve_hint = false; 20 19 s32 __ro_after_init smccc_soc_id_version = SMCCC_RET_NOT_SUPPORTED; 21 20 s32 __ro_after_init smccc_soc_id_revision = SMCCC_RET_NOT_SUPPORTED; 22 21 ··· 27 28 smccc_conduit = conduit; 28 29 29 30 smccc_trng_available = smccc_probe_trng(); 30 - if (IS_ENABLED(CONFIG_ARM64_SVE) && 31 - smccc_version >= ARM_SMCCC_VERSION_1_3) 32 - smccc_has_sve_hint = true; 33 31 34 32 if ((smccc_version >= ARM_SMCCC_VERSION_1_2) && 35 33 (smccc_conduit != SMCCC_CONDUIT_NONE)) {
+3 -29
include/linux/arm-smccc.h
··· 315 315 316 316 void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit); 317 317 318 - extern u64 smccc_has_sve_hint; 319 - 320 318 /** 321 319 * arm_smccc_get_soc_id_version() 322 320 * ··· 413 415 }; 414 416 415 417 /** 416 - * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls 417 - * 418 - * Sets the SMCCC hint bit to indicate if there is live state in the SVE 419 - * registers, this modifies x0 in place and should never be called from C 420 - * code. 421 - */ 422 - asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0); 423 - 424 - /** 425 418 * __arm_smccc_smc() - make SMC calls 426 419 * @a0-a7: arguments passed in registers 0 to 7 427 420 * @res: result values from registers 0 to 3 ··· 476 487 477 488 #define SMCCC_SMC_INST __SMC(0) 478 489 #define SMCCC_HVC_INST __HVC(0) 479 - 480 - #endif 481 - 482 - /* nVHE hypervisor doesn't have a current thread so needs separate checks */ 483 - #if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__) 484 - 485 - #define SMCCC_SVE_CHECK ALTERNATIVE("nop \n", "bl __arm_smccc_sve_check \n", \ 486 - ARM64_SVE) 487 - #define smccc_sve_clobbers "x16", "x30", "cc", 488 - 489 - #else 490 - 491 - #define SMCCC_SVE_CHECK 492 - #define smccc_sve_clobbers 493 490 494 491 #endif 495 492 ··· 549 574 register unsigned long r3 asm("r3"); \ 550 575 CONCATENATE(__declare_arg_, \ 551 576 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \ 552 - asm volatile(SMCCC_SVE_CHECK \ 553 - inst "\n" : \ 577 + asm volatile(inst "\n" : \ 554 578 "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \ 555 579 : CONCATENATE(__constraint_read_, \ 556 580 COUNT_ARGS(__VA_ARGS__)) \ 557 - : smccc_sve_clobbers "memory"); \ 581 + : "memory"); \ 558 582 if (___res) \ 559 583 *___res = (typeof(*___res)){r0, r1, r2, r3}; \ 560 584 } while (0) ··· 602 628 asm ("" : \ 603 629 : CONCATENATE(__constraint_read_, \ 604 630 COUNT_ARGS(__VA_ARGS__)) \ 605 - : smccc_sve_clobbers "memory"); \ 631 + : "memory"); \ 606 632 if (___res) \ 607 633 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \ 608 634 } while (0)