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

parisc: Initialize the fault vector earlier in the boot process.

A fault vector on parisc needs to be 2K aligned. Furthermore the
checksum of the fault vector needs to sum up to 0 which is being
calculated and written at runtime.

Up to now we aligned both PA20 and PA11 fault vectors on the same 4K
page in order to easily write the checksum after having mapped the
kernel read-only (by mapping this page only as read-write).
But when we want to map the kernel text and data on huge pages this
makes things harder.
So, simplify it by aligning both fault vectors on 2K boundries and write
the checksum before we map the page read-only.

Signed-off-by: Helge Deller <deller@gmx.de>

+21 -28
+3 -8
arch/parisc/kernel/entry.S
··· 646 646 647 647 648 648 /* 649 - * Align fault_vector_20 on 4K boundary so that both 650 - * fault_vector_11 and fault_vector_20 are on the 651 - * same page. This is only necessary as long as we 652 - * write protect the kernel text, which we may stop 653 - * doing once we use large page translations to cover 654 - * the static part of the kernel address space. 649 + * Fault_vectors are architecturally required to be aligned on a 2K 650 + * boundary 655 651 */ 656 652 657 653 .text 658 - 659 - .align 4096 654 + .align 2048 660 655 661 656 ENTRY(fault_vector_20) 662 657 /* First vector is invalid (0) */
+3
arch/parisc/kernel/setup.c
··· 377 377 void start_parisc(void) 378 378 { 379 379 extern void start_kernel(void); 380 + extern void early_trap_init(void); 380 381 381 382 int ret, cpunum; 382 383 struct pdc_coproc_cfg coproc_cfg; ··· 397 396 } else { 398 397 panic("must have an fpu to boot linux"); 399 398 } 399 + 400 + early_trap_init(); /* initialize checksum of fault_vector */ 400 401 401 402 start_kernel(); 402 403 // not reached
+15 -20
arch/parisc/kernel/traps.c
··· 807 807 } 808 808 809 809 810 - int __init check_ivt(void *iva) 810 + void __init initialize_ivt(const void *iva) 811 811 { 812 812 extern u32 os_hpmc_size; 813 813 extern const u32 os_hpmc[]; ··· 818 818 u32 *hpmcp; 819 819 u32 length; 820 820 821 - if (strcmp((char *)iva, "cows can fly")) 822 - return -1; 821 + if (strcmp((const char *)iva, "cows can fly")) 822 + panic("IVT invalid"); 823 823 824 824 ivap = (u32 *)iva; 825 825 ··· 839 839 check += ivap[i]; 840 840 841 841 ivap[5] = -check; 842 - 843 - return 0; 844 842 } 845 843 844 + 845 + /* early_trap_init() is called before we set up kernel mappings and 846 + * write-protect the kernel */ 847 + void __init early_trap_init(void) 848 + { 849 + extern const void fault_vector_20; 850 + 846 851 #ifndef CONFIG_64BIT 847 - extern const void fault_vector_11; 852 + extern const void fault_vector_11; 853 + initialize_ivt(&fault_vector_11); 848 854 #endif 849 - extern const void fault_vector_20; 855 + 856 + initialize_ivt(&fault_vector_20); 857 + } 850 858 851 859 void __init trap_init(void) 852 860 { 853 - void *iva; 854 - 855 - if (boot_cpu_data.cpu_type >= pcxu) 856 - iva = (void *) &fault_vector_20; 857 - else 858 - #ifdef CONFIG_64BIT 859 - panic("Can't boot 64-bit OS on PA1.1 processor!"); 860 - #else 861 - iva = (void *) &fault_vector_11; 862 - #endif 863 - 864 - if (check_ivt(iva)) 865 - panic("IVT invalid"); 866 861 }