mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-11-07 14:26:44 +00:00
- Add powerpc qspinlock implementation optimised for large system scalability and
paravirt. See the merge message for more details.
- Enable objtool to be built on powerpc to generate mcount locations.
- Use a temporary mm for code patching with the Radix MMU, so the writable mapping is
restricted to the patching CPU.
- Add an option to build the 64-bit big-endian kernel with the ELFv2 ABI.
- Sanitise user registers on interrupt entry on 64-bit Book3S.
- Many other small features and fixes.
Thanks to: Aboorva Devarajan, Angel Iglesias, Benjamin Gray, Bjorn Helgaas, Bo Liu, Chen
Lifu, Christoph Hellwig, Christophe JAILLET, Christophe Leroy, Christopher M. Riedl, Colin
Ian King, Deming Wang, Disha Goel, Dmitry Torokhov, Finn Thain, Geert Uytterhoeven,
Gustavo A. R. Silva, Haowen Bai, Joel Stanley, Jordan Niethe, Julia Lawall, Kajol Jain,
Laurent Dufour, Li zeming, Miaoqian Lin, Michael Jeanson, Nathan Lynch, Naveen N. Rao,
Nayna Jain, Nicholas Miehlbradt, Nicholas Piggin, Pali Rohár, Randy Dunlap, Rohan McLure,
Russell Currey, Sathvika Vasireddy, Shaomin Deng, Stephen Kitt, Stephen Rothwell, Thomas
Weißschuh, Tiezhu Yang, Uwe Kleine-König, Xie Shaowen, Xiu Jianfeng, XueBing Chen, Yang
Yingliang, Zhang Jiaming, ruanjinjie, Jessica Yu, Wolfram Sang.
-----BEGIN PGP SIGNATURE-----
iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAmOfrj8THG1wZUBlbGxl
cm1hbi5pZC5hdQAKCRBR6+o8yOGlgIWtD/9mGF/ze2k+qFTo+30fb7bO8WJIDgsR
dIASnZjXV7q/45elvymhUdkQv4R7xL3pzC40P1+ZKtWzGTNe+zWUQLoALNwRK85j
8CsxZbqefGNKE5Z6ZHo9s37wsu3+jJu9yEQpGFo1LINyzeclCn5St5oqfRam+Hd/
cPF+VfvREwZ0+YOKGBhJ2EgC+Gc9xsFY7DLQsoYlu71iZZr6Z6rgZW/EY5h3RMGS
YKBoVwDsWaU0FpFWrr/rYTI6DqSr3AHr1+ftDg7ncCZMD6vQva6aMCCt94aLB1aE
vC+DNdhZlA558bXGa5yA7Wr//7aUBUIwyC60DogOeZ6vw3kD9tdEd1fbH5hmqNKY
K5bfqm28XU2959CTE8RDgsYYZvwDcfrjBIML14WZGdCQOTcGKpgOGp22o6yNb1Pq
JKpHHnVpvu2PZ/p2XdKSm9+etr2yI6lXZAEVTS7ehdtMukButjSHEVbSCEZ8tlWz
KokQt2J23BMHuSrXK6+67wWQBtdsLEk+LBOQmweiwarMocqvL/Zjz/5J7DR2DtH8
wlY3wOtB1+E5j7xZ+RgK3c3jNg5dH39ZwvFsSATWTI3P+iq6OK/bbk4q4LmZt2l9
ZIfH/CXPf9BvGCHzHa3AAd3UBbJLFwj17btMEv1wFVPS0T4LPUzkgTNTNUYeP6zL
h1e5QfgUxvKPuQ==
=7k3p
-----END PGP SIGNATURE-----
Merge tag 'powerpc-6.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman:
- Add powerpc qspinlock implementation optimised for large system
scalability and paravirt. See the merge message for more details
- Enable objtool to be built on powerpc to generate mcount locations
- Use a temporary mm for code patching with the Radix MMU, so the
writable mapping is restricted to the patching CPU
- Add an option to build the 64-bit big-endian kernel with the ELFv2
ABI
- Sanitise user registers on interrupt entry on 64-bit Book3S
- Many other small features and fixes
Thanks to Aboorva Devarajan, Angel Iglesias, Benjamin Gray, Bjorn
Helgaas, Bo Liu, Chen Lifu, Christoph Hellwig, Christophe JAILLET,
Christophe Leroy, Christopher M. Riedl, Colin Ian King, Deming Wang,
Disha Goel, Dmitry Torokhov, Finn Thain, Geert Uytterhoeven, Gustavo A.
R. Silva, Haowen Bai, Joel Stanley, Jordan Niethe, Julia Lawall, Kajol
Jain, Laurent Dufour, Li zeming, Miaoqian Lin, Michael Jeanson, Nathan
Lynch, Naveen N. Rao, Nayna Jain, Nicholas Miehlbradt, Nicholas Piggin,
Pali Rohár, Randy Dunlap, Rohan McLure, Russell Currey, Sathvika
Vasireddy, Shaomin Deng, Stephen Kitt, Stephen Rothwell, Thomas
Weißschuh, Tiezhu Yang, Uwe Kleine-König, Xie Shaowen, Xiu Jianfeng,
XueBing Chen, Yang Yingliang, Zhang Jiaming, ruanjinjie, Jessica Yu,
and Wolfram Sang.
* tag 'powerpc-6.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (181 commits)
powerpc/code-patching: Fix oops with DEBUG_VM enabled
powerpc/qspinlock: Fix 32-bit build
powerpc/prom: Fix 32-bit build
powerpc/rtas: mandate RTAS syscall filtering
powerpc/rtas: define pr_fmt and convert printk call sites
powerpc/rtas: clean up includes
powerpc/rtas: clean up rtas_error_log_max initialization
powerpc/pseries/eeh: use correct API for error log size
powerpc/rtas: avoid scheduling in rtas_os_term()
powerpc/rtas: avoid device tree lookups in rtas_os_term()
powerpc/rtasd: use correct OF API for event scan rate
powerpc/rtas: document rtas_call()
powerpc/pseries: unregister VPA when hot unplugging a CPU
powerpc/pseries: reset the RCU watchdogs after a LPM
powerpc: Take in account addition CPU node when building kexec FDT
powerpc: export the CPU node count
powerpc/cpuidle: Set CPUIDLE_FLAG_POLLING for snooze state
powerpc/dts/fsl: Fix pca954x i2c-mux node names
cxl: Remove unnecessary cxl_pci_window_alignment()
selftests/powerpc: Fix resource leaks
...
234 lines
5.4 KiB
C
234 lines
5.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
|
|
*/
|
|
|
|
#include <subcmd/parse-options.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <objtool/builtin.h>
|
|
#include <objtool/objtool.h>
|
|
|
|
#define ERROR(format, ...) \
|
|
fprintf(stderr, \
|
|
"error: objtool: " format "\n", \
|
|
##__VA_ARGS__)
|
|
|
|
struct opts opts;
|
|
|
|
static const char * const check_usage[] = {
|
|
"objtool <actions> [<options>] file.o",
|
|
NULL,
|
|
};
|
|
|
|
static const char * const env_usage[] = {
|
|
"OBJTOOL_ARGS=\"<options>\"",
|
|
NULL,
|
|
};
|
|
|
|
static int parse_dump(const struct option *opt, const char *str, int unset)
|
|
{
|
|
if (!str || !strcmp(str, "orc")) {
|
|
opts.dump_orc = true;
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int parse_hacks(const struct option *opt, const char *str, int unset)
|
|
{
|
|
bool found = false;
|
|
|
|
/*
|
|
* Use strstr() as a lazy method of checking for comma-separated
|
|
* options.
|
|
*
|
|
* No string provided == enable all options.
|
|
*/
|
|
|
|
if (!str || strstr(str, "jump_label")) {
|
|
opts.hack_jump_label = true;
|
|
found = true;
|
|
}
|
|
|
|
if (!str || strstr(str, "noinstr")) {
|
|
opts.hack_noinstr = true;
|
|
found = true;
|
|
}
|
|
|
|
if (!str || strstr(str, "skylake")) {
|
|
opts.hack_skylake = true;
|
|
found = true;
|
|
}
|
|
|
|
return found ? 0 : -1;
|
|
}
|
|
|
|
const struct option check_options[] = {
|
|
OPT_GROUP("Actions:"),
|
|
OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake", "patch toolchain bugs/limitations", parse_hacks),
|
|
OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"),
|
|
OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"),
|
|
OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"),
|
|
OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"),
|
|
OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"),
|
|
OPT_BOOLEAN(0, "rethunk", &opts.rethunk, "validate and annotate rethunk usage"),
|
|
OPT_BOOLEAN(0, "unret", &opts.unret, "validate entry unret placement"),
|
|
OPT_INTEGER(0, "prefix", &opts.prefix, "generate prefix symbols"),
|
|
OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"),
|
|
OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rules"),
|
|
OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls"),
|
|
OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"),
|
|
OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integrity (kCFI) function preambles"),
|
|
OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump),
|
|
|
|
OPT_GROUP("Options:"),
|
|
OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"),
|
|
OPT_BOOLEAN(0, "backup", &opts.backup, "create .orig files before modification"),
|
|
OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"),
|
|
OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"),
|
|
OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"),
|
|
OPT_BOOLEAN(0, "mnop", &opts.mnop, "nop out mcount call sites"),
|
|
OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"),
|
|
OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section addresses in warnings"),
|
|
OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"),
|
|
|
|
OPT_END(),
|
|
};
|
|
|
|
int cmd_parse_options(int argc, const char **argv, const char * const usage[])
|
|
{
|
|
const char *envv[16] = { };
|
|
char *env;
|
|
int envc;
|
|
|
|
env = getenv("OBJTOOL_ARGS");
|
|
if (env) {
|
|
envv[0] = "OBJTOOL_ARGS";
|
|
for (envc = 1; envc < ARRAY_SIZE(envv); ) {
|
|
envv[envc++] = env;
|
|
env = strchr(env, ' ');
|
|
if (!env)
|
|
break;
|
|
*env = '\0';
|
|
env++;
|
|
}
|
|
|
|
parse_options(envc, envv, check_options, env_usage, 0);
|
|
}
|
|
|
|
argc = parse_options(argc, argv, check_options, usage, 0);
|
|
if (argc != 1)
|
|
usage_with_options(usage, check_options);
|
|
return argc;
|
|
}
|
|
|
|
static bool opts_valid(void)
|
|
{
|
|
if (opts.hack_jump_label ||
|
|
opts.hack_noinstr ||
|
|
opts.ibt ||
|
|
opts.mcount ||
|
|
opts.noinstr ||
|
|
opts.orc ||
|
|
opts.retpoline ||
|
|
opts.rethunk ||
|
|
opts.sls ||
|
|
opts.stackval ||
|
|
opts.static_call ||
|
|
opts.uaccess) {
|
|
if (opts.dump_orc) {
|
|
ERROR("--dump can't be combined with other options");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if (opts.unret && !opts.rethunk) {
|
|
ERROR("--unret requires --rethunk");
|
|
return false;
|
|
}
|
|
|
|
if (opts.dump_orc)
|
|
return true;
|
|
|
|
ERROR("At least one command required");
|
|
return false;
|
|
}
|
|
|
|
static bool mnop_opts_valid(void)
|
|
{
|
|
if (opts.mnop && !opts.mcount) {
|
|
ERROR("--mnop requires --mcount");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool link_opts_valid(struct objtool_file *file)
|
|
{
|
|
if (opts.link)
|
|
return true;
|
|
|
|
if (has_multiple_files(file->elf)) {
|
|
ERROR("Linked object detected, forcing --link");
|
|
opts.link = true;
|
|
return true;
|
|
}
|
|
|
|
if (opts.noinstr) {
|
|
ERROR("--noinstr requires --link");
|
|
return false;
|
|
}
|
|
|
|
if (opts.ibt) {
|
|
ERROR("--ibt requires --link");
|
|
return false;
|
|
}
|
|
|
|
if (opts.unret) {
|
|
ERROR("--unret requires --link");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int objtool_run(int argc, const char **argv)
|
|
{
|
|
const char *objname;
|
|
struct objtool_file *file;
|
|
int ret;
|
|
|
|
argc = cmd_parse_options(argc, argv, check_usage);
|
|
objname = argv[0];
|
|
|
|
if (!opts_valid())
|
|
return 1;
|
|
|
|
if (opts.dump_orc)
|
|
return orc_dump(objname);
|
|
|
|
file = objtool_open_read(objname);
|
|
if (!file)
|
|
return 1;
|
|
|
|
if (!mnop_opts_valid())
|
|
return 1;
|
|
|
|
if (!link_opts_valid(file))
|
|
return 1;
|
|
|
|
ret = check(file);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (file->elf->changed)
|
|
return elf_write(file->elf);
|
|
|
|
return 0;
|
|
}
|