mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Merge tag 'x86_paravirt_for_v7.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 paravirt updates from Borislav Petkov: - A nice cleanup to the paravirt code containing a unification of the paravirt clock interface, taming the include hell by splitting the pv_ops structure and removing of a bunch of obsolete code (Juergen Gross) * tag 'x86_paravirt_for_v7.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) x86/paravirt: Use XOR r32,r32 to clear register in pv_vcpu_is_preempted() x86/paravirt: Remove trailing semicolons from alternative asm templates x86/pvlocks: Move paravirt spinlock functions into own header x86/paravirt: Specify pv_ops array in paravirt macros x86/paravirt: Allow pv-calls outside paravirt.h objtool: Allow multiple pv_ops arrays x86/xen: Drop xen_mmu_ops x86/xen: Drop xen_cpu_ops x86/xen: Drop xen_irq_ops x86/paravirt: Move pv_native_*() prototypes to paravirt.c x86/paravirt: Introduce new paravirt-base.h header x86/paravirt: Move paravirt_sched_clock() related code into tsc.c x86/paravirt: Use common code for paravirt_steal_clock() riscv/paravirt: Use common code for paravirt_steal_clock() loongarch/paravirt: Use common code for paravirt_steal_clock() arm64/paravirt: Use common code for paravirt_steal_clock() arm/paravirt: Use common code for paravirt_steal_clock() sched: Move clock related paravirt code to kernel/sched paravirt: Remove asm/paravirt_api_clock.h x86/paravirt: Move thunk macros to paravirt_types.h ...
This commit is contained in:
@@ -711,10 +711,14 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
|
||||
immr = find_reloc_by_dest(elf, (void *)sec, offset+3);
|
||||
disp = find_reloc_by_dest(elf, (void *)sec, offset+7);
|
||||
|
||||
if (!immr || strcmp(immr->sym->name, "pv_ops"))
|
||||
if (!immr || strncmp(immr->sym->name, "pv_ops", 6))
|
||||
break;
|
||||
|
||||
idx = (reloc_addend(immr) + 8) / sizeof(void *);
|
||||
idx = pv_ops_idx_off(immr->sym->name);
|
||||
if (idx < 0)
|
||||
break;
|
||||
|
||||
idx += (reloc_addend(immr) + 8) / sizeof(void *);
|
||||
|
||||
func = disp->sym;
|
||||
if (disp->sym->type == STT_SECTION)
|
||||
|
||||
@@ -521,21 +521,58 @@ static int decode_instructions(struct objtool_file *file)
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the pv_ops[] .data table to find the static initialized values.
|
||||
* Known pv_ops*[] arrays.
|
||||
*/
|
||||
static int add_pv_ops(struct objtool_file *file, const char *symname)
|
||||
static struct {
|
||||
const char *name;
|
||||
int idx_off;
|
||||
} pv_ops_tables[] = {
|
||||
{ .name = "pv_ops", },
|
||||
{ .name = "pv_ops_lock", },
|
||||
{ .name = NULL, .idx_off = -1 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Get index offset for a pv_ops* array.
|
||||
*/
|
||||
int pv_ops_idx_off(const char *symname)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; pv_ops_tables[idx].name; idx++) {
|
||||
if (!strcmp(symname, pv_ops_tables[idx].name))
|
||||
break;
|
||||
}
|
||||
|
||||
return pv_ops_tables[idx].idx_off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a pv_ops*[] .data table to find the static initialized values.
|
||||
*/
|
||||
static int add_pv_ops(struct objtool_file *file, int pv_ops_idx)
|
||||
{
|
||||
struct symbol *sym, *func;
|
||||
unsigned long off, end;
|
||||
struct reloc *reloc;
|
||||
int idx;
|
||||
int idx, idx_off;
|
||||
const char *symname;
|
||||
|
||||
symname = pv_ops_tables[pv_ops_idx].name;
|
||||
sym = find_symbol_by_name(file->elf, symname);
|
||||
if (!sym)
|
||||
return 0;
|
||||
if (!sym) {
|
||||
ERROR("Unknown pv_ops array %s", symname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
off = sym->offset;
|
||||
end = off + sym->len;
|
||||
idx_off = pv_ops_tables[pv_ops_idx].idx_off;
|
||||
if (idx_off < 0) {
|
||||
ERROR("pv_ops array %s has unknown index offset", symname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
reloc = find_reloc_by_dest_range(file->elf, sym->sec, off, end - off);
|
||||
if (!reloc)
|
||||
@@ -553,7 +590,7 @@ static int add_pv_ops(struct objtool_file *file, const char *symname)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (objtool_pv_add(file, idx, func))
|
||||
if (objtool_pv_add(file, idx + idx_off, func))
|
||||
return -1;
|
||||
|
||||
off = reloc_offset(reloc) + 1;
|
||||
@@ -569,14 +606,6 @@ static int add_pv_ops(struct objtool_file *file, const char *symname)
|
||||
*/
|
||||
static int init_pv_ops(struct objtool_file *file)
|
||||
{
|
||||
static const char *pv_ops_tables[] = {
|
||||
"pv_ops",
|
||||
"xen_cpu_ops",
|
||||
"xen_irq_ops",
|
||||
"xen_mmu_ops",
|
||||
NULL,
|
||||
};
|
||||
const char *pv_ops;
|
||||
struct symbol *sym;
|
||||
int idx, nr;
|
||||
|
||||
@@ -585,11 +614,20 @@ static int init_pv_ops(struct objtool_file *file)
|
||||
|
||||
file->pv_ops = NULL;
|
||||
|
||||
sym = find_symbol_by_name(file->elf, "pv_ops");
|
||||
if (!sym)
|
||||
nr = 0;
|
||||
for (idx = 0; pv_ops_tables[idx].name; idx++) {
|
||||
sym = find_symbol_by_name(file->elf, pv_ops_tables[idx].name);
|
||||
if (!sym) {
|
||||
pv_ops_tables[idx].idx_off = -1;
|
||||
continue;
|
||||
}
|
||||
pv_ops_tables[idx].idx_off = nr;
|
||||
nr += sym->len / sizeof(unsigned long);
|
||||
}
|
||||
|
||||
if (nr == 0)
|
||||
return 0;
|
||||
|
||||
nr = sym->len / sizeof(unsigned long);
|
||||
file->pv_ops = calloc(nr, sizeof(struct pv_state));
|
||||
if (!file->pv_ops) {
|
||||
ERROR_GLIBC("calloc");
|
||||
@@ -599,8 +637,10 @@ static int init_pv_ops(struct objtool_file *file)
|
||||
for (idx = 0; idx < nr; idx++)
|
||||
INIT_LIST_HEAD(&file->pv_ops[idx].targets);
|
||||
|
||||
for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++) {
|
||||
if (add_pv_ops(file, pv_ops))
|
||||
for (idx = 0; pv_ops_tables[idx].name; idx++) {
|
||||
if (pv_ops_tables[idx].idx_off < 0)
|
||||
continue;
|
||||
if (add_pv_ops(file, idx))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,5 +159,6 @@ const char *objtool_disas_insn(struct instruction *insn);
|
||||
|
||||
extern size_t sym_name_max_len;
|
||||
extern struct disas_context *objtool_disas_ctx;
|
||||
int pv_ops_idx_off(const char *symname);
|
||||
|
||||
#endif /* _CHECK_H */
|
||||
|
||||
Reference in New Issue
Block a user