| .. | .. |
|---|
| 12 | 12 | #include <linux/memblock.h> |
|---|
| 13 | 13 | #include <linux/cpuidle.h> |
|---|
| 14 | 14 | #include <linux/cpufreq.h> |
|---|
| 15 | +#include <linux/memory_hotplug.h> |
|---|
| 15 | 16 | |
|---|
| 16 | 17 | #include <asm/elf.h> |
|---|
| 17 | 18 | #include <asm/vdso.h> |
|---|
| .. | .. |
|---|
| 19 | 20 | #include <asm/setup.h> |
|---|
| 20 | 21 | #include <asm/acpi.h> |
|---|
| 21 | 22 | #include <asm/numa.h> |
|---|
| 23 | +#include <asm/idtentry.h> |
|---|
| 22 | 24 | #include <asm/xen/hypervisor.h> |
|---|
| 23 | 25 | #include <asm/xen/hypercall.h> |
|---|
| 24 | 26 | |
|---|
| .. | .. |
|---|
| 30 | 32 | #include <xen/features.h> |
|---|
| 31 | 33 | #include <xen/hvc-console.h> |
|---|
| 32 | 34 | #include "xen-ops.h" |
|---|
| 33 | | -#include "vdso.h" |
|---|
| 34 | 35 | #include "mmu.h" |
|---|
| 35 | 36 | |
|---|
| 36 | 37 | #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024) |
|---|
| .. | .. |
|---|
| 58 | 59 | } xen_remap_buf __initdata __aligned(PAGE_SIZE); |
|---|
| 59 | 60 | static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY; |
|---|
| 60 | 61 | |
|---|
| 61 | | -/* |
|---|
| 62 | +/* |
|---|
| 62 | 63 | * The maximum amount of extra memory compared to the base size. The |
|---|
| 63 | 64 | * main scaling factor is the size of struct page. At extreme ratios |
|---|
| 64 | 65 | * of base:extra, all the base memory can be filled with page |
|---|
| 65 | 66 | * structures for the extra memory, leaving no space for anything |
|---|
| 66 | 67 | * else. |
|---|
| 67 | | - * |
|---|
| 68 | + * |
|---|
| 68 | 69 | * 10x seems like a reasonable balance between scaling flexibility and |
|---|
| 69 | 70 | * leaving a practically usable system. |
|---|
| 70 | 71 | */ |
|---|
| .. | .. |
|---|
| 411 | 412 | |
|---|
| 412 | 413 | remap_range_size = xen_find_pfn_range(&remap_pfn); |
|---|
| 413 | 414 | if (!remap_range_size) { |
|---|
| 414 | | - pr_warning("Unable to find available pfn range, not remapping identity pages\n"); |
|---|
| 415 | + pr_warn("Unable to find available pfn range, not remapping identity pages\n"); |
|---|
| 415 | 416 | xen_set_identity_and_release_chunk(cur_pfn, |
|---|
| 416 | 417 | cur_pfn + left, nr_pages); |
|---|
| 417 | 418 | break; |
|---|
| .. | .. |
|---|
| 493 | 494 | * The remap information (which mfn remap to which pfn) is contained in the |
|---|
| 494 | 495 | * to be remapped memory itself in a linked list anchored at xen_remap_mfn. |
|---|
| 495 | 496 | * This scheme allows to remap the different chunks in arbitrary order while |
|---|
| 496 | | - * the resulting mapping will be independant from the order. |
|---|
| 497 | + * the resulting mapping will be independent from the order. |
|---|
| 497 | 498 | */ |
|---|
| 498 | 499 | void __init xen_remap_memory(void) |
|---|
| 499 | 500 | { |
|---|
| .. | .. |
|---|
| 543 | 544 | { |
|---|
| 544 | 545 | unsigned long limit; |
|---|
| 545 | 546 | |
|---|
| 546 | | -#ifdef CONFIG_X86_32 |
|---|
| 547 | | - limit = GB(64) / PAGE_SIZE; |
|---|
| 548 | | -#else |
|---|
| 549 | 547 | limit = MAXMEM / PAGE_SIZE; |
|---|
| 550 | 548 | if (!xen_initial_domain() && xen_512gb_limit) |
|---|
| 551 | 549 | limit = GB(512) / PAGE_SIZE; |
|---|
| 552 | | -#endif |
|---|
| 550 | + |
|---|
| 553 | 551 | return limit; |
|---|
| 554 | 552 | } |
|---|
| 555 | 553 | |
|---|
| .. | .. |
|---|
| 589 | 587 | if (type == E820_TYPE_RAM) { |
|---|
| 590 | 588 | start = PAGE_ALIGN(start); |
|---|
| 591 | 589 | end &= ~((phys_addr_t)PAGE_SIZE - 1); |
|---|
| 590 | +#ifdef CONFIG_MEMORY_HOTPLUG |
|---|
| 591 | + /* |
|---|
| 592 | + * Don't allow adding memory not in E820 map while booting the |
|---|
| 593 | + * system. Once the balloon driver is up it will remove that |
|---|
| 594 | + * restriction again. |
|---|
| 595 | + */ |
|---|
| 596 | + max_mem_size = end; |
|---|
| 597 | +#endif |
|---|
| 592 | 598 | } |
|---|
| 593 | 599 | |
|---|
| 594 | 600 | e820__range_add(start, end - start, type); |
|---|
| .. | .. |
|---|
| 712 | 718 | if (!xen_is_e820_reserved(start, size)) |
|---|
| 713 | 719 | return; |
|---|
| 714 | 720 | |
|---|
| 715 | | -#ifdef CONFIG_X86_32 |
|---|
| 716 | | - /* |
|---|
| 717 | | - * Relocating the p2m on 32 bit system to an arbitrary virtual address |
|---|
| 718 | | - * is not supported, so just give up. |
|---|
| 719 | | - */ |
|---|
| 720 | | - xen_raw_console_write("Xen hypervisor allocated p2m list conflicts with E820 map\n"); |
|---|
| 721 | | - BUG(); |
|---|
| 722 | | -#else |
|---|
| 723 | 721 | xen_relocate_p2m(); |
|---|
| 724 | 722 | memblock_free(start, size); |
|---|
| 725 | | -#endif |
|---|
| 726 | 723 | } |
|---|
| 727 | 724 | |
|---|
| 728 | 725 | /** |
|---|
| .. | .. |
|---|
| 747 | 744 | |
|---|
| 748 | 745 | memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries); |
|---|
| 749 | 746 | set_xen_guest_handle(memmap.buffer, xen_e820_table.entries); |
|---|
| 747 | + |
|---|
| 748 | +#if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_XEN_BALLOON) |
|---|
| 749 | + xen_saved_max_mem_size = max_mem_size; |
|---|
| 750 | +#endif |
|---|
| 750 | 751 | |
|---|
| 751 | 752 | op = xen_initial_domain() ? |
|---|
| 752 | 753 | XENMEM_machine_memory_map : |
|---|
| .. | .. |
|---|
| 790 | 791 | |
|---|
| 791 | 792 | /* |
|---|
| 792 | 793 | * Clamp the amount of extra memory to a EXTRA_MEM_RATIO |
|---|
| 793 | | - * factor the base size. On non-highmem systems, the base |
|---|
| 794 | | - * size is the full initial memory allocation; on highmem it |
|---|
| 795 | | - * is limited to the max size of lowmem, so that it doesn't |
|---|
| 796 | | - * get completely filled. |
|---|
| 794 | + * factor the base size. |
|---|
| 797 | 795 | * |
|---|
| 798 | 796 | * Make sure we have no memory above max_pages, as this area |
|---|
| 799 | 797 | * isn't handled by the p2m management. |
|---|
| 800 | | - * |
|---|
| 801 | | - * In principle there could be a problem in lowmem systems if |
|---|
| 802 | | - * the initial memory is also very large with respect to |
|---|
| 803 | | - * lowmem, but we won't try to deal with that here. |
|---|
| 804 | 798 | */ |
|---|
| 805 | 799 | extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), |
|---|
| 806 | 800 | extra_pages, max_pages - max_pfn); |
|---|
| .. | .. |
|---|
| 907 | 901 | return "Xen"; |
|---|
| 908 | 902 | } |
|---|
| 909 | 903 | |
|---|
| 910 | | -/* |
|---|
| 911 | | - * Set the bit indicating "nosegneg" library variants should be used. |
|---|
| 912 | | - * We only need to bother in pure 32-bit mode; compat 32-bit processes |
|---|
| 913 | | - * can have un-truncated segments, so wrapping around is allowed. |
|---|
| 914 | | - */ |
|---|
| 915 | | -static void __init fiddle_vdso(void) |
|---|
| 916 | | -{ |
|---|
| 917 | | -#ifdef CONFIG_X86_32 |
|---|
| 918 | | - u32 *mask = vdso_image_32.data + |
|---|
| 919 | | - vdso_image_32.sym_VDSO32_NOTE_MASK; |
|---|
| 920 | | - *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; |
|---|
| 921 | | -#endif |
|---|
| 922 | | -} |
|---|
| 923 | | - |
|---|
| 924 | 904 | static int register_callback(unsigned type, const void *func) |
|---|
| 925 | 905 | { |
|---|
| 926 | 906 | struct callback_register callback = { |
|---|
| .. | .. |
|---|
| 937 | 917 | int ret; |
|---|
| 938 | 918 | unsigned sysenter_feature; |
|---|
| 939 | 919 | |
|---|
| 940 | | -#ifdef CONFIG_X86_32 |
|---|
| 941 | | - sysenter_feature = X86_FEATURE_SEP; |
|---|
| 942 | | -#else |
|---|
| 943 | 920 | sysenter_feature = X86_FEATURE_SYSENTER32; |
|---|
| 944 | | -#endif |
|---|
| 945 | 921 | |
|---|
| 946 | 922 | if (!boot_cpu_has(sysenter_feature)) |
|---|
| 947 | 923 | return; |
|---|
| 948 | 924 | |
|---|
| 949 | | - ret = register_callback(CALLBACKTYPE_sysenter, xen_sysenter_target); |
|---|
| 925 | + ret = register_callback(CALLBACKTYPE_sysenter, xen_entry_SYSENTER_compat); |
|---|
| 950 | 926 | if(ret != 0) |
|---|
| 951 | 927 | setup_clear_cpu_cap(sysenter_feature); |
|---|
| 952 | 928 | } |
|---|
| 953 | 929 | |
|---|
| 954 | 930 | void xen_enable_syscall(void) |
|---|
| 955 | 931 | { |
|---|
| 956 | | -#ifdef CONFIG_X86_64 |
|---|
| 957 | 932 | int ret; |
|---|
| 958 | 933 | |
|---|
| 959 | | - ret = register_callback(CALLBACKTYPE_syscall, xen_syscall_target); |
|---|
| 934 | + ret = register_callback(CALLBACKTYPE_syscall, xen_entry_SYSCALL_64); |
|---|
| 960 | 935 | if (ret != 0) { |
|---|
| 961 | 936 | printk(KERN_ERR "Failed to set syscall callback: %d\n", ret); |
|---|
| 962 | 937 | /* Pretty fatal; 64-bit userspace has no other |
|---|
| .. | .. |
|---|
| 965 | 940 | |
|---|
| 966 | 941 | if (boot_cpu_has(X86_FEATURE_SYSCALL32)) { |
|---|
| 967 | 942 | ret = register_callback(CALLBACKTYPE_syscall32, |
|---|
| 968 | | - xen_syscall32_target); |
|---|
| 943 | + xen_entry_SYSCALL_compat); |
|---|
| 969 | 944 | if (ret != 0) |
|---|
| 970 | 945 | setup_clear_cpu_cap(X86_FEATURE_SYSCALL32); |
|---|
| 971 | 946 | } |
|---|
| 972 | | -#endif /* CONFIG_X86_64 */ |
|---|
| 973 | 947 | } |
|---|
| 974 | 948 | |
|---|
| 975 | | -void __init xen_pvmmu_arch_setup(void) |
|---|
| 949 | +static void __init xen_pvmmu_arch_setup(void) |
|---|
| 976 | 950 | { |
|---|
| 977 | 951 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); |
|---|
| 978 | 952 | HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); |
|---|
| .. | .. |
|---|
| 980 | 954 | HYPERVISOR_vm_assist(VMASST_CMD_enable, |
|---|
| 981 | 955 | VMASST_TYPE_pae_extended_cr3); |
|---|
| 982 | 956 | |
|---|
| 983 | | - if (register_callback(CALLBACKTYPE_event, xen_hypervisor_callback) || |
|---|
| 957 | + if (register_callback(CALLBACKTYPE_event, |
|---|
| 958 | + xen_asm_exc_xen_hypervisor_callback) || |
|---|
| 984 | 959 | register_callback(CALLBACKTYPE_failsafe, xen_failsafe_callback)) |
|---|
| 985 | 960 | BUG(); |
|---|
| 986 | 961 | |
|---|
| .. | .. |
|---|
| 1009 | 984 | disable_cpuidle(); |
|---|
| 1010 | 985 | disable_cpufreq(); |
|---|
| 1011 | 986 | WARN_ON(xen_set_default_idle()); |
|---|
| 1012 | | - fiddle_vdso(); |
|---|
| 1013 | 987 | #ifdef CONFIG_NUMA |
|---|
| 1014 | 988 | numa_off = 1; |
|---|
| 1015 | 989 | #endif |
|---|