mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
Merge branch 'work.sparc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
This commit is contained in:
@@ -50,16 +50,12 @@ struct thread_struct {
|
|||||||
unsigned long fsr;
|
unsigned long fsr;
|
||||||
unsigned long fpqdepth;
|
unsigned long fpqdepth;
|
||||||
struct fpq fpqueue[16];
|
struct fpq fpqueue[16];
|
||||||
unsigned long flags;
|
|
||||||
mm_segment_t current_ds;
|
mm_segment_t current_ds;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */
|
|
||||||
#define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */
|
|
||||||
|
|
||||||
#define INIT_THREAD { \
|
#define INIT_THREAD { \
|
||||||
.flags = SPARC_FLAG_KTHREAD, \
|
|
||||||
.current_ds = KERNEL_DS, \
|
.current_ds = KERNEL_DS, \
|
||||||
|
.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do necessary setup to start up a newly executed thread. */
|
/* Do necessary setup to start up a newly executed thread. */
|
||||||
|
@@ -118,6 +118,7 @@ struct thread_info {
|
|||||||
.task = &tsk, \
|
.task = &tsk, \
|
||||||
.current_ds = ASI_P, \
|
.current_ds = ASI_P, \
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
|
.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* how to get the thread information struct from C */
|
/* how to get the thread information struct from C */
|
||||||
|
@@ -515,7 +515,7 @@ continue_boot:
|
|||||||
|
|
||||||
/* I want a kernel stack NOW! */
|
/* I want a kernel stack NOW! */
|
||||||
set init_thread_union, %g1
|
set init_thread_union, %g1
|
||||||
set (THREAD_SIZE - STACKFRAME_SZ), %g2
|
set (THREAD_SIZE - STACKFRAME_SZ - TRACEREG_SZ), %g2
|
||||||
add %g1, %g2, %sp
|
add %g1, %g2, %sp
|
||||||
mov 0, %fp /* And for good luck */
|
mov 0, %fp /* And for good luck */
|
||||||
|
|
||||||
|
@@ -706,7 +706,7 @@ tlb_fixup_done:
|
|||||||
wr %g0, ASI_P, %asi
|
wr %g0, ASI_P, %asi
|
||||||
mov 1, %g1
|
mov 1, %g1
|
||||||
sllx %g1, THREAD_SHIFT, %g1
|
sllx %g1, THREAD_SHIFT, %g1
|
||||||
sub %g1, (STACKFRAME_SZ + STACK_BIAS), %g1
|
sub %g1, (STACKFRAME_SZ + STACK_BIAS + TRACEREG_SZ), %g1
|
||||||
add %g6, %g1, %sp
|
add %g6, %g1, %sp
|
||||||
|
|
||||||
/* Set per-cpu pointer initially to zero, this makes
|
/* Set per-cpu pointer initially to zero, this makes
|
||||||
|
@@ -216,16 +216,6 @@ void flush_thread(void)
|
|||||||
clear_thread_flag(TIF_USEDFPU);
|
clear_thread_flag(TIF_USEDFPU);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This task is no longer a kernel thread. */
|
|
||||||
if (current->thread.flags & SPARC_FLAG_KTHREAD) {
|
|
||||||
current->thread.flags &= ~SPARC_FLAG_KTHREAD;
|
|
||||||
|
|
||||||
/* We must fixup kregs as well. */
|
|
||||||
/* XXX This was not fixed for ti for a while, worked. Unused? */
|
|
||||||
current->thread.kregs = (struct pt_regs *)
|
|
||||||
(task_stack_page(current) + (THREAD_SIZE - TRACEREG_SZ));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct sparc_stackf __user *
|
static inline struct sparc_stackf __user *
|
||||||
@@ -313,7 +303,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
|
|||||||
extern int nwindows;
|
extern int nwindows;
|
||||||
unsigned long psr;
|
unsigned long psr;
|
||||||
memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ);
|
memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ);
|
||||||
p->thread.flags |= SPARC_FLAG_KTHREAD;
|
|
||||||
p->thread.current_ds = KERNEL_DS;
|
p->thread.current_ds = KERNEL_DS;
|
||||||
ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8);
|
ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8);
|
||||||
childregs->u_regs[UREG_G1] = sp; /* function */
|
childregs->u_regs[UREG_G1] = sp; /* function */
|
||||||
@@ -325,7 +314,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
|
|||||||
}
|
}
|
||||||
memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ);
|
memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ);
|
||||||
childregs->u_regs[UREG_FP] = sp;
|
childregs->u_regs[UREG_FP] = sp;
|
||||||
p->thread.flags &= ~SPARC_FLAG_KTHREAD;
|
|
||||||
p->thread.current_ds = USER_DS;
|
p->thread.current_ds = USER_DS;
|
||||||
ti->kpc = (((unsigned long) ret_from_fork) - 0x8);
|
ti->kpc = (((unsigned long) ret_from_fork) - 0x8);
|
||||||
ti->kpsr = current->thread.fork_kpsr | PSR_PIL;
|
ti->kpsr = current->thread.fork_kpsr | PSR_PIL;
|
||||||
|
@@ -266,7 +266,6 @@ static __init void leon_patch(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct tt_entry *sparc_ttable;
|
struct tt_entry *sparc_ttable;
|
||||||
static struct pt_regs fake_swapper_regs;
|
|
||||||
|
|
||||||
/* Called from head_32.S - before we have setup anything
|
/* Called from head_32.S - before we have setup anything
|
||||||
* in the kernel. Be very careful with what you do here.
|
* in the kernel. Be very careful with what you do here.
|
||||||
@@ -363,8 +362,6 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
(*(linux_dbvec->teach_debugger))();
|
(*(linux_dbvec->teach_debugger))();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_task.thread.kregs = &fake_swapper_regs;
|
|
||||||
|
|
||||||
/* Run-time patch instructions to match the cpu model */
|
/* Run-time patch instructions to match the cpu model */
|
||||||
per_cpu_patch();
|
per_cpu_patch();
|
||||||
|
|
||||||
|
@@ -165,8 +165,6 @@ extern int root_mountflags;
|
|||||||
|
|
||||||
char reboot_command[COMMAND_LINE_SIZE];
|
char reboot_command[COMMAND_LINE_SIZE];
|
||||||
|
|
||||||
static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
static void __init per_cpu_patch(void)
|
static void __init per_cpu_patch(void)
|
||||||
{
|
{
|
||||||
struct cpuid_patch_entry *p;
|
struct cpuid_patch_entry *p;
|
||||||
@@ -661,8 +659,6 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
|
rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
task_thread_info(&init_task)->kregs = &fake_swapper_regs;
|
|
||||||
|
|
||||||
#ifdef CONFIG_IP_PNP
|
#ifdef CONFIG_IP_PNP
|
||||||
if (!ic_set_manually) {
|
if (!ic_set_manually) {
|
||||||
phandle chosen = prom_finddevice("/chosen");
|
phandle chosen = prom_finddevice("/chosen");
|
||||||
|
@@ -274,103 +274,9 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
|
asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
||||||
enum direction dir)
|
|
||||||
{
|
|
||||||
unsigned int reg;
|
|
||||||
int size = ((insn >> 19) & 3) == 3 ? 8 : 4;
|
|
||||||
|
|
||||||
if ((regs->pc | regs->npc) & 3)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Must access_ok() in all the necessary places. */
|
|
||||||
#define WINREG_ADDR(regnum) \
|
|
||||||
((void __user *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))
|
|
||||||
|
|
||||||
reg = (insn >> 25) & 0x1f;
|
|
||||||
if (reg >= 16) {
|
|
||||||
if (!access_ok(WINREG_ADDR(reg - 16), size))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
reg = (insn >> 14) & 0x1f;
|
|
||||||
if (reg >= 16) {
|
|
||||||
if (!access_ok(WINREG_ADDR(reg - 16), size))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
if (!(insn & 0x2000)) {
|
|
||||||
reg = (insn & 0x1f);
|
|
||||||
if (reg >= 16) {
|
|
||||||
if (!access_ok(WINREG_ADDR(reg - 16), size))
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef WINREG_ADDR
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
|
|
||||||
{
|
{
|
||||||
send_sig_fault(SIGBUS, BUS_ADRALN,
|
send_sig_fault(SIGBUS, BUS_ADRALN,
|
||||||
(void __user *)safe_compute_effective_address(regs, insn),
|
(void __user *)safe_compute_effective_address(regs, insn),
|
||||||
0, current);
|
0, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
|
||||||
{
|
|
||||||
enum direction dir;
|
|
||||||
|
|
||||||
if(!(current->thread.flags & SPARC_FLAG_UNALIGNED) ||
|
|
||||||
(((insn >> 30) & 3) != 3))
|
|
||||||
goto kill_user;
|
|
||||||
dir = decode_direction(insn);
|
|
||||||
if(!ok_for_user(regs, insn, dir)) {
|
|
||||||
goto kill_user;
|
|
||||||
} else {
|
|
||||||
int err, size = decode_access_size(insn);
|
|
||||||
unsigned long addr;
|
|
||||||
|
|
||||||
if(floating_point_load_or_store_p(insn)) {
|
|
||||||
printk("User FPU load/store unaligned unsupported.\n");
|
|
||||||
goto kill_user;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = compute_effective_address(regs, insn);
|
|
||||||
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
|
|
||||||
switch(dir) {
|
|
||||||
case load:
|
|
||||||
err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
|
|
||||||
regs),
|
|
||||||
size, (unsigned long *) addr,
|
|
||||||
decode_signedness(insn));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case store:
|
|
||||||
err = do_int_store(((insn>>25)&0x1f), size,
|
|
||||||
(unsigned long *) addr, regs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case both:
|
|
||||||
/*
|
|
||||||
* This was supported in 2.4. However, we question
|
|
||||||
* the value of SWAP instruction across word boundaries.
|
|
||||||
*/
|
|
||||||
printk("Unaligned SWAP unsupported.\n");
|
|
||||||
err = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
unaligned_panic("Impossible user unaligned trap.");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (err)
|
|
||||||
goto kill_user;
|
|
||||||
else
|
|
||||||
advance(regs);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
kill_user:
|
|
||||||
user_mna_trap_fault(regs, insn);
|
|
||||||
out:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user