arm64 fixes:
- Don't taint the kernel if CPUs have different sets of page sizes supported (other than the one in use). - Issue I-cache maintenance for module ftrace trampoline. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE5RElWfyWxS+3PLO2a9axLQDIXvEFAl1W5VMACgkQa9axLQDI XvFAWQ//RrxMHeN7/Ynv1MDqucZlMpQJMUV2V0K5wYO6ZwGMKYXw62SBzb9AMv0y iFhYNZbtBoE2JhLNEfwhdNkk9NfUsKbUcfyt0cono2DU1tVihmmVqbNbairNhKVo j7vxnCx8SMQ5ZT+QaTpKUddzlzb4jdycXGYaje62bbA19BCOVVIuy61wGNtHP4IU 817RHqIj6aqIbmplt79+Q3vOopB8BbxrnpC5cp8rw1CKbfu7kQN4zePIA4Z4bhag G5hm+aTV1qzrmEud2WkuA7044vsw2Wkd/8gksRyQKkypfqfQ3NrASDn3xGqOi/5t 2DsyJPaVUC1tsJdrVqpfWZfLJJ8FGyox7aeXL7OdPrfWP6HI9jJnodRVH/av97g6 psaSoJNxXbVqrg/wva6i2f25KBYdp/vQW0Nmjljvt4dmEDrE/jpifAYAH/LUmi5H fMNXyOdeDcgUoVfcEk/S1leiDf0gUy+B8ylknk12knbMuk/9ATq/2H3RKqrRJYWL qUQBvB04d7NHZl8wl+IVLlK8g4x5Jeetjm7GHvLbOp9agb63kwVFq50c4zD052LA eKy6LbUO2xHyA3PrtvBem/hKZ/GCTh0o0xcwUkyNcsLUHfKnMcHLEH/WWd5rmYIQ xvbQVhVORR8ru7eCQCRMBmjGaHFz2ZQa4Q3V3qVBnX+q/F6dku8= =VneQ -----END PGP SIGNATURE----- Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux Pull arm64 fixes from Catalin Marinas: - Don't taint the kernel if CPUs have different sets of page sizes supported (other than the one in use). - Issue I-cache maintenance for module ftrace trampoline. * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side arm64: cpufeature: Don't treat granule sizes as strict
This commit is contained in:
Коммит
b7e7c85dc7
|
@ -184,9 +184,17 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
|
static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
|
||||||
S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
|
/*
|
||||||
S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI),
|
* We already refuse to boot CPUs that don't support our configured
|
||||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI),
|
* page size, so we can only detect mismatches for a page size other
|
||||||
|
* than the one we're currently using. Unfortunately, SoCs like this
|
||||||
|
* exist in the wild so, even though we don't like it, we'll have to go
|
||||||
|
* along with it and treat them as non-strict.
|
||||||
|
*/
|
||||||
|
S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
|
||||||
|
S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI),
|
||||||
|
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI),
|
||||||
|
|
||||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_BIGENDEL0_SHIFT, 4, 0),
|
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_BIGENDEL0_SHIFT, 4, 0),
|
||||||
/* Linux shouldn't care about secure memory */
|
/* Linux shouldn't care about secure memory */
|
||||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_SNSMEM_SHIFT, 4, 0),
|
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_SNSMEM_SHIFT, 4, 0),
|
||||||
|
|
|
@ -73,7 +73,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
||||||
|
|
||||||
if (offset < -SZ_128M || offset >= SZ_128M) {
|
if (offset < -SZ_128M || offset >= SZ_128M) {
|
||||||
#ifdef CONFIG_ARM64_MODULE_PLTS
|
#ifdef CONFIG_ARM64_MODULE_PLTS
|
||||||
struct plt_entry trampoline;
|
struct plt_entry trampoline, *dst;
|
||||||
struct module *mod;
|
struct module *mod;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -106,23 +106,27 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
||||||
* to check if the actual opcodes are in fact identical,
|
* to check if the actual opcodes are in fact identical,
|
||||||
* regardless of the offset in memory so use memcmp() instead.
|
* regardless of the offset in memory so use memcmp() instead.
|
||||||
*/
|
*/
|
||||||
trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline);
|
dst = mod->arch.ftrace_trampoline;
|
||||||
if (memcmp(mod->arch.ftrace_trampoline, &trampoline,
|
trampoline = get_plt_entry(addr, dst);
|
||||||
sizeof(trampoline))) {
|
if (memcmp(dst, &trampoline, sizeof(trampoline))) {
|
||||||
if (plt_entry_is_initialized(mod->arch.ftrace_trampoline)) {
|
if (plt_entry_is_initialized(dst)) {
|
||||||
pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n");
|
pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* point the trampoline to our ftrace entry point */
|
/* point the trampoline to our ftrace entry point */
|
||||||
module_disable_ro(mod);
|
module_disable_ro(mod);
|
||||||
*mod->arch.ftrace_trampoline = trampoline;
|
*dst = trampoline;
|
||||||
module_enable_ro(mod, true);
|
module_enable_ro(mod, true);
|
||||||
|
|
||||||
/* update trampoline before patching in the branch */
|
/*
|
||||||
smp_wmb();
|
* Ensure updated trampoline is visible to instruction
|
||||||
|
* fetch before we patch in the branch.
|
||||||
|
*/
|
||||||
|
__flush_icache_range((unsigned long)&dst[0],
|
||||||
|
(unsigned long)&dst[1]);
|
||||||
}
|
}
|
||||||
addr = (unsigned long)(void *)mod->arch.ftrace_trampoline;
|
addr = (unsigned long)dst;
|
||||||
#else /* CONFIG_ARM64_MODULE_PLTS */
|
#else /* CONFIG_ARM64_MODULE_PLTS */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
#endif /* CONFIG_ARM64_MODULE_PLTS */
|
#endif /* CONFIG_ARM64_MODULE_PLTS */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче