diff options
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/include/asm/oplib_64.h | 3 | ||||
| -rw-r--r-- | arch/sparc/include/asm/setup.h | 2 | ||||
| -rw-r--r-- | arch/sparc/include/uapi/asm/unistd.h | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/entry.h | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/head_64.S | 40 | ||||
| -rw-r--r-- | arch/sparc/kernel/hvtramp.S | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/setup_64.c | 28 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_32.S | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_64.S | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/trampoline_64.S | 12 | ||||
| -rw-r--r-- | arch/sparc/mm/gup.c | 30 | ||||
| -rw-r--r-- | arch/sparc/prom/cif.S | 5 | ||||
| -rw-r--r-- | arch/sparc/prom/init_64.c | 6 | ||||
| -rw-r--r-- | arch/sparc/prom/p1275.c | 2 | 
14 files changed, 75 insertions, 66 deletions
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index f34682430fcf..2e3a4add8591 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -62,7 +62,8 @@ struct linux_mem_p1275 {  /* You must call prom_init() before using any of the library services,   * preferably as early as possible.  Pass it the romvec pointer.   */ -void prom_init(void *cif_handler, void *cif_stack); +void prom_init(void *cif_handler); +void prom_init_report(void);  /* Boot argument acquisition, returns the boot command line string. */  char *prom_getbootargs(void); diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h index f5fffd84d0dd..29d64b1758ed 100644 --- a/arch/sparc/include/asm/setup.h +++ b/arch/sparc/include/asm/setup.h @@ -48,6 +48,8 @@ unsigned long safe_compute_effective_address(struct pt_regs *, unsigned int);  #endif  #ifdef CONFIG_SPARC64 +void __init start_early_boot(void); +  /* unaligned_64.c */  int handle_ldf_stq(u32 insn, struct pt_regs *regs);  void handle_ld_nf(u32 insn, struct pt_regs *regs); diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index c842a89b1190..46d83842eddc 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -414,8 +414,9 @@  #define __NR_seccomp		346  #define __NR_getrandom		347  #define __NR_memfd_create	348 +#define __NR_bpf		349 -#define NR_syscalls		349 +#define NR_syscalls		350  /* Bitmask values returned from kern_features system call.  */  #define KERN_FEATURE_MIXED_MODE_STACK	0x00000001 diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index ebaba6167dd4..88d322b67fac 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -65,13 +65,10 @@ struct pause_patch_entry {  extern struct pause_patch_entry __pause_3insn_patch,  	__pause_3insn_patch_end; -void __init per_cpu_patch(void);  void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,  			     struct sun4v_1insn_patch_entry *);  void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,  			     struct sun4v_2insn_patch_entry *); -void __init sun4v_patch(void); -void __init boot_cpu_id_too_large(int cpu);  extern unsigned int dcache_parity_tl1_occurred;  extern unsigned int icache_parity_tl1_occurred; diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 4fdeb8040d4d..3d61fcae7ee3 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -672,14 +672,12 @@ tlb_fixup_done:  	sethi	%hi(init_thread_union), %g6  	or	%g6, %lo(init_thread_union), %g6  	ldx	[%g6 + TI_TASK], %g4 -	mov	%sp, %l6  	wr	%g0, ASI_P, %asi  	mov	1, %g1  	sllx	%g1, THREAD_SHIFT, %g1  	sub	%g1, (STACKFRAME_SZ + STACK_BIAS), %g1  	add	%g6, %g1, %sp -	mov	0, %fp  	/* Set per-cpu pointer initially to zero, this makes  	 * the boot-cpu use the in-kernel-image per-cpu areas @@ -706,44 +704,14 @@ tlb_fixup_done:  	 nop  #endif -	mov	%l6, %o1			! OpenPROM stack  	call	prom_init  	 mov	%l7, %o0			! OpenPROM cif handler -	/* Initialize current_thread_info()->cpu as early as possible. -	 * In order to do that accurately we have to patch up the get_cpuid() -	 * assembler sequences.  And that, in turn, requires that we know -	 * if we are on a Starfire box or not.  While we're here, patch up -	 * the sun4v sequences as well. +	/* To create a one-register-window buffer between the kernel's +	 * initial stack and the last stack frame we use from the firmware, +	 * do the rest of the boot from a C helper function.  	 */ -	call	check_if_starfire -	 nop -	call	per_cpu_patch -	 nop -	call	sun4v_patch -	 nop - -#ifdef CONFIG_SMP -	call	hard_smp_processor_id -	 nop -	cmp	%o0, NR_CPUS -	blu,pt	%xcc, 1f -	 nop -	call	boot_cpu_id_too_large -	 nop -	/* Not reached... */ - -1: -#else -	mov	0, %o0 -#endif -	sth	%o0, [%g6 + TI_CPU] - -	call	prom_init_report -	 nop - -	/* Off we go.... */ -	call	start_kernel +	call	start_early_boot  	 nop  	/* Not reached... */ diff --git a/arch/sparc/kernel/hvtramp.S b/arch/sparc/kernel/hvtramp.S index b7ddcdd1dea9..cdbfec299f2f 100644 --- a/arch/sparc/kernel/hvtramp.S +++ b/arch/sparc/kernel/hvtramp.S @@ -109,7 +109,6 @@ hv_cpu_startup:  	sllx		%g5, THREAD_SHIFT, %g5  	sub		%g5, (STACKFRAME_SZ + STACK_BIAS), %g5  	add		%g6, %g5, %sp -	mov		0, %fp  	call		init_irqwork_curcpu  	 nop diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index e629b8377587..c38d19fc27ba 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -30,6 +30,7 @@  #include <linux/cpu.h>  #include <linux/initrd.h>  #include <linux/module.h> +#include <linux/start_kernel.h>  #include <asm/io.h>  #include <asm/processor.h> @@ -162,7 +163,7 @@ char reboot_command[COMMAND_LINE_SIZE];  static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; -void __init per_cpu_patch(void) +static void __init per_cpu_patch(void)  {  	struct cpuid_patch_entry *p;  	unsigned long ver; @@ -254,7 +255,7 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,  	}  } -void __init sun4v_patch(void) +static void __init sun4v_patch(void)  {  	extern void sun4v_hvapi_init(void); @@ -323,14 +324,25 @@ static void __init pause_patch(void)  	}  } -#ifdef CONFIG_SMP -void __init boot_cpu_id_too_large(int cpu) +void __init start_early_boot(void)  { -	prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n", -		    cpu, NR_CPUS); -	prom_halt(); +	int cpu; + +	check_if_starfire(); +	per_cpu_patch(); +	sun4v_patch(); + +	cpu = hard_smp_processor_id(); +	if (cpu >= NR_CPUS) { +		prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n", +			    cpu, NR_CPUS); +		prom_halt(); +	} +	current_thread_info()->cpu = cpu; + +	prom_init_report(); +	start_kernel();  } -#endif  /* On Ultra, we support all of the v8 capabilities. */  unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6a873c344bc0..ad0cdf497b78 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -86,4 +86,4 @@ sys_call_table:  /*330*/	.long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime  /*335*/	.long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev  /*340*/	.long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr -/*345*/	.long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create +/*345*/	.long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index d9151b6490d8..580cde9370c9 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -87,7 +87,7 @@ sys_call_table32:  /*330*/	.word compat_sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime  	.word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev  /*340*/	.word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr -	.word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create +	.word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf  #endif /* CONFIG_COMPAT */ @@ -166,4 +166,4 @@ sys_call_table:  /*330*/	.word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime  	.word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev  /*340*/	.word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr -	.word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create +	.word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S index 737f8cbc7d56..88ede1d53b4c 100644 --- a/arch/sparc/kernel/trampoline_64.S +++ b/arch/sparc/kernel/trampoline_64.S @@ -109,10 +109,13 @@ startup_continue:  	brnz,pn		%g1, 1b  	 nop -	sethi		%hi(p1275buf), %g2 -	or		%g2, %lo(p1275buf), %g2 -	ldx		[%g2 + 0x10], %l2 -	add		%l2, -(192 + 128), %sp +	/* Get onto temporary stack which will be in the locked +	 * kernel image. +	 */ +	sethi		%hi(tramp_stack), %g1 +	or		%g1, %lo(tramp_stack), %g1 +	add		%g1, TRAMP_STACK_SIZE, %g1 +	sub		%g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp  	flushw  	/* Setup the loop variables: @@ -394,7 +397,6 @@ after_lock_tlb:  	sllx		%g5, THREAD_SHIFT, %g5  	sub		%g5, (STACKFRAME_SZ + STACK_BIAS), %g5  	add		%g6, %g5, %sp -	mov		0, %fp  	rdpr		%pstate, %o1  	or		%o1, PSTATE_IE, %o1 diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index 1aed0432c64b..ae6ce383d4df 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c @@ -160,6 +160,36 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,  	return 1;  } +int __get_user_pages_fast(unsigned long start, int nr_pages, int write, +			  struct page **pages) +{ +	struct mm_struct *mm = current->mm; +	unsigned long addr, len, end; +	unsigned long next, flags; +	pgd_t *pgdp; +	int nr = 0; + +	start &= PAGE_MASK; +	addr = start; +	len = (unsigned long) nr_pages << PAGE_SHIFT; +	end = start + len; + +	local_irq_save(flags); +	pgdp = pgd_offset(mm, addr); +	do { +		pgd_t pgd = *pgdp; + +		next = pgd_addr_end(addr, end); +		if (pgd_none(pgd)) +			break; +		if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) +			break; +	} while (pgdp++, addr = next, addr != end); +	local_irq_restore(flags); + +	return nr; +} +  int get_user_pages_fast(unsigned long start, int nr_pages, int write,  			struct page **pages)  { diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S index 9c86b4b7d429..8050f381f518 100644 --- a/arch/sparc/prom/cif.S +++ b/arch/sparc/prom/cif.S @@ -11,11 +11,10 @@  	.text  	.globl	prom_cif_direct  prom_cif_direct: +	save	%sp, -192, %sp  	sethi	%hi(p1275buf), %o1  	or	%o1, %lo(p1275buf), %o1 -	ldx	[%o1 + 0x0010], %o2	! prom_cif_stack -	save	%o2, -192, %sp -	ldx	[%i1 + 0x0008], %l2	! prom_cif_handler +	ldx	[%o1 + 0x0008], %l2	! prom_cif_handler  	mov	%g4, %l0  	mov	%g5, %l1  	mov	%g6, %l3 diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c index d95db755828f..110b0d78b864 100644 --- a/arch/sparc/prom/init_64.c +++ b/arch/sparc/prom/init_64.c @@ -26,13 +26,13 @@ phandle prom_chosen_node;   * It gets passed the pointer to the PROM vector.   */ -extern void prom_cif_init(void *, void *); +extern void prom_cif_init(void *); -void __init prom_init(void *cif_handler, void *cif_stack) +void __init prom_init(void *cif_handler)  {  	phandle node; -	prom_cif_init(cif_handler, cif_stack); +	prom_cif_init(cif_handler);  	prom_chosen_node = prom_finddevice(prom_chosen_path);  	if (!prom_chosen_node || (s32)prom_chosen_node == -1) diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c index b2340f008ae0..545d8bb79b65 100644 --- a/arch/sparc/prom/p1275.c +++ b/arch/sparc/prom/p1275.c @@ -20,7 +20,6 @@  struct {  	long prom_callback;			/* 0x00 */  	void (*prom_cif_handler)(long *);	/* 0x08 */ -	unsigned long prom_cif_stack;		/* 0x10 */  } p1275buf;  extern void prom_world(int); @@ -52,5 +51,4 @@ void p1275_cmd_direct(unsigned long *args)  void prom_cif_init(void *cif_handler, void *cif_stack)  {  	p1275buf.prom_cif_handler = (void (*)(long *))cif_handler; -	p1275buf.prom_cif_stack = (unsigned long)cif_stack;  }  |