[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 28/36] xen/arm: introduce xen_map_text_rw
From: Luca Miccio <lucmiccio@xxxxxxxxx> Introduce two new arm specific functions to temporarily map/unmap the Xen text read-write (the Xen text is mapped read-only by default by setup_pagetables): xen_map_text_rw and xen_unmap_text_rw. There is only one caller in the alternative framework. The non-colored implementation simply uses __vmap to do the mapping. In other words, there are no changes to the non-colored case. The colored implementation calculates Xen text physical addresses appropriately, according to the coloring configuration. Export vm_alloc because it is needed by the colored implementation of xen_map_text_rw. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx> Signed-off-by: Luca Miccio <lucmiccio@xxxxxxxxx> --- xen/arch/arm/alternative.c | 8 ++------ xen/arch/arm/include/asm/mm.h | 3 +++ xen/arch/arm/mm.c | 38 +++++++++++++++++++++++++++++++++++ xen/common/vmap.c | 4 ++-- xen/include/xen/vmap.h | 2 ++ 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c index 237c4e5642..2481521c9c 100644 --- a/xen/arch/arm/alternative.c +++ b/xen/arch/arm/alternative.c @@ -185,9 +185,6 @@ 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); @@ -196,8 +193,7 @@ static int __apply_alternatives_multi_stop(void *unused) * 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); + xenmap = xen_map_text_rw(); /* Re-mapping Xen is not expected to fail during boot. */ BUG_ON(!xenmap); @@ -208,7 +204,7 @@ static int __apply_alternatives_multi_stop(void *unused) /* The patching is not expected to fail during boot. */ BUG_ON(ret != 0); - vunmap(xenmap); + xen_unmap_text_rw(xenmap); /* Barriers provided by the cache flushing */ write_atomic(&patched, 1); diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h index 1422091436..defb1efaad 100644 --- a/xen/arch/arm/include/asm/mm.h +++ b/xen/arch/arm/include/asm/mm.h @@ -195,6 +195,9 @@ extern void mmu_init_secondary_cpu(void); extern void setup_xenheap_mappings(unsigned long base_mfn, unsigned long nr_mfns); /* Map a frame table to cover physical addresses ps through pe */ extern void setup_frametable_mappings(paddr_t ps, paddr_t pe); +/* Create temporary Xen text read-write mapping */ +extern void *xen_map_text_rw(void); +extern void xen_unmap_text_rw(void *va); /* Map a 4k page in a fixmap entry */ extern void set_fixmap(unsigned map, mfn_t mfn, unsigned attributes); /* Remove a mapping from a fixmap entry */ diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 53ea13641b..b18c7cd373 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -637,6 +637,31 @@ static void clear_table(void *table) } #ifdef CONFIG_COLORING +void* __init xen_map_text_rw(void) +{ + paddr_t xen_paddr = __pa(_start); + unsigned int xen_size = 1 << get_order_from_bytes(_end - _start); + void *va = vm_alloc(xen_size, 1, VMAP_DEFAULT); + unsigned long cur = (unsigned long)va; + mfn_t mfn_col; + unsigned int i; + + for ( i = 0; i < xen_size; i++, cur += PAGE_SIZE ) + { + xen_paddr = next_xen_colored(xen_paddr); + mfn_col = maddr_to_mfn(xen_paddr); + if ( map_pages_to_xen(cur, mfn_col, 1, PAGE_HYPERVISOR) ) + return NULL; + xen_paddr += PAGE_SIZE; + } + return va; +} + +void __init xen_unmap_text_rw(void *va) +{ + vunmap(va); +} + /* * Translate a Xen (.text) virtual address to the colored physical one * depending on the hypervisor configuration. @@ -796,6 +821,19 @@ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr) xen_pt_enforce_wnx(); } #else +void* __init xen_map_text_rw(void) +{ + unsigned int xen_order = get_order_from_bytes(_end - _start); + mfn_t xen_mfn = virt_to_mfn(_start); + return __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR, + VMAP_DEFAULT); +} + +void __init xen_unmap_text_rw(void *va) +{ + vunmap(va); +} + /* Boot-time pagetable setup. * Changes here may need matching changes in head.S */ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr) diff --git a/xen/common/vmap.c b/xen/common/vmap.c index 4fd6b3067e..bedfc9d418 100644 --- a/xen/common/vmap.c +++ b/xen/common/vmap.c @@ -45,8 +45,8 @@ void __init vm_init_type(enum vmap_region type, void *start, void *end) populate_pt_range(va, vm_low[type] - nr); } -static void *vm_alloc(unsigned int nr, unsigned int align, - enum vmap_region t) +void *vm_alloc(unsigned int nr, unsigned int align, + enum vmap_region t) { unsigned int start, bit; diff --git a/xen/include/xen/vmap.h b/xen/include/xen/vmap.h index b0f7632e89..dcf2be692f 100644 --- a/xen/include/xen/vmap.h +++ b/xen/include/xen/vmap.h @@ -12,6 +12,8 @@ enum vmap_region { void vm_init_type(enum vmap_region type, void *start, void *end); +void *vm_alloc(unsigned int nr, unsigned int align, + enum vmap_region t); void *__vmap(const mfn_t *mfn, unsigned int granularity, unsigned int nr, unsigned int align, unsigned int flags, enum vmap_region); void *vmap(const mfn_t *mfn, unsigned int nr); -- 2.30.2
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |