diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-07-19 10:23:47 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-08-21 14:44:50 -0400 |
commit | 59b294403e9814e7c1154043567f0d71bac7a511 (patch) | |
tree | 42f84556415209884f19ab58df234ae098f67c66 /arch | |
parent | a3118beb6a8cbe77ae3342125d920205871b0717 (diff) |
xen/x86: Use memblock_reserve for sensitive areas.
instead of a big memblock_reserve. This way we can be more
selective in freeing regions (and it also makes it easier
to understand where is what).
[v1: Move the auto_translate_physmap to proper line]
[v2: Per Stefano suggestion add more comments]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/xen/enlighten.c | 48 | ||||
-rw-r--r-- | arch/x86/xen/p2m.c | 5 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 9 |
3 files changed, 53 insertions, 9 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ff962d4b821e..e532eb50e8d7 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -998,7 +998,54 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) | |||
998 | 998 | ||
999 | return ret; | 999 | return ret; |
1000 | } | 1000 | } |
1001 | /* | ||
1002 | * If the MFN is not in the m2p (provided to us by the hypervisor) this | ||
1003 | * function won't do anything. In practice this means that the XenBus | ||
1004 | * MFN won't be available for the initial domain. */ | ||
1005 | static void __init xen_reserve_mfn(unsigned long mfn) | ||
1006 | { | ||
1007 | unsigned long pfn; | ||
1008 | |||
1009 | if (!mfn) | ||
1010 | return; | ||
1011 | pfn = mfn_to_pfn(mfn); | ||
1012 | if (phys_to_machine_mapping_valid(pfn)) | ||
1013 | memblock_reserve(PFN_PHYS(pfn), PAGE_SIZE); | ||
1014 | } | ||
1015 | static void __init xen_reserve_internals(void) | ||
1016 | { | ||
1017 | unsigned long size; | ||
1018 | |||
1019 | if (!xen_pv_domain()) | ||
1020 | return; | ||
1021 | |||
1022 | /* xen_start_info does not exist in the M2P, hence can't use | ||
1023 | * xen_reserve_mfn. */ | ||
1024 | memblock_reserve(__pa(xen_start_info), PAGE_SIZE); | ||
1025 | |||
1026 | xen_reserve_mfn(PFN_DOWN(xen_start_info->shared_info)); | ||
1027 | xen_reserve_mfn(xen_start_info->store_mfn); | ||
1001 | 1028 | ||
1029 | if (!xen_initial_domain()) | ||
1030 | xen_reserve_mfn(xen_start_info->console.domU.mfn); | ||
1031 | |||
1032 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
1033 | return; | ||
1034 | |||
1035 | /* | ||
1036 | * ALIGN up to compensate for the p2m_page pointing to an array that | ||
1037 | * can partially filled (look in xen_build_dynamic_phys_to_machine). | ||
1038 | */ | ||
1039 | |||
1040 | size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long)); | ||
1041 | |||
1042 | /* We could use xen_reserve_mfn here, but would end up looping quite | ||
1043 | * a lot (and call memblock_reserve for each PAGE), so lets just use | ||
1044 | * the easy way and reserve it wholesale. */ | ||
1045 | memblock_reserve(__pa(xen_start_info->mfn_list), size); | ||
1046 | |||
1047 | /* The pagetables are reserved in mmu.c */ | ||
1048 | } | ||
1002 | void xen_setup_shared_info(void) | 1049 | void xen_setup_shared_info(void) |
1003 | { | 1050 | { |
1004 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | 1051 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
@@ -1362,6 +1409,7 @@ asmlinkage void __init xen_start_kernel(void) | |||
1362 | xen_raw_console_write("mapping kernel into physical memory\n"); | 1409 | xen_raw_console_write("mapping kernel into physical memory\n"); |
1363 | pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); | 1410 | pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); |
1364 | 1411 | ||
1412 | xen_reserve_internals(); | ||
1365 | /* Allocate and initialize top and mid mfn levels for p2m structure */ | 1413 | /* Allocate and initialize top and mid mfn levels for p2m structure */ |
1366 | xen_build_mfn_list_list(); | 1414 | xen_build_mfn_list_list(); |
1367 | 1415 | ||
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index e4adbfbdfada..6a2bfa43c8a1 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -388,6 +388,11 @@ void __init xen_build_dynamic_phys_to_machine(void) | |||
388 | } | 388 | } |
389 | 389 | ||
390 | m2p_override_init(); | 390 | m2p_override_init(); |
391 | |||
392 | /* NOTE: We cannot call memblock_reserve here for the mfn_list as there | ||
393 | * isn't enough pieces to make it work (for one - we are still using the | ||
394 | * Xen provided pagetable). Do it later in xen_reserve_internals. | ||
395 | */ | ||
391 | } | 396 | } |
392 | 397 | ||
393 | unsigned long get_phys_to_machine(unsigned long pfn) | 398 | unsigned long get_phys_to_machine(unsigned long pfn) |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index a4790bf22c59..9efca750405d 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -424,15 +424,6 @@ char * __init xen_memory_setup(void) | |||
424 | e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, | 424 | e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, |
425 | E820_RESERVED); | 425 | E820_RESERVED); |
426 | 426 | ||
427 | /* | ||
428 | * Reserve Xen bits: | ||
429 | * - mfn_list | ||
430 | * - xen_start_info | ||
431 | * See comment above "struct start_info" in <xen/interface/xen.h> | ||
432 | */ | ||
433 | memblock_reserve(__pa(xen_start_info->mfn_list), | ||
434 | xen_start_info->pt_base - xen_start_info->mfn_list); | ||
435 | |||
436 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 427 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
437 | 428 | ||
438 | return "Xen"; | 429 | return "Xen"; |