/* * noexec = on|off * * Control non-executable mappings for processes. * * on Enable * off Disable */ static int __init noexec_setup(char *str) { if (!str) return -EINVAL; if (!strncmp(str, "on", 2)) { disable_nx = 0; } else if (!strncmp(str, "off", 3)) { disable_nx = 1; } x86_configure_nx(); return 0; }
/* First C function to be called on Xen boot */ asmlinkage void __init xen_start_kernel(void) { pgd_t *pgd; if (!xen_start_info) return; xen_domain_type = XEN_PV_DOMAIN; /* Install Xen paravirt ops */ pv_info = xen_info; pv_init_ops = xen_init_ops; pv_time_ops = xen_time_ops; pv_cpu_ops = xen_cpu_ops; pv_apic_ops = xen_apic_ops; x86_init.resources.memory_setup = xen_memory_setup; x86_init.oem.arch_setup = xen_arch_setup; x86_init.oem.banner = xen_banner; x86_init.timers.timer_init = xen_time_init; x86_init.timers.setup_percpu_clockev = x86_init_noop; x86_cpuinit.setup_percpu_clockev = x86_init_noop; x86_platform.calibrate_tsc = xen_tsc_khz; x86_platform.get_wallclock = xen_get_wallclock; x86_platform.set_wallclock = xen_set_wallclock; /* * Set up some pagetable state before starting to set any ptes. */ xen_init_mmu_ops(); /* Prevent unwanted bits from being set in PTEs. */ __supported_pte_mask &= ~_PAGE_GLOBAL; if (!xen_initial_domain()) __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); __supported_pte_mask |= _PAGE_IOMAP; /* * Prevent page tables from being allocated in highmem, even * if CONFIG_HIGHPTE is enabled. */ __userpte_alloc_gfp &= ~__GFP_HIGHMEM; /* Work out if we support NX */ x86_configure_nx(); xen_setup_features(); /* Get mfn list */ if (!xen_feature(XENFEAT_auto_translated_physmap)) xen_build_dynamic_phys_to_machine(); /* * Set up kernel GDT and segment registers, mainly so that * -fstack-protector code can be executed. */ xen_setup_stackprotector(); xen_init_irq_ops(); xen_init_cpuid_mask(); #ifdef CONFIG_X86_LOCAL_APIC /* * set up the basic apic ops. */ set_xen_basic_apic_ops(); #endif if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start; pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit; } machine_ops = xen_machine_ops; /* * The only reliable way to retain the initial address of the * percpu gdt_page is to remember it here, so we can go and * mark it RW later, when the initial percpu area is freed. */ xen_initial_gdt = &per_cpu(gdt_page, 0); xen_smp_init(); pgd = (pgd_t *)xen_start_info->pt_base; /* Don't do the full vcpu_info placement stuff until we have a possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; local_irq_disable(); early_boot_irqs_off(); xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); init_mm.pgd = pgd; /* keep using Xen gdt for now; no urgent need to change it */ #ifdef CONFIG_X86_32 pv_info.kernel_rpl = 1; if (xen_feature(XENFEAT_supervisor_mode_kernel)) pv_info.kernel_rpl = 0; #else pv_info.kernel_rpl = 0; #endif /* set the limit of our address space */ xen_reserve_top(); #ifdef CONFIG_X86_32 /* set up basic CPUID stuff */ cpu_detect(&new_cpu_data); new_cpu_data.hard_math = 1; new_cpu_data.wp_works_ok = 1; new_cpu_data.x86_capability[0] = cpuid_edx(1); #endif /* Poke various useful things into boot_params */ boot_params.hdr.type_of_loader = (9 << 4) | 0; boot_params.hdr.ramdisk_image = xen_start_info->mod_start ? __pa(xen_start_info->mod_start) : 0; boot_params.hdr.ramdisk_size = xen_start_info->mod_len; boot_params.hdr.cmd_line_ptr = __pa(xen_start_info->cmd_line); if (!xen_initial_domain()) { add_preferred_console("xenboot", 0, NULL); add_preferred_console("tty", 0, NULL); add_preferred_console("hvc", 0, NULL); } else { /* Make sure ACS will be enabled */ pci_request_acs(); } xen_raw_console_write("about to get started...\n"); xen_setup_runstate_info(0); /* Start the world */ #ifdef CONFIG_X86_32 i386_start_kernel(); #else x86_64_start_reservations((char *)__pa_symbol(&boot_params)); #endif }