Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d1b2027 authored by Kumar Gala's avatar Kumar Gala Committed by Paul Mackerras
Browse files

powerpc: Fixup lwsync at runtime



To allow for a single kernel image on e500 v1/v2/mc we need to fixup lwsync
at runtime.  On e500v1/v2 lwsync causes an illop so we need to patch up
the code.  We default to 'sync' since that is always safe and if the cpu
is capable we will replace 'sync' with 'lwsync'.

We introduce CPU_FTR_LWSYNC as a way to determine at runtime if this is
needed.  This flag could be moved elsewhere since we dont really use it
for the normal CPU_FTR purpose.

Finally we only store the relative offset in the fixup section to keep it
as small as possible rather than using a full fixup_entry.

Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 5888da18
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -86,6 +86,12 @@ int module_finalize(const Elf_Ehdr *hdr,
				  (void *)sect->sh_addr + sect->sh_size);
#endif

	sect = find_section(hdr, sechdrs, "__lwsync_fixup");
	if (sect != NULL)
		do_lwsync_fixups(cur_cpu_spec->cpu_features,
				 (void *)sect->sh_addr,
				 (void *)sect->sh_addr + sect->sh_size);

	return 0;
}

+4 −0
Original line number Diff line number Diff line
@@ -101,6 +101,10 @@ unsigned long __init early_init(unsigned long dt_ptr)
			  PTRRELOC(&__start___ftr_fixup),
			  PTRRELOC(&__stop___ftr_fixup));

	do_lwsync_fixups(spec->cpu_features,
			 PTRRELOC(&__start___lwsync_fixup),
			 PTRRELOC(&__stop___lwsync_fixup));

	return KERNELBASE + offset;
}

+2 −0
Original line number Diff line number Diff line
@@ -363,6 +363,8 @@ void __init setup_system(void)
			  &__start___ftr_fixup, &__stop___ftr_fixup);
	do_feature_fixups(powerpc_firmware_features,
			  &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
	do_lwsync_fixups(cur_cpu_spec->cpu_features,
			 &__start___lwsync_fixup, &__stop___lwsync_fixup);

	/*
	 * Unflatten the device-tree passed by prom_init or kexec
+10 −0
Original line number Diff line number Diff line
@@ -571,6 +571,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
	if (start64)
		do_feature_fixups(powerpc_firmware_features,
				  start64, start64 + size64);

	start64 = find_section64(v64->hdr, "__lwsync_fixup", &size64);
	if (start64)
		do_lwsync_fixups(cur_cpu_spec->cpu_features,
				 start64, start64 + size64);
#endif /* CONFIG_PPC64 */

	start32 = find_section32(v32->hdr, "__ftr_fixup", &size32);
@@ -585,6 +590,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
				  start32, start32 + size32);
#endif /* CONFIG_PPC64 */

	start32 = find_section32(v32->hdr, "__lwsync_fixup", &size32);
	if (start32)
		do_lwsync_fixups(cur_cpu_spec->cpu_features,
				 start32, start32 + size32);

	return 0;
}

+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@ SECTIONS
	. = ALIGN(8);
	__ftr_fixup	: { *(__ftr_fixup) }

	. = ALIGN(8);
	__lwsync_fixup	: { *(__lwsync_fixup) }

#ifdef CONFIG_PPC64
	. = ALIGN(8);
	__fw_ftr_fixup	: { *(__fw_ftr_fixup) }
Loading