[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 10/22] mini-os: make p2m related code depend on CONFIG_PARAVIRT
All handling related to p2m is needed for paravirtualized environment only. So put all functions operating on p2m list in #ifdef CONFIG_PARAVIRT sections. Add a paravirt.h header defining dummy functions for non-paravirtualized environments. Instead of using references to start_info use dedicated variables initialized from start_info on boot. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- arch/arm/balloon.c | 5 --- arch/arm/mm.c | 4 --- arch/x86/balloon.c | 13 ++++++++ arch/x86/mm.c | 67 +++++++++++++++++++++++++++++---------- arch/x86/setup.c | 6 ++-- arch/x86/traps.c | 6 ++-- balloon.c | 1 + include/arm/arch_mm.h | 3 -- include/balloon.h | 3 -- include/mm.h | 2 +- include/paravirt.h | 48 ++++++++++++++++++++++++++++ include/x86/arch_mm.h | 40 +++++------------------ include/xen/arch-x86/xen-x86_32.h | 2 ++ include/xen/arch-x86/xen-x86_64.h | 2 ++ mm.c | 1 + 15 files changed, 133 insertions(+), 70 deletions(-) diff --git a/arch/arm/balloon.c b/arch/arm/balloon.c index 7f35328..958ecba 100644 --- a/arch/arm/balloon.c +++ b/arch/arm/balloon.c @@ -27,11 +27,6 @@ unsigned long virt_kernel_area_end; /* TODO: find a virtual area */ -int arch_expand_p2m(unsigned long max_pfn) -{ - return 0; -} - void arch_pfn_add(unsigned long pfn, unsigned long mfn) { } diff --git a/arch/arm/mm.c b/arch/arm/mm.c index fc8d4bc..4f58fc7 100644 --- a/arch/arm/mm.c +++ b/arch/arm/mm.c @@ -72,10 +72,6 @@ void arch_init_mm(unsigned long *start_pfn_p, unsigned long *max_pfn_p) *max_pfn_p = to_phys(new_device_tree) >> PAGE_SHIFT; } -void arch_init_p2m(unsigned long max_pfn) -{ -} - void arch_init_demand_mapping_area(void) { } diff --git a/arch/x86/balloon.c b/arch/x86/balloon.c index 42389e4..16aaae4 100644 --- a/arch/x86/balloon.c +++ b/arch/x86/balloon.c @@ -26,11 +26,13 @@ #include <mini-os/errno.h> #include <mini-os/lib.h> #include <mini-os/mm.h> +#include <mini-os/paravirt.h> #ifdef CONFIG_BALLOON unsigned long virt_kernel_area_end = VIRT_KERNEL_AREA; +#ifdef CONFIG_PARAVIRT static void p2m_invalidate(unsigned long *list, unsigned long start_idx) { unsigned long idx; @@ -143,5 +145,16 @@ void arch_pfn_add(unsigned long pfn, unsigned long mfn) do_exit(); } } +#else +void arch_pfn_add(unsigned long pfn, unsigned long mfn) +{ + pgentry_t *pgt; + + pgt = need_pgt((unsigned long)pfn_to_virt(pfn)); + ASSERT(pgt); + if ( !(*pgt & _PAGE_PSE) ) + *pgt = (pgentry_t)(mfn << PAGE_SHIFT) | _PAGE_PRESENT | _PAGE_RW; +} +#endif #endif diff --git a/arch/x86/mm.c b/arch/x86/mm.c index fe18f53..0543017 100644 --- a/arch/x86/mm.c +++ b/arch/x86/mm.c @@ -39,6 +39,7 @@ #include <mini-os/hypervisor.h> #include <mini-os/balloon.h> #include <mini-os/mm.h> +#include <mini-os/paravirt.h> #include <mini-os/types.h> #include <mini-os/lib.h> #include <mini-os/xmalloc.h> @@ -53,10 +54,24 @@ unsigned long *phys_to_machine_mapping; unsigned long mfn_zero; +pgentry_t *pt_base; +static unsigned long first_free_pfn; +static unsigned long last_free_pfn; + extern char stack[]; extern void page_walk(unsigned long va); -#ifndef CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT +void arch_mm_preinit(void *p) +{ + start_info_t *si = p; + + phys_to_machine_mapping = (unsigned long *)si->mfn_list; + pt_base = (pgentry_t *)si->pt_base; + first_free_pfn = PFN_UP(to_phys(pt_base)) + si->nr_pt_frames; + last_free_pfn = si->nr_pages; +} +#else #include <mini-os/desc.h> user_desc gdt[NR_GDT_ENTRIES] = { @@ -85,6 +100,22 @@ desc_ptr idt_ptr = .limit = sizeof(idt) - 1, .base = (unsigned long)&idt, }; + +void arch_mm_preinit(void *p) +{ + long ret; + domid_t domid = DOMID_SELF; + + pt_base = page_table_base; + first_free_pfn = PFN_UP(to_phys(&_end)); + ret = HYPERVISOR_memory_op(XENMEM_current_reservation, &domid); + if ( ret < 0 ) + { + xprintk("could not get memory size\n"); + do_exit(); + } + last_free_pfn = ret; +} #endif /* @@ -95,7 +126,7 @@ desc_ptr idt_ptr = static void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, unsigned long offset, unsigned long level) { - pgentry_t *tab = (pgentry_t *)start_info.pt_base; + pgentry_t *tab = pt_base; unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); pgentry_t prot_e, prot_t; mmu_update_t mmu_updates[1]; @@ -172,8 +203,8 @@ static void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) unsigned long start_address, end_address; unsigned long pfn_to_map, pt_pfn = *start_pfn; static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; - pgentry_t *tab = (pgentry_t *)start_info.pt_base, page; - unsigned long pt_mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base)); + pgentry_t *tab = pt_base, page; + unsigned long pt_mfn = pfn_to_mfn(virt_to_pfn(pt_base)); unsigned long offset; int count = 0; int rc; @@ -182,6 +213,7 @@ static void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) mapped, start the loop at the very beginning. */ pfn_to_map = *start_pfn; +#ifdef CONFIG_PARAVIRT if ( *max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START) ) { printk("WARNING: Mini-OS trying to use Xen virtual space. " @@ -193,6 +225,7 @@ static void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20); } +#endif start_address = (unsigned long)pfn_to_virt(pfn_to_map); end_address = (unsigned long)pfn_to_virt(*max_pfn); @@ -202,8 +235,8 @@ static void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) while ( start_address < end_address ) { - tab = (pgentry_t *)start_info.pt_base; - pt_mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base)); + tab = pt_base; + pt_mfn = pfn_to_mfn(virt_to_pfn(pt_base)); #if defined(__x86_64__) offset = l4_table_offset(start_address); @@ -270,8 +303,8 @@ static void set_readonly(void *text, void *etext) ((unsigned long) text + PAGE_SIZE - 1) & PAGE_MASK; unsigned long end_address = (unsigned long) etext; static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; - pgentry_t *tab = (pgentry_t *)start_info.pt_base, page; - unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base)); + pgentry_t *tab = pt_base, page; + unsigned long mfn = pfn_to_mfn(virt_to_pfn(pt_base)); unsigned long offset; int count = 0; int rc; @@ -280,8 +313,8 @@ static void set_readonly(void *text, void *etext) while ( start_address + PAGE_SIZE <= end_address ) { - tab = (pgentry_t *)start_info.pt_base; - mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base)); + tab = pt_base; + mfn = pfn_to_mfn(virt_to_pfn(pt_base)); #if defined(__x86_64__) offset = l4_table_offset(start_address); @@ -343,8 +376,8 @@ static pgentry_t *get_pgt(unsigned long va) pgentry_t *tab; unsigned offset; - tab = (pgentry_t *)start_info.pt_base; - mfn = virt_to_mfn(start_info.pt_base); + tab = pt_base; + mfn = virt_to_mfn(pt_base); #if defined(__x86_64__) offset = l4_table_offset(va); @@ -379,8 +412,8 @@ pgentry_t *need_pgt(unsigned long va) unsigned long pt_pfn; unsigned offset; - tab = (pgentry_t *)start_info.pt_base; - pt_mfn = virt_to_mfn(start_info.pt_base); + tab = pt_base; + pt_mfn = virt_to_mfn(pt_base); #if defined(__x86_64__) offset = l4_table_offset(va); @@ -639,6 +672,7 @@ static void clear_bootstrap(void) printk("Unable to unmap NULL page. rc=%d\n", rc); } +#ifdef CONFIG_PARAVIRT void p2m_chk_pfn(unsigned long pfn) { if ( (pfn >> L3_P2M_SHIFT) > 0 ) @@ -670,6 +704,7 @@ void arch_init_p2m(unsigned long max_pfn) arch_remap_p2m(max_pfn); } +#endif void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) { @@ -683,8 +718,8 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) printk(" _end: %p(VA)\n", &_end); /* First page follows page table pages. */ - start_pfn = PFN_UP(to_phys(start_info.pt_base)) + start_info.nr_pt_frames; - max_pfn = start_info.nr_pages; + start_pfn = first_free_pfn; + max_pfn = last_free_pfn; if ( max_pfn >= MAX_MEM_SIZE / PAGE_SIZE ) max_pfn = MAX_MEM_SIZE / PAGE_SIZE - 1; diff --git a/arch/x86/setup.c b/arch/x86/setup.c index efecefb..8b6bb6e 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -131,6 +131,9 @@ arch_init(void *par) /* Initialize SSE */ sse_init(); + /* Setup memory management info from start_info. */ + arch_mm_preinit(par); + /* Copy the start_info struct to a globally-accessible area. */ /* WARN: don't do printk before here, it uses information from shared_info. Use xprintk instead. */ @@ -152,9 +155,6 @@ arch_init(void *par) si->cmd_line ? (const char *)si->cmd_line : "NULL"); printk(" stack: %p-%p\n", stack, stack + sizeof(stack)); - /* set up minimal memory infos */ - phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; - /* Grab the shared_info pointer and put it in a safe place. */ HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); diff --git a/arch/x86/traps.c b/arch/x86/traps.c index 0b3d85b..2d3222d 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -97,9 +97,9 @@ DO_ERROR(18, "machine check", machine_check) void page_walk(unsigned long virt_address) { - pgentry_t *tab = (pgentry_t *)start_info.pt_base, page; + pgentry_t *tab = pt_base, page; unsigned long addr = virt_address; - printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base); + printk("Pagetable walk from virt %lx, base %p:\n", virt_address, pt_base); #if defined(__x86_64__) page = tab[l4_table_offset(addr)]; @@ -119,7 +119,7 @@ void page_walk(unsigned long virt_address) } static int handle_cow(unsigned long addr) { - pgentry_t *tab = (pgentry_t *)start_info.pt_base, page; + pgentry_t *tab = pt_base, page; unsigned long new_page; int rc; diff --git a/balloon.c b/balloon.c index 608492a..8d2f151 100644 --- a/balloon.c +++ b/balloon.c @@ -25,6 +25,7 @@ #include <mini-os/balloon.h> #include <mini-os/errno.h> #include <mini-os/lib.h> +#include <mini-os/paravirt.h> #include <xen/xen.h> #include <xen/memory.h> diff --git a/include/arm/arch_mm.h b/include/arm/arch_mm.h index f4685d8..79d9e05 100644 --- a/include/arm/arch_mm.h +++ b/include/arm/arch_mm.h @@ -29,9 +29,6 @@ extern uint32_t physical_address_offset; /* Add this to a virtual address to get #define mfn_to_virt(_mfn) (to_virt(PFN_PHYS(_mfn))) #define pfn_to_virt(_pfn) (to_virt(PFN_PHYS(_pfn))) -#define mfn_to_pfn(x) (x) -#define pfn_to_mfn(x) (x) - #define virtual_to_mfn(_virt) virt_to_mfn(_virt) // FIXME diff --git a/include/balloon.h b/include/balloon.h index d8710ad..8cd41af 100644 --- a/include/balloon.h +++ b/include/balloon.h @@ -39,16 +39,13 @@ extern unsigned long nr_mem_pages; void get_max_pages(void); int balloon_up(unsigned long n_pages); -void arch_remap_p2m(unsigned long max_pfn); void mm_alloc_bitmap_remap(void); -int arch_expand_p2m(unsigned long max_pfn); void arch_pfn_add(unsigned long pfn, unsigned long mfn); int chk_free_pages(unsigned long needed); #else /* CONFIG_BALLOON */ static inline void get_max_pages(void) { } -static inline void arch_remap_p2m(unsigned long max_pfn) { } static inline void mm_alloc_bitmap_remap(void) { } static inline int chk_free_pages(unsigned long needed) { diff --git a/include/mm.h b/include/mm.h index fc3128b..953570c 100644 --- a/include/mm.h +++ b/include/mm.h @@ -36,6 +36,7 @@ #endif #include <xen/xen.h> +#include <mini-os/paravirt.h> #include <mini-os/arch_limits.h> #include <mini-os/arch_mm.h> @@ -67,7 +68,6 @@ static __inline__ int get_order(unsigned long size) void arch_init_demand_mapping_area(void); void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p); -void arch_init_p2m(unsigned long max_pfn_p); unsigned long allocate_ondemand(unsigned long n, unsigned long alignment); /* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */ diff --git a/include/paravirt.h b/include/paravirt.h index 7852e16..15076be 100644 --- a/include/paravirt.h +++ b/include/paravirt.h @@ -26,7 +26,55 @@ #if defined(CONFIG_PARAVIRT) +#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)]) +#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)]) + +/* for P2M */ +#ifdef __x86_64__ +#define P2M_SHIFT 9 #else +#define P2M_SHIFT 10 +#endif +#define P2M_ENTRIES (1UL << P2M_SHIFT) +#define P2M_MASK (P2M_ENTRIES - 1) +#define L1_P2M_SHIFT P2M_SHIFT +#define L2_P2M_SHIFT (2 * P2M_SHIFT) +#define L3_P2M_SHIFT (3 * P2M_SHIFT) +#define L1_P2M_IDX(pfn) ((pfn) & P2M_MASK) +#define L2_P2M_IDX(pfn) (((pfn) >> L1_P2M_SHIFT) & P2M_MASK) +#define L3_P2M_IDX(pfn) (((pfn) >> L2_P2M_SHIFT) & P2M_MASK) +#define INVALID_P2M_ENTRY (~0UL) + +void p2m_chk_pfn(unsigned long pfn); + +static inline unsigned long p2m_pages(unsigned long pages) +{ + return (pages + P2M_ENTRIES - 1) >> L1_P2M_SHIFT; +} + +void arch_init_p2m(unsigned long max_pfn_p); + +#else + +#define mfn_to_pfn(_mfn) ((unsigned long)(_mfn)) +#define pfn_to_mfn(_pfn) ((unsigned long)(_pfn)) + +static inline void arch_init_p2m(unsigned long max_pfn_p) { } + +#endif + +#if defined(CONFIG_PARAVIRT) && defined(CONFIG_BALLOON) + +void arch_remap_p2m(unsigned long max_pfn); +int arch_expand_p2m(unsigned long max_pfn); + +#else + +static inline void arch_remap_p2m(unsigned long max_pfn) { } +static inline int arch_expand_p2m(unsigned long max_pfn) +{ + return 0; +} #endif diff --git a/include/x86/arch_mm.h b/include/x86/arch_mm.h index 2b18b34..28ab406 100644 --- a/include/x86/arch_mm.h +++ b/include/x86/arch_mm.h @@ -184,31 +184,6 @@ typedef unsigned long pgentry_t; #define IO_PROT (L1_PROT) #define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD) -/* for P2M */ -#ifdef __x86_64__ -#define P2M_SHIFT 9 -#else -#define P2M_SHIFT 10 -#endif -#define P2M_ENTRIES (1UL << P2M_SHIFT) -#define P2M_MASK (P2M_ENTRIES - 1) -#define L1_P2M_SHIFT P2M_SHIFT -#define L2_P2M_SHIFT (2 * P2M_SHIFT) -#define L3_P2M_SHIFT (3 * P2M_SHIFT) -#define L1_P2M_IDX(pfn) ((pfn) & P2M_MASK) -#define L2_P2M_IDX(pfn) (((pfn) >> L1_P2M_SHIFT) & P2M_MASK) -#define L3_P2M_IDX(pfn) (((pfn) >> L2_P2M_SHIFT) & P2M_MASK) -#define INVALID_P2M_ENTRY (~0UL) - -#ifndef __ASSEMBLY__ -void p2m_chk_pfn(unsigned long pfn); - -static inline unsigned long p2m_pages(unsigned long pages) -{ - return (pages + P2M_ENTRIES - 1) >> L1_P2M_SHIFT; -} -#endif - #include "arch_limits.h" #define PAGE_SIZE __PAGE_SIZE #define PAGE_SHIFT __PAGE_SHIFT @@ -232,10 +207,14 @@ typedef unsigned long paddr_t; typedef unsigned long maddr_t; #endif +extern pgentry_t *pt_base; +#ifdef CONFIG_PARAVIRT extern unsigned long *phys_to_machine_mapping; +#else +extern pgentry_t page_table_base[]; +#endif extern char _text, _etext, _erodata, _edata, _end; extern unsigned long mfn_zero; -#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)]) static __inline__ maddr_t phys_to_machine(paddr_t phys) { maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT); @@ -243,7 +222,6 @@ static __inline__ maddr_t phys_to_machine(paddr_t phys) return machine; } -#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)]) static __inline__ paddr_t machine_to_phys(maddr_t machine) { paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT); @@ -267,13 +245,10 @@ static __inline__ paddr_t machine_to_phys(maddr_t machine) #define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT) #define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT) - -#define PT_BASE ((pgentry_t *)start_info.pt_base) - #ifdef __x86_64__ -#define virtual_to_l3(_virt) ((pgentry_t *)pte_to_virt(PT_BASE[l4_table_offset(_virt)])) +#define virtual_to_l3(_virt) ((pgentry_t *)pte_to_virt(pt_base[l4_table_offset(_virt)])) #else -#define virtual_to_l3(_virt) PT_BASE +#define virtual_to_l3(_virt) pt_base #endif #define virtual_to_l2(_virt) ({ \ @@ -297,6 +272,7 @@ static __inline__ paddr_t machine_to_phys(maddr_t machine) #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, NULL, L1_PROT_RO) pgentry_t *need_pgt(unsigned long addr); +void arch_mm_preinit(void *p); #endif diff --git a/include/xen/arch-x86/xen-x86_32.h b/include/xen/arch-x86/xen-x86_32.h index 1504191..6339727 100644 --- a/include/xen/arch-x86/xen-x86_32.h +++ b/include/xen/arch-x86/xen-x86_32.h @@ -55,6 +55,7 @@ #define FLAT_USER_DS FLAT_RING3_DS #define FLAT_USER_SS FLAT_RING3_SS +#ifdef CONFIG_PARAVIRT #define __HYPERVISOR_VIRT_START_PAE 0xF5800000 #define __MACH2PHYS_VIRT_START_PAE 0xF5800000 #define __MACH2PHYS_VIRT_END_PAE 0xF6800000 @@ -90,6 +91,7 @@ #ifndef machine_to_phys_mapping #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) #endif +#endif /* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ #if defined(__XEN__) || defined(__XEN_TOOLS__) diff --git a/include/xen/arch-x86/xen-x86_64.h b/include/xen/arch-x86/xen-x86_64.h index 1c4e159..2c00111 100644 --- a/include/xen/arch-x86/xen-x86_64.h +++ b/include/xen/arch-x86/xen-x86_64.h @@ -70,6 +70,7 @@ #define FLAT_USER_SS32 FLAT_RING3_SS32 #define FLAT_USER_SS FLAT_USER_SS64 +#ifdef CONFIG_PARAVIRT #define __HYPERVISOR_VIRT_START 0xFFFF800000000000 #define __HYPERVISOR_VIRT_END 0xFFFF880000000000 #define __MACH2PHYS_VIRT_START 0xFFFF800000000000 @@ -86,6 +87,7 @@ #ifndef machine_to_phys_mapping #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) #endif +#endif /* * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) diff --git a/mm.c b/mm.c index ca0b9be..c76be7f 100644 --- a/mm.c +++ b/mm.c @@ -39,6 +39,7 @@ #include <xen/memory.h> #include <mini-os/mm.h> #include <mini-os/balloon.h> +#include <mini-os/paravirt.h> #include <mini-os/types.h> #include <mini-os/lib.h> #include <mini-os/xmalloc.h> -- 2.6.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |