summaryrefslogtreecommitdiff
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/cpu-probe.c42
-rw-r--r--arch/mips/kernel/gpio_txx9.c8
-rw-r--r--arch/mips/kernel/mips-cm.c52
-rw-r--r--arch/mips/kernel/process.c16
-rw-r--r--arch/mips/kernel/ptrace.c54
-rw-r--r--arch/mips/kernel/relocate.c10
-rw-r--r--arch/mips/kernel/smp-cps.c18
-rw-r--r--arch/mips/kernel/smp.c18
-rw-r--r--arch/mips/kernel/syscalls/syscall_n32.tbl2
-rw-r--r--arch/mips/kernel/syscalls/syscall_n64.tbl2
-rw-r--r--arch/mips/kernel/syscalls/syscall_o32.tbl2
-rw-r--r--arch/mips/kernel/vpe.c3
13 files changed, 152 insertions, 77 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index ecf3278a32f7..95a1e674fd67 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -3,7 +3,7 @@
# Makefile for the Linux/MIPS kernel.
#
-extra-y := vmlinux.lds
+always-$(KBUILD_BUILTIN) := vmlinux.lds
obj-y += head.o branch.o cmpxchg.o elf.o entry.o genex.o idle.o irq.o \
process.o prom.o ptrace.o reset.o setup.o signal.o \
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index af7412549e6e..04dc9ab55524 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -9,6 +9,7 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/mmu_context.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
#include <linux/stddef.h>
@@ -37,6 +38,8 @@
unsigned int elf_hwcap __read_mostly;
EXPORT_SYMBOL_GPL(elf_hwcap);
+static bool mmid_disabled_quirk;
+
static inline unsigned long cpu_get_msa_id(void)
{
unsigned long status, msa_id;
@@ -645,7 +648,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
if (cpu_has_mips_r6) {
- if (!__builtin_constant_p(cpu_has_mmid) || cpu_has_mmid)
+ if (!mmid_disabled_quirk && (!__builtin_constant_p(cpu_has_mmid) || cpu_has_mmid))
config5 |= MIPS_CONF5_MI;
else
config5 &= ~MIPS_CONF5_MI;
@@ -708,7 +711,6 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
max_mmid_width);
asid_mask = GENMASK(max_mmid_width - 1, 0);
}
-
set_cpu_asid_mask(c, asid_mask);
}
}
@@ -2046,3 +2048,39 @@ void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe)
cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP;
cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF;
}
+
+void cpu_disable_mmid(void)
+{
+ int i;
+ unsigned long asid_mask;
+ unsigned int cpu = smp_processor_id();
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config4 = read_c0_config4();
+ unsigned int config5 = read_c0_config5();
+
+ /* Setup the initial ASID mask based on config4 */
+ asid_mask = MIPS_ENTRYHI_ASID;
+ if (config4 & MIPS_CONF4_AE)
+ asid_mask |= MIPS_ENTRYHI_ASIDX;
+ set_cpu_asid_mask(c, asid_mask);
+
+ /* Disable MMID in the C0 and update cpuinfo_mips accordingly */
+ config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
+ config5 &= ~MIPS_CONF5_MI;
+ write_c0_config5(config5);
+ /* Ensure the write to config5 above takes effect */
+ back_to_back_c0_hazard();
+ c->options &= ~MIPS_CPU_MMID;
+
+ /* Setup asid cache value cleared in per_cpu_trap_init() */
+ cpu_data[cpu].asid_cache = asid_first_version(cpu);
+
+ /* Reinit context for each CPU */
+ for_each_possible_cpu(i)
+ set_cpu_context(i, &init_mm, 0);
+
+ /* Ensure that now MMID will be seen as disable */
+ mmid_disabled_quirk = true;
+
+ pr_info("MMID support disabled due to hardware support issue\n");
+}
diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c
index 8c083612df9d..027fb57d0d79 100644
--- a/arch/mips/kernel/gpio_txx9.c
+++ b/arch/mips/kernel/gpio_txx9.c
@@ -32,14 +32,16 @@ static void txx9_gpio_set_raw(unsigned int offset, int value)
__raw_writel(val, &txx9_pioptr->dout);
}
-static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
- int value)
+static int txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
{
unsigned long flags;
spin_lock_irqsave(&txx9_gpio_lock, flags);
txx9_gpio_set_raw(offset, value);
mmiowb();
spin_unlock_irqrestore(&txx9_gpio_lock, flags);
+
+ return 0;
}
static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
@@ -68,7 +70,7 @@ static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
static struct gpio_chip txx9_gpio_chip = {
.get = txx9_gpio_get,
- .set = txx9_gpio_set,
+ .set_rv = txx9_gpio_set,
.direction_input = txx9_gpio_dir_in,
.direction_output = txx9_gpio_dir_out,
.label = "TXx9",
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 43cb1e20baed..7c9c5dc38823 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -10,6 +10,7 @@
#include <linux/spinlock.h>
#include <asm/mips-cps.h>
+#include <asm/smp-cps.h>
#include <asm/mipsregs.h>
void __iomem *mips_gcr_base;
@@ -248,6 +249,11 @@ void mips_cm_update_property(void)
return;
pr_info("HCI (Hardware Cache Init for the L2 cache) in GCR_L2_RAM_CONFIG from the CM3 is broken");
mips_cm_is_l2_hci_broken = true;
+
+ /* Disable MMID only if it was configured */
+ if (cpu_has_mmid)
+ cpu_disable_mmid();
+
of_node_put(cm_node);
}
@@ -529,39 +535,23 @@ void mips_cm_error_report(void)
write_gcr_error_cause(cm_error);
}
-unsigned int mips_cps_first_online_in_cluster(void)
+unsigned int mips_cps_first_online_in_cluster(int *first_cpu)
{
- unsigned int local_cl;
- int i;
-
- local_cl = cpu_cluster(&current_cpu_data);
+ unsigned int local_cl = cpu_cluster(&current_cpu_data);
+ struct cpumask *local_cl_mask;
/*
- * We rely upon knowledge that CPUs are numbered sequentially by
- * cluster - ie. CPUs 0..X will be in cluster 0, CPUs X+1..Y in cluster
- * 1, CPUs Y+1..Z in cluster 2 etc. This means that CPUs in the same
- * cluster will immediately precede or follow one another.
- *
- * First we scan backwards, until we find an online CPU in the cluster
- * or we move on to another cluster.
+ * mips_cps_cluster_bootcfg is allocated in cps_prepare_cpus. If it is
+ * not yet done, then we are so early that only one CPU is running, so
+ * it is the first online CPU in the cluster.
*/
- for (i = smp_processor_id() - 1; i >= 0; i--) {
- if (cpu_cluster(&cpu_data[i]) != local_cl)
- break;
- if (!cpu_online(i))
- continue;
- return false;
- }
-
- /* Then do the same for higher numbered CPUs */
- for (i = smp_processor_id() + 1; i < nr_cpu_ids; i++) {
- if (cpu_cluster(&cpu_data[i]) != local_cl)
- break;
- if (!cpu_online(i))
- continue;
- return false;
- }
-
- /* We found no online CPUs in the local cluster */
- return true;
+ if (IS_ENABLED(CONFIG_MIPS_CPS) && mips_cps_cluster_bootcfg)
+ local_cl_mask = &mips_cps_cluster_bootcfg[local_cl].cpumask;
+ else
+ return true;
+
+ *first_cpu = cpumask_any_and_but(local_cl_mask,
+ cpu_online_mask,
+ smp_processor_id());
+ return (*first_cpu >= nr_cpu_ids);
}
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index b630604c577f..02aa6a04a21d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -690,18 +690,20 @@ unsigned long mips_stack_top(void)
}
/* Space for the VDSO, data page & GIC user page */
- top -= PAGE_ALIGN(current->thread.abi->vdso->size);
- top -= PAGE_SIZE;
- top -= mips_gic_present() ? PAGE_SIZE : 0;
+ if (current->thread.abi) {
+ top -= PAGE_ALIGN(current->thread.abi->vdso->size);
+ top -= PAGE_SIZE;
+ top -= mips_gic_present() ? PAGE_SIZE : 0;
+
+ /* Space to randomize the VDSO base */
+ if (current->flags & PF_RANDOMIZE)
+ top -= VDSO_RANDOMIZE_SIZE;
+ }
/* Space for cache colour alignment */
if (cpu_has_dc_aliases)
top -= shm_align_mask + 1;
- /* Space to randomize the VDSO base */
- if (current->flags & PF_RANDOMIZE)
- top -= VDSO_RANDOMIZE_SIZE;
-
return top;
}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index f7107479c7fa..3f4c94c88124 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -922,58 +922,60 @@ static const struct pt_regs_offset regoffset_table[] = {
*/
int regs_query_register_offset(const char *name)
{
- const struct pt_regs_offset *roff;
- for (roff = regoffset_table; roff->name != NULL; roff++)
- if (!strcmp(roff->name, name))
- return roff->offset;
- return -EINVAL;
+ const struct pt_regs_offset *roff;
+
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+
+ return -EINVAL;
}
#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
static const struct user_regset mips_regsets[] = {
[REGSET_GPR] = {
- .core_note_type = NT_PRSTATUS,
+ USER_REGSET_NOTE_TYPE(PRSTATUS),
.n = ELF_NGREG,
.size = sizeof(unsigned int),
.align = sizeof(unsigned int),
- .regset_get = gpr32_get,
+ .regset_get = gpr32_get,
.set = gpr32_set,
},
[REGSET_DSP] = {
- .core_note_type = NT_MIPS_DSP,
+ USER_REGSET_NOTE_TYPE(MIPS_DSP),
.n = NUM_DSP_REGS + 1,
.size = sizeof(u32),
.align = sizeof(u32),
- .regset_get = dsp32_get,
+ .regset_get = dsp32_get,
.set = dsp32_set,
.active = dsp_active,
},
#ifdef CONFIG_MIPS_FP_SUPPORT
[REGSET_FPR] = {
- .core_note_type = NT_PRFPREG,
+ USER_REGSET_NOTE_TYPE(PRFPREG),
.n = ELF_NFPREG,
.size = sizeof(elf_fpreg_t),
.align = sizeof(elf_fpreg_t),
- .regset_get = fpr_get,
+ .regset_get = fpr_get,
.set = fpr_set,
},
[REGSET_FP_MODE] = {
- .core_note_type = NT_MIPS_FP_MODE,
+ USER_REGSET_NOTE_TYPE(MIPS_FP_MODE),
.n = 1,
.size = sizeof(int),
.align = sizeof(int),
- .regset_get = fp_mode_get,
+ .regset_get = fp_mode_get,
.set = fp_mode_set,
},
#endif
#ifdef CONFIG_CPU_HAS_MSA
[REGSET_MSA] = {
- .core_note_type = NT_MIPS_MSA,
+ USER_REGSET_NOTE_TYPE(MIPS_MSA),
.n = NUM_FPU_REGS + 1,
.size = 16,
.align = 16,
- .regset_get = msa_get,
+ .regset_get = msa_get,
.set = msa_set,
},
#endif
@@ -993,47 +995,47 @@ static const struct user_regset_view user_mips_view = {
static const struct user_regset mips64_regsets[] = {
[REGSET_GPR] = {
- .core_note_type = NT_PRSTATUS,
+ USER_REGSET_NOTE_TYPE(PRSTATUS),
.n = ELF_NGREG,
.size = sizeof(unsigned long),
.align = sizeof(unsigned long),
- .regset_get = gpr64_get,
+ .regset_get = gpr64_get,
.set = gpr64_set,
},
[REGSET_DSP] = {
- .core_note_type = NT_MIPS_DSP,
+ USER_REGSET_NOTE_TYPE(MIPS_DSP),
.n = NUM_DSP_REGS + 1,
.size = sizeof(u64),
.align = sizeof(u64),
- .regset_get = dsp64_get,
+ .regset_get = dsp64_get,
.set = dsp64_set,
.active = dsp_active,
},
#ifdef CONFIG_MIPS_FP_SUPPORT
[REGSET_FP_MODE] = {
- .core_note_type = NT_MIPS_FP_MODE,
+ USER_REGSET_NOTE_TYPE(MIPS_FP_MODE),
.n = 1,
.size = sizeof(int),
.align = sizeof(int),
- .regset_get = fp_mode_get,
+ .regset_get = fp_mode_get,
.set = fp_mode_set,
},
[REGSET_FPR] = {
- .core_note_type = NT_PRFPREG,
+ USER_REGSET_NOTE_TYPE(PRFPREG),
.n = ELF_NFPREG,
.size = sizeof(elf_fpreg_t),
.align = sizeof(elf_fpreg_t),
- .regset_get = fpr_get,
+ .regset_get = fpr_get,
.set = fpr_set,
},
#endif
#ifdef CONFIG_CPU_HAS_MSA
[REGSET_MSA] = {
- .core_note_type = NT_MIPS_MSA,
+ USER_REGSET_NOTE_TYPE(MIPS_MSA),
.n = NUM_FPU_REGS + 1,
.size = 16,
.align = 16,
- .regset_get = msa_get,
+ .regset_get = msa_get,
.set = msa_set,
},
#endif
@@ -1351,7 +1353,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs)
*/
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
- /*
+ /*
* We may come here right after calling schedule_user()
* or do_notify_resume(), in which case we can be in RCU
* user mode.
diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c
index cda7983e7c18..7f1c136ad850 100644
--- a/arch/mips/kernel/relocate.c
+++ b/arch/mips/kernel/relocate.c
@@ -138,7 +138,7 @@ static int __init reloc_handler(u32 type, u32 *loc_orig, u32 *loc_new,
apply_r_mips_hi16_rel(loc_orig, loc_new, offset);
break;
default:
- pr_err("Unhandled relocation type %d at 0x%pK\n", type,
+ pr_err("Unhandled relocation type %d at 0x%p\n", type,
loc_orig);
return -ENOEXEC;
}
@@ -439,10 +439,10 @@ static void show_kernel_relocation(const char *level)
{
if (__kaslr_offset > 0) {
printk(level);
- pr_cont("Kernel relocated by 0x%pK\n", (void *)__kaslr_offset);
- pr_cont(" .text @ 0x%pK\n", _text);
- pr_cont(" .data @ 0x%pK\n", _sdata);
- pr_cont(" .bss @ 0x%pK\n", __bss_start);
+ pr_cont("Kernel relocated by 0x%p\n", (void *)__kaslr_offset);
+ pr_cont(" .text @ 0x%p\n", _text);
+ pr_cont(" .data @ 0x%p\n", _sdata);
+ pr_cont(" .bss @ 0x%p\n", __bss_start);
}
}
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index cc26d56f3ab6..22d4f9ff3ae2 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -236,6 +236,7 @@ static void __init cps_smp_setup(void)
/* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */
if (!cl && !c)
smp_num_siblings = core_vpes;
+ cpumask_set_cpu(nvpes, &__cpu_primary_thread_mask);
for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
cpu_set_cluster(&cpu_data[nvpes + v], cl);
@@ -280,9 +281,20 @@ static void __init cps_smp_setup(void)
#endif /* CONFIG_MIPS_MT_FPAFF */
}
+unsigned long calibrate_delay_is_known(void)
+{
+ int first_cpu_cluster = 0;
+
+ /* The calibration has to be done on the primary CPU of the cluster */
+ if (mips_cps_first_online_in_cluster(&first_cpu_cluster))
+ return 0;
+
+ return cpu_data[first_cpu_cluster].udelay_val;
+}
+
static void __init cps_prepare_cpus(unsigned int max_cpus)
{
- unsigned int nclusters, ncores, core_vpes, c, cl, cca;
+ unsigned int nclusters, ncores, core_vpes, nvpe = 0, c, cl, cca;
bool cca_unsuitable, cores_limited;
struct cluster_boot_config *cluster_bootcfg;
struct core_boot_config *core_bootcfg;
@@ -355,10 +367,13 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
/* Allocate VPE boot configuration structs */
for (c = 0; c < ncores; c++) {
+ int v;
core_vpes = core_vpe_count(cl, c);
core_bootcfg[c].vpe_config = kcalloc(core_vpes,
sizeof(*core_bootcfg[c].vpe_config),
GFP_KERNEL);
+ for (v = 0; v < core_vpes; v++)
+ cpumask_set_cpu(nvpe++, &mips_cps_cluster_bootcfg[cl].cpumask);
if (!core_bootcfg[c].vpe_config)
goto err_out;
}
@@ -368,6 +383,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
cl = cpu_cluster(&current_cpu_data);
c = cpu_core(&current_cpu_data);
cluster_bootcfg = &mips_cps_cluster_bootcfg[cl];
+ cpu_smt_set_num_threads(core_vpes, core_vpes);
core_bootcfg = &cluster_bootcfg->core_config[c];
bitmap_set(cluster_bootcfg->core_power, cpu_core(&current_cpu_data), 1);
atomic_set(&core_bootcfg->vpe_mask, 1 << cpu_vpe_id(&current_cpu_data));
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 39e193cad2b9..4868e79f3b30 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -56,8 +56,10 @@ EXPORT_SYMBOL(cpu_sibling_map);
cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_core_map);
+#ifndef CONFIG_HOTPLUG_PARALLEL
static DECLARE_COMPLETION(cpu_starting);
static DECLARE_COMPLETION(cpu_running);
+#endif
/*
* A logical cpu mask containing only one VPE per core to
@@ -74,6 +76,8 @@ static cpumask_t cpu_core_setup_map;
cpumask_t cpu_coherent_mask;
+struct cpumask __cpu_primary_thread_mask __read_mostly;
+
unsigned int smp_max_threads __initdata = UINT_MAX;
static int __init early_nosmt(char *s)
@@ -367,6 +371,9 @@ asmlinkage void start_secondary(void)
* to an option instead of something based on .cputype
*/
+#ifdef CONFIG_HOTPLUG_PARALLEL
+ cpuhp_ap_sync_alive();
+#endif
calibrate_delay();
cpu_data[cpu].udelay_val = loops_per_jiffy;
@@ -376,8 +383,10 @@ asmlinkage void start_secondary(void)
cpumask_set_cpu(cpu, &cpu_coherent_mask);
notify_cpu_starting(cpu);
+#ifndef CONFIG_HOTPLUG_PARALLEL
/* Notify boot CPU that we're starting & ready to sync counters */
complete(&cpu_starting);
+#endif
synchronise_count_slave(cpu);
@@ -386,11 +395,13 @@ asmlinkage void start_secondary(void)
calculate_cpu_foreign_map();
+#ifndef CONFIG_HOTPLUG_PARALLEL
/*
* Notify boot CPU that we're up & online and it can safely return
* from __cpu_up
*/
complete(&cpu_running);
+#endif
/*
* irq will be enabled in ->smp_finish(), enabling it too early
@@ -447,6 +458,12 @@ void __init smp_prepare_boot_cpu(void)
set_cpu_online(0, true);
}
+#ifdef CONFIG_HOTPLUG_PARALLEL
+int arch_cpuhp_kick_ap_alive(unsigned int cpu, struct task_struct *tidle)
+{
+ return mp_ops->boot_secondary(cpu, tidle);
+}
+#else
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
int err;
@@ -466,6 +483,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
wait_for_completion(&cpu_running);
return 0;
}
+#endif
#ifdef CONFIG_PROFILING
/* Not really SMP stuff ... */
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index aa70e371bb54..d824ffe9a014 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -406,3 +406,5 @@
465 n32 listxattrat sys_listxattrat
466 n32 removexattrat sys_removexattrat
467 n32 open_tree_attr sys_open_tree_attr
+468 n32 file_getattr sys_file_getattr
+469 n32 file_setattr sys_file_setattr
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 1e8c44c7b614..7a7049c2c307 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -382,3 +382,5 @@
465 n64 listxattrat sys_listxattrat
466 n64 removexattrat sys_removexattrat
467 n64 open_tree_attr sys_open_tree_attr
+468 n64 file_getattr sys_file_getattr
+469 n64 file_setattr sys_file_setattr
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 114a5a1a6230..d330274f0601 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -455,3 +455,5 @@
465 o32 listxattrat sys_listxattrat
466 o32 removexattrat sys_removexattrat
467 o32 open_tree_attr sys_open_tree_attr
+468 o32 file_getattr sys_file_getattr
+469 o32 file_setattr sys_file_setattr
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 737d0d4fdcd3..2b67c44adab9 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -22,6 +22,7 @@
#include <linux/vmalloc.h>
#include <linux/elf.h>
#include <linux/seq_file.h>
+#include <linux/string.h>
#include <linux/syscalls.h>
#include <linux/moduleloader.h>
#include <linux/interrupt.h>
@@ -582,7 +583,7 @@ static int vpe_elfload(struct vpe *v)
struct module mod; /* so we can re-use the relocations code */
memset(&mod, 0, sizeof(struct module));
- strcpy(mod.name, "VPE loader");
+ strscpy(mod.name, "VPE loader");
hdr = (Elf_Ehdr *) v->pbuffer;
len = v->plen;