mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/virtual-region: Rework how bugframe linkage works
The start/stop1/etc linkage scheme predates struct virtual_region, and as setup_virtual_regions() shows, it's awkward to express in the new scheme. Change the linker to provide explicit start/stop symbols for each bugframe type, and change virtual_region to have a stop pointer rather than a count. This marginally simplifies both do_bug_frame()s and prepare_payload(), but it massively simplifies setup_virtual_regions() by allowing the compiler to initialise the .frame[] array at build time. virtual_region.c is the only user of the linker symbols, and this is unlikely to change given the purpose of struct virtual_region, so move their externs out of bug.h No functional change. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Acked-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
337f11ea73
commit
3434518d05
7 files changed
+35
-44
No files matched your search
@@ -1226,10 +1226,9 @@ int do_bug_frame(const struct cpu_user_regs *regs, vaddr_t pc)
|
||||
for ( id = 0; id < BUGFRAME_NR; id++ )
|
||||
{
|
||||
const struct bug_frame *b;
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0, b = region->frame[id].bugs;
|
||||
i < region->frame[id].n_bugs; b++, i++ )
|
||||
for ( b = region->frame[id].start;
|
||||
b < region->frame[id].stop; b++ )
|
||||
{
|
||||
if ( ((vaddr_t)bug_loc(b)) == pc )
|
||||
{
|
||||
|
||||
+2
-3
@@ -25,10 +25,9 @@ int do_bug_frame(const struct cpu_user_regs *regs, unsigned long pc)
|
||||
for ( id = 0; id < BUGFRAME_NR; id++ )
|
||||
{
|
||||
const struct bug_frame *b;
|
||||
size_t i;
|
||||
|
||||
for ( i = 0, b = region->frame[id].bugs;
|
||||
i < region->frame[id].n_bugs; b++, i++ )
|
||||
for ( b = region->frame[id].start;
|
||||
b < region->frame[id].stop; b++ )
|
||||
{
|
||||
if ( bug_loc(b) == pc )
|
||||
{
|
||||
|
||||
@@ -804,12 +804,11 @@ static int prepare_payload(struct payload *payload,
|
||||
if ( !sec )
|
||||
continue;
|
||||
|
||||
if ( !section_ok(elf, sec, sizeof(*region->frame[i].bugs)) )
|
||||
if ( !section_ok(elf, sec, sizeof(*region->frame[i].start)) )
|
||||
return -EINVAL;
|
||||
|
||||
region->frame[i].bugs = sec->load_addr;
|
||||
region->frame[i].n_bugs = sec->sec->sh_size /
|
||||
sizeof(*region->frame[i].bugs);
|
||||
region->frame[i].start = sec->load_addr;
|
||||
region->frame[i].stop = sec->load_addr + sec->sec->sh_size;
|
||||
}
|
||||
|
||||
sec = livepatch_elf_sec_by_name(elf, ".altinstructions");
|
||||
|
||||
+20
-25
@@ -9,12 +9,25 @@
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/virtual_region.h>
|
||||
|
||||
extern const struct bug_frame
|
||||
__start_bug_frames_0[], __stop_bug_frames_0[],
|
||||
__start_bug_frames_1[], __stop_bug_frames_1[],
|
||||
__start_bug_frames_2[], __stop_bug_frames_2[],
|
||||
__start_bug_frames_3[], __stop_bug_frames_3[];
|
||||
|
||||
static struct virtual_region core = {
|
||||
.list = LIST_HEAD_INIT(core.list),
|
||||
.text_start = _stext,
|
||||
.text_end = _etext,
|
||||
.rodata_start = _srodata,
|
||||
.rodata_end = _erodata,
|
||||
|
||||
.frame = {
|
||||
{ __start_bug_frames_0, __stop_bug_frames_0 },
|
||||
{ __start_bug_frames_1, __stop_bug_frames_1 },
|
||||
{ __start_bug_frames_2, __stop_bug_frames_2 },
|
||||
{ __start_bug_frames_3, __stop_bug_frames_3 },
|
||||
},
|
||||
};
|
||||
|
||||
/* Becomes irrelevant when __init sections are cleared. */
|
||||
@@ -22,6 +35,13 @@ static struct virtual_region core_init __initdata = {
|
||||
.list = LIST_HEAD_INIT(core_init.list),
|
||||
.text_start = _sinittext,
|
||||
.text_end = _einittext,
|
||||
|
||||
.frame = {
|
||||
{ __start_bug_frames_0, __stop_bug_frames_0 },
|
||||
{ __start_bug_frames_1, __stop_bug_frames_1 },
|
||||
{ __start_bug_frames_2, __stop_bug_frames_2 },
|
||||
{ __start_bug_frames_3, __stop_bug_frames_3 },
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -133,31 +153,6 @@ void __init unregister_init_virtual_region(void)
|
||||
void __init setup_virtual_regions(const struct exception_table_entry *start,
|
||||
const struct exception_table_entry *end)
|
||||
{
|
||||
size_t sz;
|
||||
unsigned int i;
|
||||
static const struct bug_frame *const __initconstrel bug_frames[] = {
|
||||
__start_bug_frames,
|
||||
__stop_bug_frames_0,
|
||||
__stop_bug_frames_1,
|
||||
__stop_bug_frames_2,
|
||||
__stop_bug_frames_3,
|
||||
NULL
|
||||
};
|
||||
|
||||
for ( i = 1; bug_frames[i]; i++ )
|
||||
{
|
||||
const struct bug_frame *s;
|
||||
|
||||
s = bug_frames[i - 1];
|
||||
sz = bug_frames[i] - s;
|
||||
|
||||
core.frame[i - 1].n_bugs = sz;
|
||||
core.frame[i - 1].bugs = s;
|
||||
|
||||
core_init.frame[i - 1].n_bugs = sz;
|
||||
core_init.frame[i - 1].bugs = s;
|
||||
}
|
||||
|
||||
core_init.ex = core.ex = start;
|
||||
core_init.ex_end = core.ex_end = end;
|
||||
|
||||
|
||||
@@ -155,12 +155,6 @@ int do_bug_frame(const struct cpu_user_regs *regs, unsigned long pc);
|
||||
|
||||
#endif /* CONFIG_GENERIC_BUG_FRAME */
|
||||
|
||||
extern const struct bug_frame __start_bug_frames[],
|
||||
__stop_bug_frames_0[],
|
||||
__stop_bug_frames_1[],
|
||||
__stop_bug_frames_2[],
|
||||
__stop_bug_frames_3[];
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __XEN_BUG_H__ */
|
||||
|
||||
@@ -29,8 +29,7 @@ struct virtual_region
|
||||
symbols_lookup_t *symbols_lookup;
|
||||
|
||||
struct {
|
||||
const struct bug_frame *bugs; /* The pointer to array of bug frames. */
|
||||
size_t n_bugs; /* The number of them. */
|
||||
const struct bug_frame *start, *stop; /* Pointers to array of bug frames. */
|
||||
} frame[BUGFRAME_NR];
|
||||
|
||||
const struct exception_table_entry *ex;
|
||||
|
||||
@@ -115,13 +115,19 @@
|
||||
/* List of constructs other than *_SECTIONS in alphabetical order. */
|
||||
|
||||
#define BUGFRAMES \
|
||||
__start_bug_frames = .; \
|
||||
__start_bug_frames_0 = .; \
|
||||
*(.bug_frames.0) \
|
||||
__stop_bug_frames_0 = .; \
|
||||
\
|
||||
__start_bug_frames_1 = .; \
|
||||
*(.bug_frames.1) \
|
||||
__stop_bug_frames_1 = .; \
|
||||
\
|
||||
__start_bug_frames_2 = .; \
|
||||
*(.bug_frames.2) \
|
||||
__stop_bug_frames_2 = .; \
|
||||
\
|
||||
__start_bug_frames_3 = .; \
|
||||
*(.bug_frames.3) \
|
||||
__stop_bug_frames_3 = .;
|
||||
|
||||
|
||||