[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 19/22] x86/mm: introduce a per-CPU fixmap area
Introduce the logic to manage a per-CPU fixmap area. This includes adding a new set of headers that are capable of creating mappings in the per-CPU page-table regions by making use of the map_pages_to_xen_cpu(). This per-CPU fixmap area is currently set to use one L3 slot: 1GiB of linear address space. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/include/asm/fixmap.h | 44 +++++++++++++++++++++++++++++++ xen/arch/x86/mm.c | 16 ++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/include/asm/fixmap.h b/xen/arch/x86/include/asm/fixmap.h index 516ec3fa6c95..a456c65072d8 100644 --- a/xen/arch/x86/include/asm/fixmap.h +++ b/xen/arch/x86/include/asm/fixmap.h @@ -118,6 +118,50 @@ extern void __set_fixmap_x( #define __fix_x_to_virt(x) (FIXADDR_X_TOP - ((x) << PAGE_SHIFT)) #define fix_x_to_virt(x) ((void *)__fix_x_to_virt(x)) +/* per-CPU fixmap area. */ +enum percpu_fixed_addresses { + __end_of_percpu_fixed_addresses +}; + +#define PERCPU_FIXADDR_SIZE (__end_of_percpu_fixed_addresses << PAGE_SHIFT) +#define PERCPU_FIXADDR PERCPU_VIRT_SLOT(0) + +static inline void *percpu_fix_to_virt(enum percpu_fixed_addresses idx) +{ + BUG_ON(idx >=__end_of_percpu_fixed_addresses); + return (void *)PERCPU_FIXADDR + (idx << PAGE_SHIFT); +} + +static inline void percpu_set_fixmap_remote( + unsigned int cpu, enum percpu_fixed_addresses idx, mfn_t mfn, + unsigned long flags) +{ + map_pages_to_xen_cpu((unsigned long)percpu_fix_to_virt(idx), mfn, 1, flags, + cpu); +} + +static inline void percpu_clear_fixmap_remote( + unsigned int cpu, enum percpu_fixed_addresses idx) +{ + /* + * Use map_pages_to_xen_cpu() instead of destroy_xen_mappings_cpu() to + * avoid tearing down the intermediate page-tables if empty. + */ + map_pages_to_xen_cpu((unsigned long)percpu_fix_to_virt(idx), INVALID_MFN, 1, + 0, cpu); +} + +static inline void percpu_set_fixmap(enum percpu_fixed_addresses idx, mfn_t mfn, + unsigned long flags) +{ + percpu_set_fixmap_remote(smp_processor_id(), idx, mfn, flags); +} + +static inline void percpu_clear_fixmap(enum percpu_fixed_addresses idx) +{ + percpu_clear_fixmap_remote(smp_processor_id(), idx); +} + #endif /* __ASSEMBLY__ */ #endif diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index faf2d42745d1..937089d203cc 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -6467,7 +6467,17 @@ int allocate_perdomain_local_l3(unsigned int cpu) per_cpu(local_l3, cpu) = l3; - return 0; + /* + * Pre-allocate the page-table structures for the per-cpu fixmap. Some of + * the per-cpu fixmap calls might happen in contexts where memory + * allocation is not possible. + * + * Only one L3 slot is currently reserved for the per-CPU fixmap. + */ + BUILD_BUG_ON(PERCPU_FIXADDR_SIZE > (1 << L3_PAGETABLE_SHIFT)); + return map_pages_to_xen_cpu(PERCPU_VIRT_START, INVALID_MFN, + PFN_DOWN(PERCPU_FIXADDR_SIZE), MAP_SMALL_PAGES, + cpu); } void free_perdomain_local_l3(unsigned int cpu) @@ -6478,6 +6488,10 @@ void free_perdomain_local_l3(unsigned int cpu) return; per_cpu(local_l3, cpu) = NULL; + + destroy_xen_mappings_cpu(PERCPU_VIRT_START, + PERCPU_VIRT_START + PERCPU_FIXADDR_SIZE, cpu); + free_xenheap_page(l3); } -- 2.45.2
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |