summaryrefslogtreecommitdiff
path: root/arch/mips/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include')
-rw-r--r--arch/mips/include/asm/Kbuild7
-rw-r--r--arch/mips/include/asm/asmmacro.h3
-rw-r--r--arch/mips/include/asm/bootinfo.h2
-rw-r--r--arch/mips/include/asm/div64.h55
-rw-r--r--arch/mips/include/asm/io.h14
-rw-r--r--arch/mips/include/asm/kvm_host.h238
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h8
-rw-r--r--arch/mips/include/asm/mach-generic/spaces.h12
-rw-r--r--arch/mips/include/asm/mach-loongson64/boot_param.h27
-rw-r--r--arch/mips/include/asm/mach-loongson64/builtin_dtbs.h1
-rw-r--r--arch/mips/include/asm/mach-loongson64/kernel-entry-init.h27
-rw-r--r--arch/mips/include/asm/mach-loongson64/loongson.h27
-rw-r--r--arch/mips/include/asm/mach-ralink/mt7621.h7
-rw-r--r--arch/mips/include/asm/mips-cps.h23
-rw-r--r--arch/mips/include/asm/octeon/cvmx-address.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootinfo.h2
-rw-r--r--arch/mips/include/asm/page.h9
-rw-r--r--arch/mips/include/asm/pci.h1
-rw-r--r--arch/mips/include/asm/processor.h9
-rw-r--r--arch/mips/include/asm/thread_info.h6
-rw-r--r--arch/mips/include/asm/uaccess.h598
-rw-r--r--arch/mips/include/asm/vdso/gettimeofday.h26
22 files changed, 397 insertions, 707 deletions
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 8f6fe69674b7..dee172716581 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -1,9 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
# MIPS headers
-generated-y += syscall_table_32_o32.h
-generated-y += syscall_table_64_n32.h
-generated-y += syscall_table_64_n64.h
-generated-y += syscall_table_64_o32.h
+generated-y += syscall_table_n32.h
+generated-y += syscall_table_n64.h
+generated-y += syscall_table_o32.h
generated-y += unistd_nr_n32.h
generated-y += unistd_nr_n64.h
generated-y += unistd_nr_o32.h
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 86f2323ebe6b..ca83ada7015f 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -44,8 +44,7 @@
.endm
#endif
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \
- defined(CONFIG_CPU_MIPSR6)
+#ifdef CONFIG_CPU_HAS_DIEI
.macro local_irq_enable reg=t0
ei
irq_enable_hazard
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 5be10ece3ef0..4c2e8173e6ec 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -107,7 +107,7 @@ extern void (*free_init_pages_eva)(void *begin, void *end);
extern char arcs_cmdline[COMMAND_LINE_SIZE];
/*
- * Registers a0, a1, a3 and a4 as passed to the kernel entry by firmware
+ * Registers a0, a1, a2 and a3 as passed to the kernel entry by firmware
*/
extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
diff --git a/arch/mips/include/asm/div64.h b/arch/mips/include/asm/div64.h
index dc5ea5736440..ceece76fc971 100644
--- a/arch/mips/include/asm/div64.h
+++ b/arch/mips/include/asm/div64.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2004 Maciej W. Rozycki
+ * Copyright (C) 2000, 2004, 2021 Maciej W. Rozycki
* Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org)
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -9,25 +9,18 @@
#ifndef __ASM_DIV64_H
#define __ASM_DIV64_H
-#include <asm-generic/div64.h>
-
-#if BITS_PER_LONG == 64
+#include <asm/bitsperlong.h>
-#include <linux/types.h>
+#if BITS_PER_LONG == 32
/*
* No traps on overflows for any of these...
*/
-#define __div64_32(n, base) \
-({ \
+#define do_div64_32(res, high, low, base) ({ \
unsigned long __cf, __tmp, __tmp2, __i; \
unsigned long __quot32, __mod32; \
- unsigned long __high, __low; \
- unsigned long long __n; \
\
- __high = *__n >> 32; \
- __low = __n; \
__asm__( \
" .set push \n" \
" .set noat \n" \
@@ -51,18 +44,48 @@
" subu %0, %0, %z6 \n" \
" addiu %2, %2, 1 \n" \
"3: \n" \
- " bnez %4, 0b\n\t" \
- " srl %5, %1, 0x1f\n\t" \
+ " bnez %4, 0b \n" \
+ " srl %5, %1, 0x1f \n" \
" .set pop" \
: "=&r" (__mod32), "=&r" (__tmp), \
"=&r" (__quot32), "=&r" (__cf), \
"=&r" (__i), "=&r" (__tmp2) \
- : "Jr" (base), "0" (__high), "1" (__low)); \
+ : "Jr" (base), "0" (high), "1" (low)); \
\
- (__n) = __quot32; \
+ (res) = __quot32; \
__mod32; \
})
-#endif /* BITS_PER_LONG == 64 */
+#define __div64_32(n, base) ({ \
+ unsigned long __upper, __low, __high, __radix; \
+ unsigned long long __quot; \
+ unsigned long long __div; \
+ unsigned long __mod; \
+ \
+ __div = (*n); \
+ __radix = (base); \
+ \
+ __high = __div >> 32; \
+ __low = __div; \
+ \
+ if (__high < __radix) { \
+ __upper = __high; \
+ __high = 0; \
+ } else { \
+ __upper = __high % __radix; \
+ __high /= __radix; \
+ } \
+ \
+ __mod = do_div64_32(__low, __upper, __low, __radix); \
+ \
+ __quot = __high; \
+ __quot = __quot << 32 | __low; \
+ (*n) = __quot; \
+ __mod; \
+})
+
+#endif /* BITS_PER_LONG == 32 */
+
+#include <asm-generic/div64.h>
#endif /* __ASM_DIV64_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 78537aa23500..2c138450ad3b 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -100,11 +100,23 @@ static inline void set_io_port_base(unsigned long base)
* almost all conceivable cases a device driver should not be using
* this function
*/
-static inline unsigned long virt_to_phys(volatile const void *address)
+static inline unsigned long __virt_to_phys_nodebug(volatile const void *address)
{
return __pa(address);
}
+#ifdef CONFIG_DEBUG_VIRTUAL
+extern phys_addr_t __virt_to_phys(volatile const void *x);
+#else
+#define __virt_to_phys(x) __virt_to_phys_nodebug(x)
+#endif
+
+#define virt_to_phys virt_to_phys
+static inline phys_addr_t virt_to_phys(const volatile void *x)
+{
+ return __virt_to_phys(x);
+}
+
/*
* phys_to_virt - map physical address to virtual
* @address: address to remap
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 3a5612e7304c..603ad562d101 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -88,44 +88,10 @@
#define KVM_HALT_POLL_NS_DEFAULT 500000
-#ifdef CONFIG_KVM_MIPS_VZ
extern unsigned long GUESTID_MASK;
extern unsigned long GUESTID_FIRST_VERSION;
extern unsigned long GUESTID_VERSION_MASK;
-#endif
-
-
-/*
- * Special address that contains the comm page, used for reducing # of traps
- * This needs to be within 32Kb of 0x0 (so the zero register can be used), but
- * preferably not at 0x0 so that most kernel NULL pointer dereferences can be
- * caught.
- */
-#define KVM_GUEST_COMMPAGE_ADDR ((PAGE_SIZE > 0x8000) ? 0 : \
- (0x8000 - PAGE_SIZE))
-#define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu->arch.cop0) & (ST0_EXL | ST0_ERL)) || \
- ((kvm_read_c0_guest_status(vcpu->arch.cop0) & KSU_USER) == 0))
-
-#define KVM_GUEST_KUSEG 0x00000000UL
-#define KVM_GUEST_KSEG0 0x40000000UL
-#define KVM_GUEST_KSEG1 0x40000000UL
-#define KVM_GUEST_KSEG23 0x60000000UL
-#define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) & 0xe0000000)
-#define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
-
-#define KVM_GUEST_CKSEG0ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0)
-#define KVM_GUEST_CKSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1)
-#define KVM_GUEST_CKSEG23ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG23)
-
-/*
- * Map an address to a certain kernel segment
- */
-#define KVM_GUEST_KSEG0ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0)
-#define KVM_GUEST_KSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1)
-#define KVM_GUEST_KSEG23ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG23)
-
-#define KVM_INVALID_PAGE 0xdeadbeef
#define KVM_INVALID_ADDR 0xdeadbeef
/*
@@ -165,7 +131,6 @@ struct kvm_vcpu_stat {
u64 fpe_exits;
u64 msa_disabled_exits;
u64 flush_dcache_exits;
-#ifdef CONFIG_KVM_MIPS_VZ
u64 vz_gpsi_exits;
u64 vz_gsfc_exits;
u64 vz_hc_exits;
@@ -177,7 +142,6 @@ struct kvm_vcpu_stat {
#ifdef CONFIG_CPU_LOONGSON64
u64 vz_cpucfg_exits;
#endif
-#endif
u64 halt_successful_poll;
u64 halt_attempted_poll;
u64 halt_poll_success_ns;
@@ -303,14 +267,6 @@ enum emulation_result {
EMULATE_HYPERCALL, /* HYPCALL instruction */
};
-#define mips3_paddr_to_tlbpfn(x) \
- (((unsigned long)(x) >> MIPS3_PG_SHIFT) & MIPS3_PG_FRAME)
-#define mips3_tlbpfn_to_paddr(x) \
- ((unsigned long)((x) & MIPS3_PG_FRAME) << MIPS3_PG_SHIFT)
-
-#define MIPS3_PG_SHIFT 6
-#define MIPS3_PG_FRAME 0x3fffffc0
-
#if defined(CONFIG_64BIT)
#define VPN2_MASK GENMASK(cpu_vmbits - 1, 13)
#else
@@ -337,7 +293,6 @@ struct kvm_mips_tlb {
#define KVM_MIPS_AUX_FPU 0x1
#define KVM_MIPS_AUX_MSA 0x2
-#define KVM_MIPS_GUEST_TLB_SIZE 64
struct kvm_vcpu_arch {
void *guest_ebase;
int (*vcpu_run)(struct kvm_vcpu *vcpu);
@@ -370,9 +325,6 @@ struct kvm_vcpu_arch {
/* COP0 State */
struct mips_coproc *cop0;
- /* Host KSEG0 address of the EI/DI offset */
- void *kseg0_commpage;
-
/* Resume PC after MMIO completion */
unsigned long io_pc;
/* GPR used as IO source/target */
@@ -398,19 +350,9 @@ struct kvm_vcpu_arch {
/* Bitmask of pending exceptions to be cleared */
unsigned long pending_exceptions_clr;
- /* S/W Based TLB for guest */
- struct kvm_mips_tlb guest_tlb[KVM_MIPS_GUEST_TLB_SIZE];
-
- /* Guest kernel/user [partial] mm */
- struct mm_struct guest_kernel_mm, guest_user_mm;
-
- /* Guest ASID of last user mode execution */
- unsigned int last_user_gasid;
-
/* Cache some mmu pages needed inside spinlock regions */
struct kvm_mmu_memory_cache mmu_page_cache;
-#ifdef CONFIG_KVM_MIPS_VZ
/* vcpu's vzguestid is different on each host cpu in an smp system */
u32 vzguestid[NR_CPUS];
@@ -421,7 +363,6 @@ struct kvm_vcpu_arch {
/* emulated guest MAAR registers */
unsigned long maar[6];
-#endif
/* Last CPU the VCPU state was loaded on */
int last_sched_cpu;
@@ -651,20 +592,6 @@ static inline void kvm_change_##name1(struct mips_coproc *cop0, \
__BUILD_KVM_ATOMIC_SAVED(name, type, _reg, sel) \
__BUILD_KVM_SET_WRAP(c0_guest_##name, sw_gc0_##name, type)
-#ifndef CONFIG_KVM_MIPS_VZ
-
-/*
- * T&E (trap & emulate software based virtualisation)
- * We generate the common accessors operating exclusively on the saved context
- * in RAM.
- */
-
-#define __BUILD_KVM_RW_HW __BUILD_KVM_RW_SW
-#define __BUILD_KVM_SET_HW __BUILD_KVM_SET_SW
-#define __BUILD_KVM_ATOMIC_HW __BUILD_KVM_ATOMIC_SW
-
-#else
-
/*
* VZ (hardware assisted virtualisation)
* These macros use the active guest state in VZ mode (hardware registers),
@@ -697,8 +624,6 @@ static inline void kvm_change_##name1(struct mips_coproc *cop0, \
*/
#define __BUILD_KVM_ATOMIC_HW __BUILD_KVM_SET_HW
-#endif
-
/*
* Define accessors for CP0 registers that are accessible to the guest. These
* are primarily used by common emulation code, which may need to access the
@@ -874,42 +799,9 @@ void kvm_drop_fpu(struct kvm_vcpu *vcpu);
void kvm_lose_fpu(struct kvm_vcpu *vcpu);
/* TLB handling */
-u32 kvm_get_kernel_asid(struct kvm_vcpu *vcpu);
-
-u32 kvm_get_user_asid(struct kvm_vcpu *vcpu);
-
-u32 kvm_get_commpage_asid (struct kvm_vcpu *vcpu);
-
-#ifdef CONFIG_KVM_MIPS_VZ
int kvm_mips_handle_vz_root_tlb_fault(unsigned long badvaddr,
struct kvm_vcpu *vcpu, bool write_fault);
-#endif
-extern int kvm_mips_handle_kseg0_tlb_fault(unsigned long badbaddr,
- struct kvm_vcpu *vcpu,
- bool write_fault);
-
-extern int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
- struct kvm_vcpu *vcpu);
-extern int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
- struct kvm_mips_tlb *tlb,
- unsigned long gva,
- bool write_fault);
-
-extern enum emulation_result kvm_mips_handle_tlbmiss(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu,
- bool write_fault);
-
-extern void kvm_mips_dump_host_tlbs(void);
-extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
-extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi,
- bool user, bool kernel);
-
-extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
- unsigned long entryhi);
-
-#ifdef CONFIG_KVM_MIPS_VZ
int kvm_vz_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
int kvm_vz_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long gva,
unsigned long *gpa);
@@ -923,48 +815,13 @@ void kvm_vz_load_guesttlb(const struct kvm_mips_tlb *buf, unsigned int index,
void kvm_loongson_clear_guest_vtlb(void);
void kvm_loongson_clear_guest_ftlb(void);
#endif
-#endif
-
-void kvm_mips_suspend_mm(int cpu);
-void kvm_mips_resume_mm(int cpu);
/* MMU handling */
-/**
- * enum kvm_mips_flush - Types of MMU flushes.
- * @KMF_USER: Flush guest user virtual memory mappings.
- * Guest USeg only.
- * @KMF_KERN: Flush guest kernel virtual memory mappings.
- * Guest USeg and KSeg2/3.
- * @KMF_GPA: Flush guest physical memory mappings.
- * Also includes KSeg0 if KMF_KERN is set.
- */
-enum kvm_mips_flush {
- KMF_USER = 0x0,
- KMF_KERN = 0x1,
- KMF_GPA = 0x2,
-};
-void kvm_mips_flush_gva_pt(pgd_t *pgd, enum kvm_mips_flush flags);
bool kvm_mips_flush_gpa_pt(struct kvm *kvm, gfn_t start_gfn, gfn_t end_gfn);
int kvm_mips_mkclean_gpa_pt(struct kvm *kvm, gfn_t start_gfn, gfn_t end_gfn);
pgd_t *kvm_pgd_alloc(void);
void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
-void kvm_trap_emul_invalidate_gva(struct kvm_vcpu *vcpu, unsigned long addr,
- bool user);
-void kvm_trap_emul_gva_lockless_begin(struct kvm_vcpu *vcpu);
-void kvm_trap_emul_gva_lockless_end(struct kvm_vcpu *vcpu);
-
-enum kvm_mips_fault_result {
- KVM_MIPS_MAPPED = 0,
- KVM_MIPS_GVA,
- KVM_MIPS_GPA,
- KVM_MIPS_TLB,
- KVM_MIPS_TLBINV,
- KVM_MIPS_TLBMOD,
-};
-enum kvm_mips_fault_result kvm_trap_emul_gva_fault(struct kvm_vcpu *vcpu,
- unsigned long gva,
- bool write);
#define KVM_ARCH_WANT_MMU_NOTIFIER
int kvm_unmap_hva_range(struct kvm *kvm,
@@ -974,7 +831,6 @@ int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
/* Emulation */
-int kvm_get_inst(u32 *opc, struct kvm_vcpu *vcpu, u32 *out);
enum emulation_result update_pc(struct kvm_vcpu *vcpu, u32 cause);
int kvm_get_badinstr(u32 *opc, struct kvm_vcpu *vcpu, u32 *out);
int kvm_get_badinstrp(u32 *opc, struct kvm_vcpu *vcpu, u32 *out);
@@ -1006,68 +862,6 @@ static inline bool kvm_is_ifetch_fault(struct kvm_vcpu_arch *vcpu)
return false;
}
-extern enum emulation_result kvm_mips_emulate_inst(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-long kvm_mips_guest_exception_base(struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_syscall(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_tlbmiss_ld(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_tlbinv_ld(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_tlbmiss_st(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_tlbinv_st(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_tlbmod(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_fpu_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_handle_ri(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_ri_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_bp_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_trap_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_msafpe_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_fpe_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
-extern enum emulation_result kvm_mips_emulate_msadis_exc(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-
extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu);
u32 kvm_mips_read_count(struct kvm_vcpu *vcpu);
@@ -1087,26 +881,9 @@ ktime_t kvm_mips_freeze_hrtimer(struct kvm_vcpu *vcpu, u32 *count);
int kvm_mips_restore_hrtimer(struct kvm_vcpu *vcpu, ktime_t before,
u32 count, int min_drift);
-#ifdef CONFIG_KVM_MIPS_VZ
void kvm_vz_acquire_htimer(struct kvm_vcpu *vcpu);
void kvm_vz_lose_htimer(struct kvm_vcpu *vcpu);
-#else
-static inline void kvm_vz_acquire_htimer(struct kvm_vcpu *vcpu) {}
-static inline void kvm_vz_lose_htimer(struct kvm_vcpu *vcpu) {}
-#endif
-
-enum emulation_result kvm_mips_check_privilege(u32 cause,
- u32 *opc,
- struct kvm_vcpu *vcpu);
-enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst,
- u32 *opc,
- u32 cause,
- struct kvm_vcpu *vcpu);
-enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
- u32 *opc,
- u32 cause,
- struct kvm_vcpu *vcpu);
enum emulation_result kvm_mips_emulate_store(union mips_instruction inst,
u32 cause,
struct kvm_vcpu *vcpu);
@@ -1117,27 +894,12 @@ enum emulation_result kvm_mips_emulate_load(union mips_instruction inst,
/* COP0 */
enum emulation_result kvm_mips_emul_wait(struct kvm_vcpu *vcpu);
-unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu);
-unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu);
-unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu);
-unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu);
-
/* Hypercalls (hypcall.c) */
enum emulation_result kvm_mips_emul_hypcall(struct kvm_vcpu *vcpu,
union mips_instruction inst);
int kvm_mips_handle_hypcall(struct kvm_vcpu *vcpu);
-/* Dynamic binary translation */
-extern int kvm_mips_trans_cache_index(union mips_instruction inst,
- u32 *opc, struct kvm_vcpu *vcpu);
-extern int kvm_mips_trans_cache_va(union mips_instruction inst, u32 *opc,
- struct kvm_vcpu *vcpu);
-extern int kvm_mips_trans_mfc0(union mips_instruction inst, u32 *opc,
- struct kvm_vcpu *vcpu);
-extern int kvm_mips_trans_mtc0(union mips_instruction inst, u32 *opc,
- struct kvm_vcpu *vcpu);
-
/* Misc */
extern void kvm_mips_dump_stats(struct kvm_vcpu *vcpu);
extern unsigned long kvm_mips_get_ramsize(struct kvm *kvm);
diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
index c38b38ce5a3d..b071a7353ee1 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
@@ -157,4 +157,12 @@ octeon_main_processor:
.macro smp_slave_setup
.endm
+#define USE_KEXEC_SMP_WAIT_FINAL
+ .macro kexec_smp_wait_final
+ .set push
+ .set noreorder
+ synci 0($0)
+ .set pop
+ .endm
+
#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
index c3ac06a6acd2..b247575c5e69 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -30,11 +30,7 @@
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_32BIT
-#ifdef CONFIG_KVM_GUEST
-#define CAC_BASE _AC(0x40000000, UL)
-#else
#define CAC_BASE _AC(0x80000000, UL)
-#endif
#ifndef IO_BASE
#define IO_BASE _AC(0xa0000000, UL)
#endif
@@ -43,12 +39,8 @@
#endif
#ifndef MAP_BASE
-#ifdef CONFIG_KVM_GUEST
-#define MAP_BASE _AC(0x60000000, UL)
-#else
#define MAP_BASE _AC(0xc0000000, UL)
#endif
-#endif
/*
* Memory above this physical address will be considered highmem.
@@ -100,11 +92,7 @@
#endif
#ifndef FIXADDR_TOP
-#ifdef CONFIG_KVM_GUEST
-#define FIXADDR_TOP ((unsigned long)(long)(int)0x7ffe0000)
-#else
#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000)
#endif
-#endif
#endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index 4592841b6b0c..035b1a69e2d0 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -198,33 +198,6 @@ enum loongson_bridge_type {
VIRTUAL = 3
};
-struct loongson_system_configuration {
- u32 nr_cpus;
- u32 nr_nodes;
- int cores_per_node;
- int cores_per_package;
- u16 boot_cpu_id;
- u16 reserved_cpus_mask;
- enum loongson_cpu_type cputype;
- enum loongson_bridge_type bridgetype;
- u64 ht_control_base;
- u64 pci_mem_start_addr;
- u64 pci_mem_end_addr;
- u64 pci_io_base;
- u64 restart_addr;
- u64 poweroff_addr;
- u64 suspend_addr;
- u64 vgabios_addr;
- u32 dma_mask_bits;
- char ecname[32];
- u32 nr_uarts;
- struct uart_device uarts[MAX_UARTS];
- u32 nr_sensors;
- struct sensor_device sensors[MAX_SENSORS];
- u64 workarounds;
- void (*early_config)(void);
-};
-
extern struct efi_memory_map_loongson *loongson_memmap;
extern struct loongson_system_configuration loongson_sysconf;
diff --git a/arch/mips/include/asm/mach-loongson64/builtin_dtbs.h b/arch/mips/include/asm/mach-loongson64/builtin_dtbs.h
index 839410cda621..8be710557bdb 100644
--- a/arch/mips/include/asm/mach-loongson64/builtin_dtbs.h
+++ b/arch/mips/include/asm/mach-loongson64/builtin_dtbs.h
@@ -8,6 +8,7 @@
#ifndef __ASM_MACH_LOONGSON64_BUILTIN_DTBS_H_
#define __ASM_MACH_LOONGSON64_BUILTIN_DTBS_H_
+extern u32 __dtb_loongson64_2core_2k1000_begin[];
extern u32 __dtb_loongson64c_4core_ls7a_begin[];
extern u32 __dtb_loongson64c_4core_rs780e_begin[];
extern u32 __dtb_loongson64c_8core_rs780e_begin[];
diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
index e4d77f4f0fe3..13373c5144f8 100644
--- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
+++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
@@ -75,4 +75,31 @@
.set pop
.endm
+#define USE_KEXEC_SMP_WAIT_FINAL
+ .macro kexec_smp_wait_final
+ /* s0:prid s1:initfn */
+ /* a0:base t1:cpuid t2:node t9:count */
+ mfc0 t1, CP0_EBASE
+ andi t1, MIPS_EBASE_CPUNUM
+ dins a0, t1, 8, 2 /* insert core id*/
+ dext t2, t1, 2, 2
+ dins a0, t2, 44, 2 /* insert node id */
+ mfc0 s0, CP0_PRID
+ andi s0, s0, (PRID_IMP_MASK | PRID_REV_MASK)
+ beq s0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1), 1f
+ beq s0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2), 1f
+ b 2f /* Loongson-3A1000/3A2000/3A3000/3A4000 */
+1: dins a0, t2, 14, 2 /* Loongson-3B1000/3B1500 need bit 15~14 */
+2: li t9, 0x100 /* wait for init loop */
+3: addiu t9, -1 /* limit mailbox access */
+ bnez t9, 3b
+ lw s1, 0x20(a0) /* check PC as an indicator */
+ beqz s1, 2b
+ ld s1, 0x20(a0) /* get PC via mailbox reg0 */
+ ld sp, 0x28(a0) /* get SP via mailbox reg1 */
+ ld gp, 0x30(a0) /* get GP via mailbox reg2 */
+ ld a1, 0x38(a0)
+ jr s1 /* jump to initial PC */
+ .endm
+
#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
index ac1c20e172a2..f7c3ab6d724e 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h
@@ -12,6 +12,30 @@
#include <linux/irq.h>
#include <boot_param.h>
+enum loongson_fw_interface {
+ LOONGSON_LEFI,
+ LOONGSON_DTB,
+};
+
+/* machine-specific boot configuration */
+struct loongson_system_configuration {
+ enum loongson_fw_interface fw_interface;
+ u32 nr_cpus;
+ u32 nr_nodes;
+ int cores_per_node;
+ int cores_per_package;
+ u16 boot_cpu_id;
+ u16 reserved_cpus_mask;
+ enum loongson_cpu_type cputype;
+ enum loongson_bridge_type bridgetype;
+ u64 restart_addr;
+ u64 poweroff_addr;
+ u64 suspend_addr;
+ u64 vgabios_addr;
+ u32 dma_mask_bits;
+ u64 workarounds;
+ void (*early_config)(void);
+};
/* machine-specific reboot/halt operation */
extern void mach_prepare_reboot(void);
@@ -23,7 +47,8 @@ extern u32 memsize, highmemsize;
extern const struct plat_smp_ops loongson3_smp_ops;
/* loongson-specific command line, env and memory initialization */
-extern void __init prom_init_env(void);
+extern void __init prom_dtb_init_env(void);
+extern void __init prom_lefi_init_env(void);
extern void __init szmem(unsigned int node);
extern void *loongson_fdt_blob;
diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
index e1af1ba50bd8..6bbf082dd149 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
@@ -24,9 +24,10 @@
#define CHIP_REV_VER_SHIFT 8
#define CHIP_REV_ECO_MASK 0xf
-#define MT7621_DRAM_BASE 0x0
-#define MT7621_DDR2_SIZE_MIN 32
-#define MT7621_DDR2_SIZE_MAX 256
+#define MT7621_LOWMEM_BASE 0x0
+#define MT7621_LOWMEM_MAX_SIZE 0x1C000000
+#define MT7621_HIGHMEM_BASE 0x20000000
+#define MT7621_HIGHMEM_SIZE 0x4000000
#define MT7621_CHIP_NAME0 0x3637544D
#define MT7621_CHIP_NAME1 0x20203132
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index fd43d876892e..35fb8ee6dd33 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -10,6 +10,8 @@
#include <linux/io.h>
#include <linux/types.h>
+#include <asm/mips-boards/launch.h>
+
extern unsigned long __cps_access_bad_size(void)
__compiletime_error("Bad size for CPS accessor");
@@ -165,11 +167,30 @@ static inline uint64_t mips_cps_cluster_config(unsigned int cluster)
*/
static inline unsigned int mips_cps_numcores(unsigned int cluster)
{
+ unsigned int ncores;
+
if (!mips_cm_present())
return 0;
/* Add one before masking to handle 0xff indicating no cores */
- return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
+ ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
+
+ if (IS_ENABLED(CONFIG_SOC_MT7621)) {
+ struct cpulaunch *launch;
+
+ /*
+ * Ralink MT7621S SoC is single core, but the GCR_CONFIG method
+ * always reports 2 cores. Check the second core's LAUNCH_FREADY
+ * flag to detect if the second core is missing. This method
+ * only works before the core has been started.
+ */
+ launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
+ launch += 2; /* MT7621 has 2 VPEs per core */
+ if (!(launch->flags & LAUNCH_FREADY))
+ ncores = 1;
+ }
+
+ return ncores;
}
/**
diff --git a/arch/mips/include/asm/octeon/cvmx-address.h b/arch/mips/include/asm/octeon/cvmx-address.h
index e4444f8c4a61..5df5c90f6a5d 100644
--- a/arch/mips/include/asm/octeon/cvmx-address.h
+++ b/arch/mips/include/asm/octeon/cvmx-address.h
@@ -152,7 +152,7 @@ typedef union {
/* physical mem address */
struct {
- /* techically, <47:40> are dont-cares */
+ /* technically, <47:40> are dont-cares */
uint64_t zeroes:24;
/* the hardware ignores <39:36> in Octeon I */
uint64_t unaddr:4;
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
index c114a7ba0bad..0e6bf220db61 100644
--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
@@ -298,6 +298,7 @@ enum cvmx_board_types_enum {
CVMX_BOARD_TYPE_UBNT_E200 = 20003,
CVMX_BOARD_TYPE_UBNT_E220 = 20005,
CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
+ CVMX_BOARD_TYPE_UBNT_E300 = 20300,
CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
@@ -401,6 +402,7 @@ static inline const char *cvmx_board_type_to_string(enum
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E300)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
}
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 65acab9c41f9..195ff4e9771f 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -210,9 +210,16 @@ static inline unsigned long ___pa(unsigned long x)
* also affect MIPS so we keep this one until GCC 3.x has been retired
* before we can apply https://patchwork.linux-mips.org/patch/1541/
*/
+#define __pa_symbol_nodebug(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
+
+#ifdef CONFIG_DEBUG_VIRTUAL
+extern phys_addr_t __phys_addr_symbol(unsigned long x);
+#else
+#define __phys_addr_symbol(x) __pa_symbol_nodebug(x)
+#endif
#ifndef __pa_symbol
-#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
+#define __pa_symbol(x) __phys_addr_symbol((unsigned long)(x))
#endif
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 6f48649201c5..9ffc8192adae 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -38,7 +38,6 @@ struct pci_controller {
struct resource *io_resource;
unsigned long io_offset;
unsigned long io_map_base;
- struct resource *busn_resource;
#ifndef CONFIG_PCI_DOMAINS_GENERIC
unsigned int index;
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 7834e7c0c78a..0c3550c82b72 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -32,16 +32,11 @@ extern unsigned int vced_count, vcei_count;
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#ifdef CONFIG_32BIT
-#ifdef CONFIG_KVM_GUEST
-/* User space process size is limited to 1GB in KVM Guest Mode */
-#define TASK_SIZE 0x3fff8000UL
-#else
/*
* User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
#define TASK_SIZE 0x80000000UL
-#endif
#define STACK_TOP_MAX TASK_SIZE
@@ -226,10 +221,6 @@ struct nlm_cop2_state {
#define COP2_INIT
#endif
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
#ifdef CONFIG_CPU_HAS_MSA
# define ARCH_MIN_TASKALIGN 16
# define FPU_ALIGN __aligned(16)
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index e2c352da3877..0b17aaa9e012 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -28,11 +28,6 @@ struct thread_info {
unsigned long tp_value; /* thread pointer */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable, <0 => BUG */
- mm_segment_t addr_limit; /*
- * thread address space limit:
- * 0x7fffffff for user-thead
- * 0xffffffff for kernel-thread
- */
struct pt_regs *regs;
long syscall; /* syscall number */
};
@@ -46,7 +41,6 @@ struct thread_info {
.flags = _TIF_FIXADE, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/*
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 61fc01f177a6..783fecce65c8 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -16,20 +16,9 @@
#include <asm/asm-eva.h>
#include <asm/extable.h>
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
#ifdef CONFIG_32BIT
-#ifdef CONFIG_KVM_GUEST
-#define __UA_LIMIT 0x40000000UL
-#else
#define __UA_LIMIT 0x80000000UL
-#endif
#define __UA_ADDR ".word"
#define __UA_LA "la"
@@ -54,43 +43,6 @@ extern u64 __ua_limit;
#endif /* CONFIG_64BIT */
/*
- * USER_DS is a bitmask that has the bits set that may not be set in a valid
- * userspace address. Note that we limit 32-bit userspace to 0x7fff8000 but
- * the arithmetic we're doing only works if the limit is a power of two, so
- * we use 0x80000000 here on 32-bit kernels. If a process passes an invalid
- * address in this range it's the process's problem, not ours :-)
- */
-
-#ifdef CONFIG_KVM_GUEST
-#define KERNEL_DS ((mm_segment_t) { 0x80000000UL })
-#define USER_DS ((mm_segment_t) { 0xC0000000UL })
-#else
-#define KERNEL_DS ((mm_segment_t) { 0UL })
-#define USER_DS ((mm_segment_t) { __UA_LIMIT })
-#endif
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(x) (current_thread_info()->addr_limit = (x))
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-/*
- * eva_kernel_access() - determine whether kernel memory access on an EVA system
- *
- * Determines whether memory accesses should be performed to kernel memory
- * on a system using Extended Virtual Addressing (EVA).
- *
- * Return: true if a kernel memory access on an EVA system, else false.
- */
-static inline bool eva_kernel_access(void)
-{
- if (!IS_ENABLED(CONFIG_EVA))
- return false;
-
- return uaccess_kernel();
-}
-
-/*
* Is a address valid? This does a straightforward calculation rather
* than tests.
*
@@ -127,7 +79,9 @@ static inline bool eva_kernel_access(void)
static inline int __access_ok(const void __user *p, unsigned long size)
{
unsigned long addr = (unsigned long)p;
- return (get_fs().seg & (addr | (addr + size) | __ua_size(size))) == 0;
+ unsigned long end = addr + size - !!size;
+
+ return (__UA_LIMIT & (addr | end | __ua_size(size))) == 0;
}
#define access_ok(addr, size) \
@@ -150,8 +104,13 @@ static inline int __access_ok(const void __user *p, unsigned long size)
*
* Returns zero on success, or -EFAULT on error.
*/
-#define put_user(x,ptr) \
- __put_user_check((x), (ptr), sizeof(*(ptr)))
+#define put_user(x, ptr) \
+({ \
+ __typeof__(*(ptr)) __user *__p = (ptr); \
+ \
+ might_fault(); \
+ access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT; \
+})
/*
* get_user: - Get a simple variable from user space.
@@ -171,8 +130,14 @@ static inline int __access_ok(const void __user *p, unsigned long size)
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define get_user(x,ptr) \
- __get_user_check((x), (ptr), sizeof(*(ptr)))
+#define get_user(x, ptr) \
+({ \
+ const __typeof__(*(ptr)) __user *__p = (ptr); \
+ \
+ might_fault(); \
+ access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) : \
+ ((x) = 0, -EFAULT); \
+})
/*
* __put_user: - Write a simple value into user space, with less checking.
@@ -194,8 +159,32 @@ static inline int __access_ok(const void __user *p, unsigned long size)
*
* Returns zero on success, or -EFAULT on error.
*/
-#define __put_user(x,ptr) \
- __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+({ \
+ __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \
+ __typeof__(*(ptr)) __pu_val = (x); \
+ int __pu_err = 0; \
+ \
+ __chk_user_ptr(__pu_ptr); \
+ switch (sizeof(*__pu_ptr)) { \
+ case 1: \
+ __put_data_asm(user_sb, __pu_ptr); \
+ break; \
+ case 2: \
+ __put_data_asm(user_sh, __pu_ptr); \
+ break; \
+ case 4: \
+ __put_data_asm(user_sw, __pu_ptr); \
+ break; \
+ case 8: \
+ __PUT_DW(user_sd, __pu_ptr); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
+ \
+ __pu_err; \
+})
/*
* __get_user: - Get a simple variable from user space, with less checking.
@@ -218,49 +207,35 @@ static inline int __access_ok(const void __user *p, unsigned long size)
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define __get_user(x,ptr) \
- __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __get_user(x, ptr) \
+({ \
+ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
+ int __gu_err = 0; \
+ \
+ __chk_user_ptr(__gu_ptr); \
+ switch (sizeof(*__gu_ptr)) { \
+ case 1: \
+ __get_data_asm((x), user_lb, __gu_ptr); \
+ break; \
+ case 2: \
+ __get_data_asm((x), user_lh, __gu_ptr); \
+ break; \
+ case 4: \
+ __get_data_asm((x), user_lw, __gu_ptr); \
+ break; \
+ case 8: \
+ __GET_DW((x), user_ld, __gu_ptr); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
+ \
+ __gu_err; \
+})
struct __large_struct { unsigned long buf[100]; };
#define __m(x) (*(struct __large_struct __user *)(x))
-/*
- * Yuck. We need two variants, one for 64bit operation and one
- * for 32 bit mode and old iron.
- */
-#ifndef CONFIG_EVA
-#define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr)
-#else
-/*
- * Kernel specific functions for EVA. We need to use normal load instructions
- * to read data from kernel when operating in EVA mode. We use these macros to
- * avoid redefining __get_user_asm for EVA.
- */
-#undef _loadd
-#undef _loadw
-#undef _loadh
-#undef _loadb
-#ifdef CONFIG_32BIT
-#define _loadd _loadw
-#else
-#define _loadd(reg, addr) "ld " reg ", " addr
-#endif
-#define _loadw(reg, addr) "lw " reg ", " addr
-#define _loadh(reg, addr) "lh " reg ", " addr
-#define _loadb(reg, addr) "lb " reg ", " addr
-
-#define __get_kernel_common(val, size, ptr) \
-do { \
- switch (size) { \
- case 1: __get_data_asm(val, _loadb, ptr); break; \
- case 2: __get_data_asm(val, _loadh, ptr); break; \
- case 4: __get_data_asm(val, _loadw, ptr); break; \
- case 8: __GET_DW(val, _loadd, ptr); break; \
- default: __get_user_unknown(); break; \
- } \
-} while (0)
-#endif
-
#ifdef CONFIG_32BIT
#define __GET_DW(val, insn, ptr) __get_data_asm_ll32(val, insn, ptr)
#endif
@@ -268,49 +243,6 @@ do { \
#define __GET_DW(val, insn, ptr) __get_data_asm(val, insn, ptr)
#endif
-extern void __get_user_unknown(void);
-
-#define __get_user_common(val, size, ptr) \
-do { \
- switch (size) { \
- case 1: __get_data_asm(val, user_lb, ptr); break; \
- case 2: __get_data_asm(val, user_lh, ptr); break; \
- case 4: __get_data_asm(val, user_lw, ptr); break; \
- case 8: __GET_DW(val, user_ld, ptr); break; \
- default: __get_user_unknown(); break; \
- } \
-} while (0)
-
-#define __get_user_nocheck(x, ptr, size) \
-({ \
- int __gu_err; \
- \
- if (eva_kernel_access()) { \
- __get_kernel_common((x), size, ptr); \
- } else { \
- __chk_user_ptr(ptr); \
- __get_user_common((x), size, ptr); \
- } \
- __gu_err; \
-})
-
-#define __get_user_check(x, ptr, size) \
-({ \
- int __gu_err = -EFAULT; \
- const __typeof__(*(ptr)) __user * __gu_ptr = (ptr); \
- \
- might_fault(); \
- if (likely(access_ok( __gu_ptr, size))) { \
- if (eva_kernel_access()) \
- __get_kernel_common((x), size, __gu_ptr); \
- else \
- __get_user_common((x), size, __gu_ptr); \
- } else \
- (x) = 0; \
- \
- __gu_err; \
-})
-
#define __get_data_asm(val, insn, addr) \
{ \
long __gu_tmp; \
@@ -364,39 +296,36 @@ do { \
(val) = __gu_tmp.t; \
}
-#ifndef CONFIG_EVA
-#define __put_kernel_common(ptr, size) __put_user_common(ptr, size)
-#else
-/*
- * Kernel specific functions for EVA. We need to use normal load instructions
- * to read data from kernel when operating in EVA mode. We use these macros to
- * avoid redefining __get_data_asm for EVA.
- */
-#undef _stored
-#undef _storew
-#undef _storeh
-#undef _storeb
-#ifdef CONFIG_32BIT
-#define _stored _storew
-#else
-#define _stored(reg, addr) "ld " reg ", " addr
-#endif
-
-#define _storew(reg, addr) "sw " reg ", " addr
-#define _storeh(reg, addr) "sh " reg ", " addr
-#define _storeb(reg, addr) "sb " reg ", " addr
+#define HAVE_GET_KERNEL_NOFAULT
-#define __put_kernel_common(ptr, size) \
+#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
- switch (size) { \
- case 1: __put_data_asm(_storeb, ptr); break; \
- case 2: __put_data_asm(_storeh, ptr); break; \
- case 4: __put_data_asm(_storew, ptr); break; \
- case 8: __PUT_DW(_stored, ptr); break; \
- default: __put_user_unknown(); break; \
+ int __gu_err; \
+ \
+ switch (sizeof(type)) { \
+ case 1: \
+ __get_data_asm(*(type *)(dst), kernel_lb, \
+ (__force type *)(src)); \
+ break; \
+ case 2: \
+ __get_data_asm(*(type *)(dst), kernel_lh, \
+ (__force type *)(src)); \
+ break; \
+ case 4: \
+ __get_data_asm(*(type *)(dst), kernel_lw, \
+ (__force type *)(src)); \
+ break; \
+ case 8: \
+ __GET_DW(*(type *)(dst), kernel_ld, \
+ (__force type *)(src)); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ break; \
} \
-} while(0)
-#endif
+ if (unlikely(__gu_err)) \
+ goto err_label; \
+} while (0)
/*
* Yuck. We need two variants, one for 64bit operation and one
@@ -409,49 +338,6 @@ do { \
#define __PUT_DW(insn, ptr) __put_data_asm(insn, ptr)
#endif
-#define __put_user_common(ptr, size) \
-do { \
- switch (size) { \
- case 1: __put_data_asm(user_sb, ptr); break; \
- case 2: __put_data_asm(user_sh, ptr); break; \
- case 4: __put_data_asm(user_sw, ptr); break; \
- case 8: __PUT_DW(user_sd, ptr); break; \
- default: __put_user_unknown(); break; \
- } \
-} while (0)
-
-#define __put_user_nocheck(x, ptr, size) \
-({ \
- __typeof__(*(ptr)) __pu_val; \
- int __pu_err = 0; \
- \
- __pu_val = (x); \
- if (eva_kernel_access()) { \
- __put_kernel_common(ptr, size); \
- } else { \
- __chk_user_ptr(ptr); \
- __put_user_common(ptr, size); \
- } \
- __pu_err; \
-})
-
-#define __put_user_check(x, ptr, size) \
-({ \
- __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- __typeof__(*(ptr)) __pu_val = (x); \
- int __pu_err = -EFAULT; \
- \
- might_fault(); \
- if (likely(access_ok( __pu_addr, size))) { \
- if (eva_kernel_access()) \
- __put_kernel_common(__pu_addr, size); \
- else \
- __put_user_common(__pu_addr, size); \
- } \
- \
- __pu_err; \
-})
-
#define __put_data_asm(insn, ptr) \
{ \
__asm__ __volatile__( \
@@ -490,7 +376,33 @@ do { \
"i" (-EFAULT)); \
}
-extern void __put_user_unknown(void);
+#define __put_kernel_nofault(dst, src, type, err_label) \
+do { \
+ type __pu_val; \
+ int __pu_err = 0; \
+ \
+ __pu_val = *(__force type *)(src); \
+ switch (sizeof(type)) { \
+ case 1: \
+ __put_data_asm(kernel_sb, (type *)(dst)); \
+ break; \
+ case 2: \
+ __put_data_asm(kernel_sh, (type *)(dst)); \
+ break; \
+ case 4: \
+ __put_data_asm(kernel_sw, (type *)(dst)) \
+ break; \
+ case 8: \
+ __PUT_DW(kernel_sd, (type *)(dst)); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ break; \
+ } \
+ if (unlikely(__pu_err)) \
+ goto err_label; \
+} while (0)
+
/*
* We're generating jump to subroutines which will be outside the range of
@@ -514,124 +426,85 @@ extern void __put_user_unknown(void);
#define DADDI_SCRATCH "$0"
#endif
-extern size_t __copy_user(void *__to, const void *__from, size_t __n);
-
-#define __invoke_copy_from(func, to, from, n) \
-({ \
- register void *__cu_to_r __asm__("$4"); \
- register const void __user *__cu_from_r __asm__("$5"); \
- register long __cu_len_r __asm__("$6"); \
- \
- __cu_to_r = (to); \
- __cu_from_r = (from); \
- __cu_len_r = (n); \
- __asm__ __volatile__( \
- ".set\tnoreorder\n\t" \
- __MODULE_JAL(func) \
- ".set\tnoat\n\t" \
- __UA_ADDU "\t$1, %1, %2\n\t" \
- ".set\tat\n\t" \
- ".set\treorder" \
- : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
- : \
- : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \
- DADDI_SCRATCH, "memory"); \
- __cu_len_r; \
-})
-
-#define __invoke_copy_to(func, to, from, n) \
-({ \
- register void __user *__cu_to_r __asm__("$4"); \
- register const void *__cu_from_r __asm__("$5"); \
- register long __cu_len_r __asm__("$6"); \
- \
- __cu_to_r = (to); \
- __cu_from_r = (from); \
- __cu_len_r = (n); \
- __asm__ __volatile__( \
- __MODULE_JAL(func) \
- : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
- : \
- : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \
- DADDI_SCRATCH, "memory"); \
- __cu_len_r; \
-})
-
-#define __invoke_copy_from_kernel(to, from, n) \
- __invoke_copy_from(__copy_user, to, from, n)
-
-#define __invoke_copy_to_kernel(to, from, n) \
- __invoke_copy_to(__copy_user, to, from, n)
-
-#define ___invoke_copy_in_kernel(to, from, n) \
- __invoke_copy_from(__copy_user, to, from, n)
-
-#ifndef CONFIG_EVA
-#define __invoke_copy_from_user(to, from, n) \
- __invoke_copy_from(__copy_user, to, from, n)
-
-#define __invoke_copy_to_user(to, from, n) \
- __invoke_copy_to(__copy_user, to, from, n)
-
-#define ___invoke_copy_in_user(to, from, n) \
- __invoke_copy_from(__copy_user, to, from, n)
-
-#else
-
-/* EVA specific functions */
-
-extern size_t __copy_from_user_eva(void *__to, const void *__from,
- size_t __n);
-extern size_t __copy_to_user_eva(void *__to, const void *__from,
- size_t __n);
-extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
-
-/*
- * Source or destination address is in userland. We need to go through
- * the TLB
- */
-#define __invoke_copy_from_user(to, from, n) \
- __invoke_copy_from(__copy_from_user_eva, to, from, n)
-
-#define __invoke_copy_to_user(to, from, n) \
- __invoke_copy_to(__copy_to_user_eva, to, from, n)
-
-#define ___invoke_copy_in_user(to, from, n) \
- __invoke_copy_from(__copy_in_user_eva, to, from, n)
-
-#endif /* CONFIG_EVA */
+extern size_t __raw_copy_from_user(void *__to, const void *__from, size_t __n);
+extern size_t __raw_copy_to_user(void *__to, const void *__from, size_t __n);
+extern size_t __raw_copy_in_user(void *__to, const void *__from, size_t __n);
static inline unsigned long
-raw_copy_to_user(void __user *to, const void *from, unsigned long n)
+raw_copy_from_user(void *to, const void __user *from, unsigned long n)
{
- if (eva_kernel_access())
- return __invoke_copy_to_kernel(to, from, n);
- else
- return __invoke_copy_to_user(to, from, n);
+ register void *__cu_to_r __asm__("$4");
+ register const void __user *__cu_from_r __asm__("$5");
+ register long __cu_len_r __asm__("$6");
+
+ __cu_to_r = to;
+ __cu_from_r = from;
+ __cu_len_r = n;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ __MODULE_JAL(__raw_copy_from_user)
+ ".set\tnoat\n\t"
+ __UA_ADDU "\t$1, %1, %2\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
+ :
+ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
+ DADDI_SCRATCH, "memory");
+
+ return __cu_len_r;
}
static inline unsigned long
-raw_copy_from_user(void *to, const void __user *from, unsigned long n)
+raw_copy_to_user(void __user *to, const void *from, unsigned long n)
{
- if (eva_kernel_access())
- return __invoke_copy_from_kernel(to, from, n);
- else
- return __invoke_copy_from_user(to, from, n);
+ register void __user *__cu_to_r __asm__("$4");
+ register const void *__cu_from_r __asm__("$5");
+ register long __cu_len_r __asm__("$6");
+
+ __cu_to_r = (to);
+ __cu_from_r = (from);
+ __cu_len_r = (n);
+
+ __asm__ __volatile__(
+ __MODULE_JAL(__raw_copy_to_user)
+ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
+ :
+ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
+ DADDI_SCRATCH, "memory");
+
+ return __cu_len_r;
}
#define INLINE_COPY_FROM_USER
#define INLINE_COPY_TO_USER
static inline unsigned long
-raw_copy_in_user(void __user*to, const void __user *from, unsigned long n)
+raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
- if (eva_kernel_access())
- return ___invoke_copy_in_kernel(to, from, n);
- else
- return ___invoke_copy_in_user(to, from, n);
+ register void __user *__cu_to_r __asm__("$4");
+ register const void __user *__cu_from_r __asm__("$5");
+ register long __cu_len_r __asm__("$6");
+
+ __cu_to_r = to;
+ __cu_from_r = from;
+ __cu_len_r = n;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ __MODULE_JAL(__raw_copy_in_user)
+ ".set\tnoat\n\t"
+ __UA_ADDU "\t$1, %1, %2\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
+ :
+ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
+ DADDI_SCRATCH, "memory");
+ return __cu_len_r;
}
-extern __kernel_size_t __bzero_kernel(void __user *addr, __kernel_size_t size);
extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size);
/*
@@ -657,28 +530,16 @@ __clear_user(void __user *addr, __kernel_size_t size)
#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"
#endif /* CONFIG_CPU_MICROMIPS */
- if (eva_kernel_access()) {
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, $0\n\t"
- "move\t$6, %2\n\t"
- __MODULE_JAL(__bzero_kernel)
- "move\t%0, $6"
- : "=r" (res)
- : "r" (addr), "r" (size)
- : bzero_clobbers);
- } else {
- might_fault();
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, $0\n\t"
- "move\t$6, %2\n\t"
- __MODULE_JAL(__bzero)
- "move\t%0, $6"
- : "=r" (res)
- : "r" (addr), "r" (size)
- : bzero_clobbers);
- }
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, $0\n\t"
+ "move\t$6, %2\n\t"
+ __MODULE_JAL(__bzero)
+ "move\t%0, $6"
+ : "=r" (res)
+ : "r" (addr), "r" (size)
+ : bzero_clobbers);
return res;
}
@@ -692,7 +553,6 @@ __clear_user(void __user *addr, __kernel_size_t size)
__cl_size; \
})
-extern long __strncpy_from_kernel_asm(char *__to, const char __user *__from, long __len);
extern long __strncpy_from_user_asm(char *__to, const char __user *__from, long __len);
/*
@@ -718,33 +578,23 @@ strncpy_from_user(char *__to, const char __user *__from, long __len)
{
long res;
- if (eva_kernel_access()) {
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, %2\n\t"
- "move\t$6, %3\n\t"
- __MODULE_JAL(__strncpy_from_kernel_asm)
- "move\t%0, $2"
- : "=r" (res)
- : "r" (__to), "r" (__from), "r" (__len)
- : "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
- } else {
- might_fault();
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, %2\n\t"
- "move\t$6, %3\n\t"
- __MODULE_JAL(__strncpy_from_user_asm)
- "move\t%0, $2"
- : "=r" (res)
- : "r" (__to), "r" (__from), "r" (__len)
- : "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
- }
+ if (!access_ok(__from, __len))
+ return -EFAULT;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ "move\t$6, %3\n\t"
+ __MODULE_JAL(__strncpy_from_user_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (__to), "r" (__from), "r" (__len)
+ : "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
return res;
}
-extern long __strnlen_kernel_asm(const char __user *s, long n);
extern long __strnlen_user_asm(const char __user *s, long n);
/*
@@ -764,26 +614,18 @@ static inline long strnlen_user(const char __user *s, long n)
{
long res;
+ if (!access_ok(s, 1))
+ return 0;
+
might_fault();
- if (eva_kernel_access()) {
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, %2\n\t"
- __MODULE_JAL(__strnlen_kernel_asm)
- "move\t%0, $2"
- : "=r" (res)
- : "r" (s), "r" (n)
- : "$2", "$4", "$5", __UA_t0, "$31");
- } else {
- __asm__ __volatile__(
- "move\t$4, %1\n\t"
- "move\t$5, %2\n\t"
- __MODULE_JAL(__strnlen_user_asm)
- "move\t%0, $2"
- : "=r" (res)
- : "r" (s), "r" (n)
- : "$2", "$4", "$5", __UA_t0, "$31");
- }
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ __MODULE_JAL(__strnlen_user_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s), "r" (n)
+ : "$2", "$4", "$5", __UA_t0, "$31");
return res;
}
diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
index 2203e2d0ae2a..44a45f3fa4b0 100644
--- a/arch/mips/include/asm/vdso/gettimeofday.h
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -20,6 +20,12 @@
#define VDSO_HAS_CLOCK_GETRES 1
+#if MIPS_ISA_REV < 6
+#define VDSO_SYSCALL_CLOBBERS "hi", "lo",
+#else
+#define VDSO_SYSCALL_CLOBBERS
+#endif
+
static __always_inline long gettimeofday_fallback(
struct __kernel_old_timeval *_tv,
struct timezone *_tz)
@@ -35,7 +41,9 @@ static __always_inline long gettimeofday_fallback(
: "=r" (ret), "=r" (error)
: "r" (tv), "r" (tz), "r" (nr)
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
- "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+ "$14", "$15", "$24", "$25",
+ VDSO_SYSCALL_CLOBBERS
+ "memory");
return error ? -ret : ret;
}
@@ -59,7 +67,9 @@ static __always_inline long clock_gettime_fallback(
: "=r" (ret), "=r" (error)
: "r" (clkid), "r" (ts), "r" (nr)
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
- "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+ "$14", "$15", "$24", "$25",
+ VDSO_SYSCALL_CLOBBERS
+ "memory");
return error ? -ret : ret;
}
@@ -83,7 +93,9 @@ static __always_inline int clock_getres_fallback(
: "=r" (ret), "=r" (error)
: "r" (clkid), "r" (ts), "r" (nr)
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
- "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+ "$14", "$15", "$24", "$25",
+ VDSO_SYSCALL_CLOBBERS
+ "memory");
return error ? -ret : ret;
}
@@ -105,7 +117,9 @@ static __always_inline long clock_gettime32_fallback(
: "=r" (ret), "=r" (error)
: "r" (clkid), "r" (ts), "r" (nr)
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
- "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+ "$14", "$15", "$24", "$25",
+ VDSO_SYSCALL_CLOBBERS
+ "memory");
return error ? -ret : ret;
}
@@ -125,7 +139,9 @@ static __always_inline int clock_getres32_fallback(
: "=r" (ret), "=r" (error)
: "r" (clkid), "r" (ts), "r" (nr)
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
- "$14", "$15", "$24", "$25", "hi", "lo", "memory");
+ "$14", "$15", "$24", "$25",
+ VDSO_SYSCALL_CLOBBERS
+ "memory");
return error ? -ret : ret;
}