[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] xen/arm: alternative: Don't call vmap() within stop_machine_run()
On Tue, 26 Apr 2022, Julien Grall wrote: > From: Julien Grall <jgrall@xxxxxxxxxx> > > Commit 88a037e2cfe1 "page_alloc: assert IRQs are enabled in heap > alloc/free" extended the checks in the buddy allocator to catch > any use of the helpers from context with interrupts disabled. > > Unfortunately, the rule is not followed in the alternative code and > this will result to crash at boot with debug enabled: > > (XEN) Xen call trace: > (XEN) [<0022a510>] alloc_xenheap_pages+0x120/0x150 (PC) > (XEN) [<00000000>] 00000000 (LR) > (XEN) [<002736ac>] arch/arm/mm.c#xen_pt_update+0x144/0x6e4 > (XEN) [<002740d4>] map_pages_to_xen+0x10/0x20 > (XEN) [<00236864>] __vmap+0x400/0x4a4 > (XEN) [<0026aee8>] > arch/arm/alternative.c#__apply_alternatives_multi_stop+0x144/0x1ec > (XEN) [<0022fe40>] stop_machine_run+0x23c/0x300 > (XEN) [<002c40c4>] apply_alternatives_all+0x34/0x5c > (XEN) [<002ce3e8>] start_xen+0xcb8/0x1024 > (XEN) [<00200068>] arch/arm/arm32/head.o#primary_switched+0xc/0x1c > > The interrupts will be disabled by the state machine in stop_machine_run(), > hence why the ASSERT is hit. > > For now the patch extending the checks has been reverted, but it would > be good to re-introduce it (allocation with interrupts disabled is not > desirable). > > So move the re-mapping of Xen to the caller of stop_machine_run(). > > Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> > Cc: David Vrabel <dvrabel@xxxxxxxxxxxx> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> > --- > > I managed to successfully boot Xen with this patch and dropping the > revert. > --- > xen/arch/arm/alternative.c | 34 +++++++++++++++++----------------- > 1 file changed, 17 insertions(+), 17 deletions(-) > > diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c > index 237c4e564209..f03cd943c636 100644 > --- a/xen/arch/arm/alternative.c > +++ b/xen/arch/arm/alternative.c > @@ -170,7 +170,7 @@ static int __apply_alternatives(const struct alt_region > *region, > * We might be patching the stop_machine state machine, so implement a > * really simple polling protocol here. > */ > -static int __apply_alternatives_multi_stop(void *unused) > +static int __apply_alternatives_multi_stop(void *xenmap) > { > static int patched = 0; > > @@ -185,22 +185,9 @@ static int __apply_alternatives_multi_stop(void *unused) > { > int ret; > struct alt_region region; > - mfn_t xen_mfn = virt_to_mfn(_start); > - paddr_t xen_size = _end - _start; > - unsigned int xen_order = get_order_from_bytes(xen_size); > - void *xenmap; > > BUG_ON(patched); > > - /* > - * The text and inittext section are read-only. So re-map Xen to > - * be able to patch the code. > - */ > - xenmap = __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR, > - VMAP_DEFAULT); > - /* Re-mapping Xen is not expected to fail during boot. */ > - BUG_ON(!xenmap); > - > region.begin = __alt_instructions; > region.end = __alt_instructions_end; > > @@ -208,8 +195,6 @@ static int __apply_alternatives_multi_stop(void *unused) > /* The patching is not expected to fail during boot. */ > BUG_ON(ret != 0); > > - vunmap(xenmap); > - > /* Barriers provided by the cache flushing */ > write_atomic(&patched, 1); > } > @@ -224,14 +209,29 @@ static int __apply_alternatives_multi_stop(void *unused) > void __init apply_alternatives_all(void) > { > int ret; > + mfn_t xen_mfn = virt_to_mfn(_start); > + paddr_t xen_size = _end - _start; > + unsigned int xen_order = get_order_from_bytes(xen_size); > + void *xenmap; > > ASSERT(system_state != SYS_STATE_active); > > + /* > + * The text and inittext section are read-only. So re-map Xen to > + * be able to patch the code. > + */ > + xenmap = __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR, > + VMAP_DEFAULT); > + /* Re-mapping Xen is not expected to fail during boot. */ > + BUG_ON(!xenmap); > + > /* better not try code patching on a live SMP system */ > - ret = stop_machine_run(__apply_alternatives_multi_stop, NULL, NR_CPUS); > + ret = stop_machine_run(__apply_alternatives_multi_stop, xenmap, NR_CPUS); > > /* stop_machine_run should never fail at this stage of the boot */ > BUG_ON(ret); > + > + vunmap(xenmap); > } > > int apply_alternatives(const struct alt_instr *start, const struct alt_instr > *end) > -- > 2.32.0 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |