summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Garrett <mjg@redhat.com>2011-03-17 10:34:55 -0400
committerMatthew Garrett <mjg@redhat.com>2011-03-17 10:34:55 -0400
commita725c00ed421e4eea7d02f5f2aea99f8f7de29df (patch)
tree40f90454b704891e0722c5bde3c3dacf83570a41
parent3ddbdca8f8a6a3008b6bc06bbd81250661e604ed (diff)
downloadkernel-a725c00ed421e4eea7d02f5f2aea99f8f7de29df.tar.gz
kernel-a725c00ed421e4eea7d02f5f2aea99f8f7de29df.tar.xz
kernel-a725c00ed421e4eea7d02f5f2aea99f8f7de29df.zip
drop efi_default_physical.patch - it's actually setting up something that's
neither physical nor virtual, and it's probably breaking EFI boots
-rw-r--r--efi_default_physical.patch403
-rw-r--r--kernel.spec6
2 files changed, 4 insertions, 405 deletions
diff --git a/efi_default_physical.patch b/efi_default_physical.patch
deleted file mode 100644
index 41de7809e..000000000
--- a/efi_default_physical.patch
+++ /dev/null
@@ -1,403 +0,0 @@
-Default EFI to physical rather than virtual. Upstream seem to be going
-in this direction.
-
-diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
-index 8e4a165..3c62f15 100644
---- a/arch/x86/include/asm/efi.h
-+++ b/arch/x86/include/asm/efi.h
-@@ -93,6 +93,9 @@ extern int add_efi_memmap;
- extern void efi_memblock_x86_reserve_range(void);
- extern void efi_call_phys_prelog(void);
- extern void efi_call_phys_epilog(void);
-+extern void efi_call_phys_prelog_in_physmode(void);
-+extern void efi_call_phys_epilog_in_physmode(void);
-+extern void efi_pagetable_init(void);
-
- #ifndef CONFIG_EFI
- /*
-diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
-index 0fe27d7..e1158b0 100644
---- a/arch/x86/platform/efi/efi.c
-+++ b/arch/x86/platform/efi/efi.c
-@@ -58,6 +58,7 @@ struct efi_memory_map memmap;
-
- static struct efi efi_phys __initdata;
- static efi_system_table_t efi_systab __initdata;
-+static efi_runtime_services_t phys_runtime;
-
- static int __init setup_noefi(char *arg)
- {
-@@ -172,7 +173,7 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
- return status;
- }
-
--static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
-+static efi_status_t __init phys_efi_get_time_early(efi_time_t *tm,
- efi_time_cap_t *tc)
- {
- efi_status_t status;
-@@ -183,6 +184,112 @@ static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
- return status;
- }
-
-+static efi_status_t phys_efi_get_time(efi_time_t *tm,
-+ efi_time_cap_t *tc)
-+{
-+ efi_status_t status;
-+
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys2((void*)phys_runtime.get_time, tm, tc);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t __init phys_efi_set_time(efi_time_t *tm)
-+{
-+ efi_status_t status;
-+
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys1((void*)phys_runtime.set_time, tm);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t phys_efi_get_wakeup_time(efi_bool_t *enabled,
-+ efi_bool_t *pending,
-+ efi_time_t *tm)
-+{
-+ efi_status_t status;
-+
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys3((void*)phys_runtime.get_wakeup_time, enabled,
-+ pending, tm);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t phys_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
-+{
-+ efi_status_t status;
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys2((void*)phys_runtime.set_wakeup_time, enabled,
-+ tm);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t phys_efi_get_variable(efi_char16_t *name,
-+ efi_guid_t *vendor,
-+ u32 *attr,
-+ unsigned long *data_size,
-+ void *data)
-+{
-+ efi_status_t status;
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys5((void*)phys_runtime.get_variable, name, vendor,
-+ attr, data_size, data);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t phys_efi_get_next_variable(unsigned long *name_size,
-+ efi_char16_t *name,
-+ efi_guid_t *vendor)
-+{
-+ efi_status_t status;
-+
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys3((void*)phys_runtime.get_next_variable,
-+ name_size, name, vendor);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t phys_efi_set_variable(efi_char16_t *name,
-+ efi_guid_t *vendor,
-+ unsigned long attr,
-+ unsigned long data_size,
-+ void *data)
-+{
-+ efi_status_t status;
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys5((void*)phys_runtime.set_variable, name,
-+ vendor, attr, data_size, data);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static efi_status_t phys_efi_get_next_high_mono_count(u32 *count)
-+{
-+ efi_status_t status;
-+ efi_call_phys_prelog_in_physmode();
-+ status = efi_call_phys1((void*)phys_runtime.get_next_high_mono_count,
-+ count);
-+ efi_call_phys_epilog_in_physmode();
-+ return status;
-+}
-+
-+static void phys_efi_reset_system(int reset_type,
-+ efi_status_t status,
-+ unsigned long data_size,
-+ efi_char16_t *data)
-+{
-+ efi_call_phys_prelog_in_physmode();
-+ efi_call_phys4((void*)phys_runtime.reset_system, reset_type, status,
-+ data_size, data);
-+ efi_call_phys_epilog_in_physmode();
-+}
-+
- int efi_set_rtc_mmss(unsigned long nowtime)
- {
- int real_seconds, real_minutes;
-@@ -435,7 +542,9 @@ void __init efi_init(void)
- * Make efi_get_time can be called before entering
- * virtual mode.
- */
-- efi.get_time = phys_efi_get_time;
-+ efi.get_time = phys_efi_get_time_early;
-+
-+ memcpy(&phys_runtime, runtime, sizeof(efi_runtime_services_t));
- } else
- printk(KERN_ERR "Could not map the EFI runtime service "
- "table!\n");
-@@ -466,6 +575,14 @@ void __init efi_init(void)
- #if EFI_DEBUG
- print_efi_memmap();
- #endif
-+
-+#ifndef CONFIG_X86_64
-+ /*
-+ * Only x86_64 supports physical mode as of now. Use virtual mode
-+ * forcibly.
-+ */
-+ usevirtefi = 1;
-+#endif
- }
-
- static void __init runtime_code_page_mkexec(void)
-@@ -579,6 +696,27 @@ void __init efi_enter_virtual_mode(void)
- memmap.map = NULL;
- }
-
-+void __init efi_setup_physical_mode(void)
-+{
-+#ifdef CONFIG_X86_64
-+ efi_pagetable_init();
-+#endif
-+ efi.get_time = phys_efi_get_time;
-+ efi.set_time = phys_efi_set_time;
-+ efi.get_wakeup_time = phys_efi_get_wakeup_time;
-+ efi.set_wakeup_time = phys_efi_set_wakeup_time;
-+ efi.get_variable = phys_efi_get_variable;
-+ efi.get_next_variable = phys_efi_get_next_variable;
-+ efi.set_variable = phys_efi_set_variable;
-+ efi.get_next_high_mono_count =
-+ phys_efi_get_next_high_mono_count;
-+ efi.reset_system = phys_efi_reset_system;
-+ efi.set_virtual_address_map = NULL; /* Not needed */
-+
-+ early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
-+ memmap.map = NULL;
-+}
-+
- /*
- * Convenience functions to obtain memory types and attributes
- */
-diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
-index 5cab48e..90767b1 100644
---- a/arch/x86/platform/efi/efi_32.c
-+++ b/arch/x86/platform/efi/efi_32.c
-@@ -110,3 +110,7 @@ void efi_call_phys_epilog(void)
-
- local_irq_restore(efi_rt_eflags);
- }
-+
-+void efi_call_phys_prelog_in_physmode(void) { /* Not supported */ }
-+void efi_call_phys_epilog_in_physmode(void) { /* Not supported */ }
-+
-diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
-index ac0621a..ad19fe9 100644
---- a/arch/x86/platform/efi/efi_64.c
-+++ b/arch/x86/platform/efi/efi_64.c
-@@ -39,7 +39,9 @@
- #include <asm/fixmap.h>
-
- static pgd_t save_pgd __initdata;
--static unsigned long efi_flags __initdata;
-+static DEFINE_PER_CPU(unsigned long, efi_flags);
-+static DEFINE_PER_CPU(unsigned long, save_cr3);
-+static pgd_t efi_pgd[PTRS_PER_PGD] __page_aligned_bss;
-
- static void __init early_mapping_set_exec(unsigned long start,
- unsigned long end,
-@@ -80,7 +82,7 @@ void __init efi_call_phys_prelog(void)
- unsigned long vaddress;
-
- early_runtime_code_mapping_set_exec(1);
-- local_irq_save(efi_flags);
-+ local_irq_save(get_cpu_var(efi_flags));
- vaddress = (unsigned long)__va(0x0UL);
- save_pgd = *pgd_offset_k(0x0UL);
- set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
-@@ -94,10 +96,23 @@ void __init efi_call_phys_epilog(void)
- */
- set_pgd(pgd_offset_k(0x0UL), save_pgd);
- __flush_tlb_all();
-- local_irq_restore(efi_flags);
-+ local_irq_restore(get_cpu_var(efi_flags));
- early_runtime_code_mapping_set_exec(0);
- }
-
-+void efi_call_phys_prelog_in_physmode(void)
-+{
-+ local_irq_save(get_cpu_var(efi_flags));
-+ get_cpu_var(save_cr3)= read_cr3();
-+ write_cr3(virt_to_phys(efi_pgd));
-+}
-+
-+void efi_call_phys_epilog_in_physmode(void)
-+{
-+ write_cr3(get_cpu_var(save_cr3));
-+ local_irq_restore(get_cpu_var(efi_flags));
-+}
-+
- void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
- u32 type)
- {
-@@ -112,3 +127,78 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
-
- return (void __iomem *)__va(phys_addr);
- }
-+
-+static pud_t *fill_pud(pgd_t *pgd, unsigned long vaddr)
-+{
-+ if (pgd_none(*pgd)) {
-+ pud_t *pud = (pud_t *)get_zeroed_page(GFP_ATOMIC);
-+ set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud)));
-+ if (pud != pud_offset(pgd, 0))
-+ printk(KERN_ERR "EFI PAGETABLE BUG #00! %p <-> %p\n",
-+ pud, pud_offset(pgd, 0));
-+ }
-+ return pud_offset(pgd, vaddr);
-+}
-+
-+static pmd_t *fill_pmd(pud_t *pud, unsigned long vaddr)
-+{
-+ if (pud_none(*pud)) {
-+ pmd_t *pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC);
-+ set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)));
-+ if (pmd != pmd_offset(pud, 0))
-+ printk(KERN_ERR "EFI PAGETABLE BUG #01! %p <-> %p\n",
-+ pmd, pmd_offset(pud, 0));
-+ }
-+ return pmd_offset(pud, vaddr);
-+}
-+
-+static pte_t *fill_pte(pmd_t *pmd, unsigned long vaddr)
-+{
-+ if (pmd_none(*pmd)) {
-+ pte_t *pte = (pte_t *)get_zeroed_page(GFP_ATOMIC);
-+ set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)));
-+ if (pte != pte_offset_kernel(pmd, 0))
-+ printk(KERN_ERR "EFI PAGETABLE BUG #02!\n");
-+ }
-+ return pte_offset_kernel(pmd, vaddr);
-+}
-+
-+void __init efi_pagetable_init(void)
-+{
-+ efi_memory_desc_t *md;
-+ unsigned long size;
-+ u64 start_pfn, end_pfn, pfn, vaddr;
-+ void *p;
-+ pgd_t *pgd;
-+ pud_t *pud;
-+ pmd_t *pmd;
-+ pte_t *pte;
-+
-+ memset(efi_pgd, 0, sizeof(efi_pgd));
-+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-+ md = p;
-+ if (!(md->type & EFI_RUNTIME_SERVICES_CODE) &&
-+ !(md->type & EFI_RUNTIME_SERVICES_DATA))
-+ continue;
-+
-+ start_pfn = md->phys_addr >> PAGE_SHIFT;
-+ size = md->num_pages << EFI_PAGE_SHIFT;
-+ end_pfn = PFN_UP(md->phys_addr + size);
-+
-+ for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
-+ vaddr = pfn << PAGE_SHIFT;
-+ pgd = efi_pgd + pgd_index(vaddr);
-+ pud = fill_pud(pgd, vaddr);
-+ pmd = fill_pmd(pud, vaddr);
-+ pte = fill_pte(pmd, vaddr);
-+ if (md->type & EFI_RUNTIME_SERVICES_CODE)
-+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
-+ else
-+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
-+ }
-+ }
-+ pgd = efi_pgd + pgd_index(PAGE_OFFSET);
-+ set_pgd(pgd, *pgd_offset_k(PAGE_OFFSET));
-+ pgd = efi_pgd + pgd_index(__START_KERNEL_map);
-+ set_pgd(pgd, *pgd_offset_k(__START_KERNEL_map));
-+}
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index fb737bc..c4e310e 100644
---- a/include/linux/efi.h
-+++ b/include/linux/efi.h
-@@ -290,6 +290,7 @@ extern void efi_map_pal_code (void);
- extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
- extern void efi_gettimeofday (struct timespec *ts);
- extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */
-+extern void efi_setup_physical_mode(void);
- extern u64 efi_get_iobase (void);
- extern u32 efi_mem_type (unsigned long phys_addr);
- extern u64 efi_mem_attributes (unsigned long phys_addr);
-diff --git a/include/linux/init.h b/include/linux/init.h
-index 577671c..2f1b28f 100644
---- a/include/linux/init.h
-+++ b/include/linux/init.h
-@@ -149,6 +149,7 @@ extern int do_one_initcall(initcall_t fn);
- extern char __initdata boot_command_line[];
- extern char *saved_command_line;
- extern unsigned int reset_devices;
-+extern unsigned int usevirtefi;
-
- /* used by init/main.c */
- void setup_arch(char **);
-diff --git a/init/main.c b/init/main.c
-index 8646401..726025e 100644
---- a/init/main.c
-+++ b/init/main.c
-@@ -196,6 +196,14 @@ static int __init set_reset_devices(char *str)
-
- __setup("reset_devices", set_reset_devices);
-
-+unsigned int usevirtefi;
-+static int __init set_virt_efi(char *str)
-+{
-+ usevirtefi = 1;
-+ return 1;
-+}
-+__setup("virtefi", set_virt_efi);
-+
- static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
- const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
- static const char *panic_later, *panic_param;
-@@ -668,8 +676,12 @@ asmlinkage void __init start_kernel(void)
- pidmap_init();
- anon_vma_init();
- #ifdef CONFIG_X86
-- if (efi_enabled)
-- efi_enter_virtual_mode();
-+ if (efi_enabled) {
-+ if (usevirtefi)
-+ efi_enter_virtual_mode();
-+ else
-+ efi_setup_physical_mode();
-+ }
- #endif
- thread_info_cache_init();
- cred_init();
diff --git a/kernel.spec b/kernel.spec
index a41a58575..e729eeea0 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -720,7 +720,6 @@ Patch12018: neuter_intel_microcode_load.patch
Patch12101: apple_backlight.patch
Patch12102: efifb_update.patch
Patch12200: acpi_reboot.patch
-Patch12210: efi_default_physical.patch
# Runtime power management
Patch12202: linux-2.6-ehci-check-port-status.patch
@@ -1347,7 +1346,6 @@ ApplyPatch neuter_intel_microcode_load.patch
ApplyPatch apple_backlight.patch
ApplyPatch efifb_update.patch
ApplyPatch acpi_reboot.patch
-ApplyPatch efi_default_physical.patch
# Runtime PM
ApplyPatch linux-2.6-ehci-check-port-status.patch
@@ -1970,6 +1968,10 @@ fi
# and build.
%changelog
+* Thu Mar 17 2011 Matthew Garrett <mjg@redhat.com>
+- drop efi_default_physical.patch - it's actually setting up something that's
+ neither physical nor virtual, and it's probably breaking EFI boots
+
* Wed Mar 16 2011 Kyle McMartin <kmcmartin@redhat.com> 2.6.39-0.rc0.git1.1
- Test out scripts/rebase.sh on 2.6.38-git1.
- Enable fhandle syscalls (ugh. conditional syscalls... update