Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, realmode: don't copy real_mode_header

Replaced copying of real_mode_header with a pointer
to beginning of RM memory.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-19-git-send-email-jarkko.sakkinen@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>

authored by

Jarkko Sakkinen and committed by
H. Peter Anvin
b429dbf6 8e029fcd

+35 -43
+2 -3
arch/x86/include/asm/realmode.h
··· 8 8 struct real_mode_header { 9 9 u32 text_start; 10 10 u32 ro_end; 11 - u32 end; 12 11 /* reboot */ 13 12 #ifdef CONFIG_X86_32 14 13 u32 machine_real_restart_asm; ··· 29 30 #endif 30 31 } __attribute__((__packed__)); 31 32 32 - extern struct real_mode_header real_mode_header; 33 - extern unsigned char *real_mode_base; 33 + extern struct real_mode_header *real_mode_header; 34 + extern unsigned char real_mode_blob_end[]; 34 35 35 36 extern unsigned long init_rsp; 36 37 extern unsigned long initial_code;
+1 -1
arch/x86/kernel/acpi/sleep.c
··· 38 38 int acpi_suspend_lowlevel(void) 39 39 { 40 40 struct wakeup_header *header = 41 - (struct wakeup_header *) __va(real_mode_header.wakeup_header); 41 + (struct wakeup_header *) __va(real_mode_header->wakeup_header); 42 42 43 43 if (header->signature != WAKEUP_HEADER_SIGNATURE) { 44 44 printk(KERN_ERR "wakeup header does not match\n");
+25 -32
arch/x86/kernel/realmode.c
··· 5 5 #include <asm/pgtable.h> 6 6 #include <asm/realmode.h> 7 7 8 - unsigned char *real_mode_base; 9 - struct real_mode_header real_mode_header; 8 + struct real_mode_header *real_mode_header; 10 9 11 10 void __init setup_real_mode(void) 12 11 { ··· 16 17 u32 *ptr; 17 18 u16 *seg; 18 19 int i; 20 + unsigned char *base; 19 21 20 - struct real_mode_header *header = 21 - (struct real_mode_header *) real_mode_blob; 22 - 23 - size_t size = PAGE_ALIGN(header->end); 22 + size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); 24 23 25 24 /* Has to be in very low memory so we can execute real-mode AP code. */ 26 25 mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); 27 26 if (!mem) 28 27 panic("Cannot allocate trampoline\n"); 29 28 30 - real_mode_base = __va(mem); 29 + base = __va(mem); 31 30 memblock_reserve(mem, size); 31 + real_mode_header = (struct real_mode_header *) base; 32 32 33 33 printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n", 34 - real_mode_base, (unsigned long long)mem, size); 34 + base, (unsigned long long)mem, size); 35 35 36 - memcpy(real_mode_base, real_mode_blob, size); 36 + memcpy(base, real_mode_blob, size); 37 37 38 - real_mode_seg = __pa(real_mode_base) >> 4; 38 + real_mode_seg = __pa(base) >> 4; 39 39 rel = (u32 *) real_mode_relocs; 40 40 41 41 /* 16-bit segment relocations. */ 42 42 count = rel[0]; 43 43 rel = &rel[1]; 44 44 for (i = 0; i < count; i++) { 45 - seg = (u16 *) (real_mode_base + rel[i]); 45 + seg = (u16 *) (base + rel[i]); 46 46 *seg = real_mode_seg; 47 47 } 48 48 ··· 49 51 count = rel[i]; 50 52 rel = &rel[i + 1]; 51 53 for (i = 0; i < count; i++) { 52 - ptr = (u32 *) (real_mode_base + rel[i]); 53 - *ptr += __pa(real_mode_base); 54 + ptr = (u32 *) (base + rel[i]); 55 + *ptr += __pa(base); 54 56 } 55 57 56 - /* Copied header will contain relocated physical addresses. */ 57 - memcpy(&real_mode_header, real_mode_base, 58 - sizeof(struct real_mode_header)); 59 - 60 58 #ifdef CONFIG_X86_32 61 - *((u32 *)__va(real_mode_header.startup_32_smp)) = __pa(startup_32_smp); 62 - *((u32 *)__va(real_mode_header.boot_gdt)) = __pa(boot_gdt); 59 + *((u32 *)__va(real_mode_header->startup_32_smp)) = __pa(startup_32_smp); 60 + *((u32 *)__va(real_mode_header->boot_gdt)) = __pa(boot_gdt); 63 61 #else 64 - *((u64 *) __va(real_mode_header.startup_64_smp)) = 62 + *((u64 *) __va(real_mode_header->startup_64_smp)) = 65 63 (u64)secondary_startup_64; 66 64 67 - *((u64 *) __va(real_mode_header.level3_ident_pgt)) = 65 + *((u64 *) __va(real_mode_header->level3_ident_pgt)) = 68 66 __pa(level3_ident_pgt) + _KERNPG_TABLE; 69 67 70 - *((u64 *) __va(real_mode_header.level3_kernel_pgt)) = 68 + *((u64 *) __va(real_mode_header->level3_kernel_pgt)) = 71 69 __pa(level3_kernel_pgt) + _KERNPG_TABLE; 72 70 #endif 73 71 } ··· 76 82 */ 77 83 static int __init set_real_mode_permissions(void) 78 84 { 79 - size_t all_size = 80 - PAGE_ALIGN(real_mode_header.end) - 81 - __pa(real_mode_base); 85 + unsigned char *base = (unsigned char *) real_mode_header; 86 + size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); 82 87 83 88 size_t ro_size = 84 - PAGE_ALIGN(real_mode_header.ro_end) - 85 - __pa(real_mode_base); 89 + PAGE_ALIGN(real_mode_header->ro_end) - 90 + __pa(base); 86 91 87 92 size_t text_size = 88 - PAGE_ALIGN(real_mode_header.ro_end) - 89 - real_mode_header.text_start; 93 + PAGE_ALIGN(real_mode_header->ro_end) - 94 + real_mode_header->text_start; 90 95 91 96 unsigned long text_start = 92 - (unsigned long) __va(real_mode_header.text_start); 97 + (unsigned long) __va(real_mode_header->text_start); 93 98 94 - set_memory_nx((unsigned long) real_mode_base, all_size >> PAGE_SHIFT); 95 - set_memory_ro((unsigned long) real_mode_base, ro_size >> PAGE_SHIFT); 99 + set_memory_nx((unsigned long) base, size >> PAGE_SHIFT); 100 + set_memory_ro((unsigned long) base, ro_size >> PAGE_SHIFT); 96 101 set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT); 97 102 98 103 return 0;
+1 -1
arch/x86/kernel/reboot.c
··· 336 336 void machine_real_restart(unsigned int type) 337 337 { 338 338 void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) 339 - real_mode_header.machine_real_restart_asm; 339 + real_mode_header->machine_real_restart_asm; 340 340 341 341 local_irq_disable(); 342 342
+2 -2
arch/x86/kernel/smpboot.c
··· 665 665 static int __cpuinit do_boot_cpu(int apicid, int cpu) 666 666 { 667 667 volatile u32 *trampoline_status = 668 - (volatile u32 *) __va(real_mode_header.trampoline_status); 668 + (volatile u32 *) __va(real_mode_header->trampoline_status); 669 669 /* start_ip had better be page-aligned! */ 670 - unsigned long start_ip = real_mode_header.trampoline_data; 670 + unsigned long start_ip = real_mode_header->trampoline_data; 671 671 672 672 unsigned long boot_error = 0; 673 673 int timeout;
+1 -1
arch/x86/kernel/tboot.c
··· 202 202 } 203 203 204 204 tboot->acpi_sinfo.kernel_s3_resume_vector = 205 - real_mode_header.wakeup_start; 205 + real_mode_header->wakeup_start; 206 206 207 207 return 0; 208 208 }
-1
arch/x86/realmode/rm/header.S
··· 12 12 GLOBAL(real_mode_header) 13 13 .long pa_text_start 14 14 .long pa_ro_end 15 - .long pa_end 16 15 #ifdef CONFIG_X86_32 17 16 .long pa_machine_real_restart_asm 18 17 #endif
-1
arch/x86/realmode/rm/realmode.lds.S
··· 65 65 .signature : { 66 66 *(.signature) 67 67 } 68 - pa_end = .; 69 68 70 69 /DISCARD/ : { 71 70 *(.note*)
+2
arch/x86/realmode/rmpiggy.S
··· 13 13 .incbin "arch/x86/realmode/rm/realmode.bin" 14 14 END(real_mode_blob) 15 15 16 + GLOBAL(real_mode_blob_end); 17 + 16 18 GLOBAL(real_mode_relocs) 17 19 .incbin "arch/x86/realmode/rm/realmode.relocs" 18 20 END(real_mode_relocs)
+1 -1
drivers/acpi/sleep.c
··· 93 93 static int acpi_sleep_prepare(u32 acpi_state) 94 94 { 95 95 #ifdef CONFIG_ACPI_SLEEP 96 - unsigned long wakeup_pa = real_mode_header.wakeup_start; 96 + unsigned long wakeup_pa = real_mode_header->wakeup_start; 97 97 /* do we have a wakeup address for S2 and S3? */ 98 98 if (acpi_state == ACPI_STATE_S3) { 99 99 if (!wakeup_pa)