powerpc: cpuset: add local functions for copyin/copyout

Add local functions to workaround an instruction segment trap (panic)
when the indirect functions copyin and copyout are called by an external
loadable kernel module (i.e. pfsync, zfs and linuxulator). The crash
was triggered by change 47a57144af, but
kernel binary linked with LLD 9 works fine. LLVM bisect points that LLD
behavior chaged after dc06b0bc9ad055d06535462d91bfc2a744b2f589.

This is know to affect powerpc targets only and the final fix is still
being discussed with the LLVM community.

PR:	266730
Reviewed by:	luporl, jhibbits (on IRC, previous version)
MFC after:	2 days
Sponsored by:	Instituto de Pesquisas Eldorado (eldorado.org.br)
Differential Revision:	https://reviews.freebsd.org/D36234
This commit is contained in:
Alfredo Dal'Ava Junior 2022-10-03 11:51:05 -03:00
parent f8b5681094
commit db79bf75ac

View File

@ -1743,10 +1743,42 @@ cpuset_check_capabilities(struct thread *td, cpulevel_t level, cpuwhich_t which,
return (0);
}
#if defined(__powerpc__)
/*
* TODO: At least powerpc64 and powerpc64le kernels panic with
* exception 0x480 (instruction segment exception) when copyin/copyout,
* are set as a function pointer in cpuset_copy_cb struct and called by
* an external module (like pfsync). Tip: copyin/copyout have an ifunc
* resolver function.
*
* Bisect of LLVM shows that the behavior changed on LLVM 10.0 with
* https://reviews.llvm.org/rGdc06b0bc9ad055d06535462d91bfc2a744b2f589
*
* This is a hack/workaround while problem is being discussed with LLVM
* community
*/
static int
cpuset_copyin(const void *uaddr, void *kaddr, size_t len)
{
return(copyin(uaddr, kaddr, len));
}
static int
cpuset_copyout(const void *kaddr, void *uaddr, size_t len)
{
return(copyout(kaddr, uaddr, len));
}
static const struct cpuset_copy_cb copy_set = {
.cpuset_copyin = copyin,
.cpuset_copyout = copyout
.cpuset_copyin = cpuset_copyin,
.cpuset_copyout = cpuset_copyout
};
#else
static const struct cpuset_copy_cb copy_set = {
.cpuset_copyin = copyin,
.cpuset_copyout = copyout
};
#endif
#ifndef _SYS_SYSPROTO_H_
struct cpuset_args {