[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 08/16] x86: add Persistent Map (PMAP) infrastructure
From: Wei Liu <wei.liu2@xxxxxxxxxx> The basic idea is like Persistent Kernel Map (PKMAP) in linux. We pre-populate all the relevant page tables before system is fully set up. It is needed to bootstrap map domain page infrastructure -- we need some way to map pages to set up the mapcache without a direct map. This infrastructure is not lock-protected therefore can only be used before smpboot. After smpboot, mapcache has to be used. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Signed-off-by: Hongyan Xia <hongyxia@xxxxxxxxxx> --- xen/arch/x86/Makefile | 1 + xen/arch/x86/pmap.c | 87 ++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/fixmap.h | 3 ++ xen/include/asm-x86/pmap.h | 10 +++++ 4 files changed, 101 insertions(+) create mode 100644 xen/arch/x86/pmap.c create mode 100644 xen/include/asm-x86/pmap.h diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 44137d919b..c8e565867b 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -52,6 +52,7 @@ obj-y += pci.o obj-y += percpu.o obj-y += physdev.o x86_64/physdev.o obj-y += platform_hypercall.o x86_64/platform_hypercall.o +obj-bin-y += pmap.init.o obj-y += psr.o obj-y += setup.o obj-y += shutdown.o diff --git a/xen/arch/x86/pmap.c b/xen/arch/x86/pmap.c new file mode 100644 index 0000000000..44d02ece89 --- /dev/null +++ b/xen/arch/x86/pmap.c @@ -0,0 +1,87 @@ +#include <xen/init.h> +#include <xen/mm.h> +#include <xen/spinlock.h> + +#include <asm/bitops.h> +#include <asm/fixmap.h> +#include <asm/flushtlb.h> + +/* + * Simple mapping infrastructure to map / unmap pages in fixed map. + * This is used to set up the page table for mapcache, which is used + * by map domain page infrastructure. + * + * This structure is not protected by any locks, so it must not be used after + * smp bring-up. + */ + +/* Bitmap to track which slot is used */ +static unsigned long __initdata inuse; + +void *__init pmap_map(mfn_t mfn) +{ + unsigned long flags; + unsigned int idx; + void *linear = NULL; + enum fixed_addresses slot; + l1_pgentry_t *pl1e; + + BUILD_BUG_ON(sizeof(inuse) * BITS_PER_LONG < NUM_FIX_PMAP); + + ASSERT(system_state < SYS_STATE_smp_boot); + + local_irq_save(flags); + + idx = find_first_zero_bit(&inuse, NUM_FIX_PMAP); + if ( idx == NUM_FIX_PMAP ) + panic("Out of PMAP slots\n"); + + __set_bit(idx, &inuse); + + slot = idx + FIX_PMAP_BEGIN; + ASSERT(slot >= FIX_PMAP_BEGIN && slot <= FIX_PMAP_END); + + linear = fix_to_virt(slot); + /* + * We cannot use set_fixmap() here. We use PMAP when there is no direct map, + * so map_pages_to_xen() called by set_fixmap() needs to map pages on + * demand, which then calls pmap() again, resulting in a loop. Modify the + * PTEs directly instead. The same is true for pmap_unmap(). + */ + pl1e = &l1_fixmap[l1_table_offset((unsigned long)linear)]; + l1e_write_atomic(pl1e, l1e_from_mfn(mfn, PAGE_HYPERVISOR)); + + local_irq_restore(flags); + + return linear; +} + +void __init pmap_unmap(void *p) +{ + unsigned long flags; + unsigned int idx; + l1_pgentry_t *pl1e; + enum fixed_addresses slot = __virt_to_fix((unsigned long)p); + + ASSERT(system_state < SYS_STATE_smp_boot); + ASSERT(slot >= FIX_PMAP_BEGIN && slot <= FIX_PMAP_END); + + idx = slot - FIX_PMAP_BEGIN; + local_irq_save(flags); + + __clear_bit(idx, &inuse); + pl1e = &l1_fixmap[l1_table_offset((unsigned long)p)]; + l1e_write_atomic(pl1e, l1e_empty()); + flush_tlb_one_local(p); + + local_irq_restore(flags); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h index 8330097a74..000f3b3375 100644 --- a/xen/include/asm-x86/fixmap.h +++ b/xen/include/asm-x86/fixmap.h @@ -24,6 +24,7 @@ #include <xen/kexec.h> #include <asm/apicdef.h> #include <asm/msi.h> +#include <asm/pmap.h> #include <acpi/apei.h> /* @@ -49,6 +50,8 @@ enum fixed_addresses { FIX_XEN_SHARED_INFO, #endif /* CONFIG_XEN_GUEST */ /* Everything else should go further down. */ + FIX_PMAP_BEGIN, + FIX_PMAP_END = FIX_PMAP_BEGIN + NUM_FIX_PMAP - 1, FIX_APIC_BASE, FIX_IO_APIC_BASE_0, FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, diff --git a/xen/include/asm-x86/pmap.h b/xen/include/asm-x86/pmap.h new file mode 100644 index 0000000000..790cd71fb3 --- /dev/null +++ b/xen/include/asm-x86/pmap.h @@ -0,0 +1,10 @@ +#ifndef __X86_PMAP_H__ +#define __X86_PMAP_H__ + +/* Large enough for mapping 5 levels of page tables with some headroom */ +#define NUM_FIX_PMAP 8 + +void *pmap_map(mfn_t mfn); +void pmap_unmap(void *p); + +#endif /* __X86_PMAP_H__ */ -- 2.24.1.AMZN
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |