diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 905224f954c4..210c40f2112a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -167,6 +167,55 @@ config ARM_AMBA endmenu +menu "ARM errata workarounds via the alternatives framework" + +config ARM64_ERRATUM_845719 + bool "Cortex-A53: 845719: a load might read incorrect data" + depends on COMPAT + default y + help + This option adds an alternative code sequence to work around ARM + erratum 845719 on Cortex-A53 parts up to r0p4. + + When running a compat (AArch32) userspace on an affected Cortex-A53 + part, a load at EL0 from a virtual address that matches the bottom 32 + bits of the virtual address used by a recent load at (AArch64) EL1 + might return incorrect data. + + The workaround is to write the contextidr_el1 register on exception + return to a 32-bit task. + Please note that this does not necessarily enable the workaround, + as it depends on the alternative framework, which will only patch + the kernel if an affected CPU is detected. + + If unsure, say Y. + +config ARM64_ERRATUM_843419 + bool "Cortex-A53: 843419: A load or store might access an incorrect address" + depends on MODULES + default y + help + This option builds kernel modules using the large memory model in + order to avoid the use of the ADRP instruction, which can cause + a subsequent memory access to use an incorrect address on Cortex-A53 + parts up to r0p4. + + Note that the kernel itself must be linked with a version of ld + which fixes potentially affected ADRP instructions through the + use of veneers. + + If unsure, say Y. + +config ARM64_ERRATUM_835769 + bool "Cortex-A53: 835769: AArch64 multiply-accumulate instruction might produce incorrect result" + depends on MODULES + default y + help + This option build kernel with option -mfix-cortex-a53-835769 to + fix mulity-accumulate bug of cpu + +endmenu + menu "Kernel Features" config ARM64_64K_PAGES diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 113b2f1ead2d..880f3b49213a 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -35,6 +35,15 @@ comma = , CHECKFLAGS += -D__aarch64__ +ifeq ($(CONFIG_ARM64_ERRATUM_843419), y) +KBUILD_CFLAGS_MODULE += $(call cc-option,-mfix-cortex-a53-843419) +endif + +ifeq ($(CONFIG_ARM64_ERRATUM_835769), y) +KBUILD_CFLAGS_MODULE += $(call cc-option,-mfix-cortex-a53-835769) +endif +$(info KBUILD_CFLAGS_MODULE:$(KBUILD_CFLAGS_MODULE)) + # Default value head-y := arch/arm64/kernel/head.o diff --git a/arch/arm64/configs/odroidc2_defconfig b/arch/arm64/configs/odroidc2_defconfig index 4298789532d2..5f0e13a73cdf 100644 --- a/arch/arm64/configs/odroidc2_defconfig +++ b/arch/arm64/configs/odroidc2_defconfig @@ -246,6 +246,13 @@ CONFIG_ARCH_MESON64_ODROIDC2=y # CONFIG_ARM_AMBA=y +# +# ARM errata workarounds via the alternatives framework +# +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_835769=y + # # Kernel Features # diff --git a/arch/arm64/configs/odroidc2_i2c_defconfig b/arch/arm64/configs/odroidc2_i2c_defconfig index c20ed34ffc3b..6131fd1fb26c 100644 --- a/arch/arm64/configs/odroidc2_i2c_defconfig +++ b/arch/arm64/configs/odroidc2_i2c_defconfig @@ -246,6 +246,13 @@ CONFIG_ARCH_MESON64_ODROIDC2=y # CONFIG_ARM_AMBA=y +# +# ARM errata workarounds via the alternatives framework +# +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_835769=y + # # Kernel Features # diff --git a/arch/arm64/include/asm/psci.h b/arch/arm64/include/asm/psci.h index e5312ea0ec1a..c28c08f4e37f 100644 --- a/arch/arm64/include/asm/psci.h +++ b/arch/arm64/include/asm/psci.h @@ -16,4 +16,7 @@ int psci_init(void); +int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2); +int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2); + #endif /* __ASM_PSCI_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 5a02c276debc..3fd3345e9cc6 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -14,7 +14,7 @@ arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ entry-fpsimd.o process.o ptrace.o setup.o signal.o \ sys.o stacktrace.o time.o traps.o io.o vdso.o \ hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \ - opcodes.o + opcodes.o psci-call.o arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ sys_compat.o diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index a702f4d1dedd..58cec5054688 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -116,6 +116,16 @@ .if \el == 0 ct_user_enter ldr x23, [sp, #S_SP] // load return stack pointer +#ifdef CONFIG_ARM64_ERRATUM_845719 + tbz x22, #4, 1f +#ifdef CONFIG_PID_IN_CONTEXTIDR + mrs x29, contextidr_el1 + msr contextidr_el1, x29 +#else + msr contextidr_el1, xzr +#endif +1: +#endif .endif .if \ret ldr x1, [sp, #S_X1] // preserve x0 (syscall return) diff --git a/arch/arm64/kernel/psci-call.S b/arch/arm64/kernel/psci-call.S new file mode 100644 index 000000000000..cf83e61cd3b5 --- /dev/null +++ b/arch/arm64/kernel/psci-call.S @@ -0,0 +1,28 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Copyright (C) 2015 ARM Limited + * + * Author: Will Deacon + */ + +#include + +/* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ +ENTRY(__invoke_psci_fn_hvc) + hvc #0 + ret +ENDPROC(__invoke_psci_fn_hvc) + +/* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ +ENTRY(__invoke_psci_fn_smc) + smc #0 + ret +ENDPROC(__invoke_psci_fn_smc) diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 20fa086e0f58..a9599be6a2fd 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -95,40 +95,6 @@ static u32 psci_power_state_pack(struct psci_power_state state) << PSCI_POWER_STATE_AFFL_SHIFT); } -/* - * The following two functions are invoked via the invoke_psci_fn pointer - * and will not be inlined, allowing us to piggyback on the AAPCS. - */ -static noinline int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, - u64 arg2) -{ - asm volatile( - __asmeq("%0", "x0") - __asmeq("%1", "x1") - __asmeq("%2", "x2") - __asmeq("%3", "x3") - "hvc #0\n" - : "+r" (function_id) - : "r" (arg0), "r" (arg1), "r" (arg2)); - - return function_id; -} - -static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, - u64 arg2) -{ - asm volatile( - __asmeq("%0", "x0") - __asmeq("%1", "x1") - __asmeq("%2", "x2") - __asmeq("%3", "x3") - "smc #0\n" - : "+r" (function_id) - : "r" (arg0), "r" (arg1), "r" (arg2)); - - return function_id; -} - static int psci_cpu_suspend(struct psci_power_state state, unsigned long entry_point) { diff --git a/drivers/amlogic/amlnf/dev/phydev.c b/drivers/amlogic/amlnf/dev/phydev.c index ecf63b57c255..1024c6735162 100644 --- a/drivers/amlogic/amlnf/dev/phydev.c +++ b/drivers/amlogic/amlnf/dev/phydev.c @@ -1134,6 +1134,56 @@ static void show_phydev_info(void) } } +/* +this function alloc phydev and init it. +*/ +int aml_alloc_phydev(struct amlnand_phydev **phydev_pp, + struct amlnand_chip *aml_chip, + struct dev_para **dev_para, + int dev_idx) +{ + int ret = 0; + struct hw_controller *controller = &(aml_chip->controller); + /*struct nand_config *config = aml_chip->config_ptr;*/ + struct nand_flash *flash = &(aml_chip->flash); + struct amlnand_phydev *phydev_p = NULL; + + *phydev_pp = aml_nand_malloc(sizeof(struct amlnand_phydev)); + if (*phydev_pp == NULL) { + aml_nand_msg("malloc failed need %lx here", + (sizeof(struct amlnand_phydev))); + ret = -NAND_MALLOC_FAILURE; + return ret; + } + + phydev_p = *phydev_pp; + memset(phydev_p, 0, sizeof(struct amlnand_phydev)); + phydev_p->priv = aml_chip; + + *dev_para = &aml_chip->config_ptr->dev_para[dev_idx]; + memcpy((void *)&phydev_p->name, + &(*dev_para)->name, MAX_DEVICE_NAME_LEN*sizeof(char)); + + /*set default parameter*/ + phydev_p->writesize = flash->pagesize; + phydev_p->erasesize = flash->blocksize; + phydev_p->oobavail = controller->oobavail; + phydev_p->writesize_shift = ffs(phydev_p->writesize) - 1; + phydev_p->erasesize_shift = ffs(phydev_p->erasesize) - 1; + phydev_p->write = nand_write; + phydev_p->read = nand_read; + phydev_p->erase = nand_erase; + phydev_p->block_isbad = nand_block_isbad; + phydev_p->block_markbad = nand_block_markbad; + phydev_p->block_modifybbt = block_modifybbt; + phydev_p->update_bbt = update_bbt; + phydev_p->phydev_test_block = nand_test_block; +#ifndef AML_NAND_UBOOT + phydev_p->suspend = phydev_suspend; + phydev_p->resume = phydev_resume; +#endif + return ret; +} /****** *nand chip usage diff --git a/drivers/amlogic/amports/video.c b/drivers/amlogic/amports/video.c index 7e6fffc24bef..924bb98bf3be 100644 --- a/drivers/amlogic/amports/video.c +++ b/drivers/amlogic/amports/video.c @@ -519,7 +519,7 @@ static DEFINE_MUTEX(video_module_mutex); static DEFINE_SPINLOCK(lock); static u32 frame_par_ready_to_set, frame_par_force_to_set; static u32 vpts_remainder; -static bool video_property_changed; +static int video_property_changed; static u32 video_notify_flag; static int enable_video_discontinue_report = 1; diff --git a/drivers/amlogic/hdmi/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/hdmi/hdmi_tx_20/hw/hdmi_tx_hw.c index 9455001a9533..9e3c659c24e8 100644 --- a/drivers/amlogic/hdmi/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/amlogic/hdmi/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -44,6 +44,7 @@ #include /*#include */ #include +#include #include "mach_reg.h" #include "hdmi_tx_reg.h" @@ -254,7 +255,6 @@ int hdmitx_ddc_hw_op(enum ddc_op cmd) return ret; } -#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" int hdmitx_hdcp_opr(unsigned int val) { if (val == 1) { diff --git a/drivers/amlogic/input/sensor/stk220x_poll.c b/drivers/amlogic/input/sensor/stk220x_poll.c index 7c3dc70c954c..ada53839f083 100644 --- a/drivers/amlogic/input/sensor/stk220x_poll.c +++ b/drivers/amlogic/input/sensor/stk220x_poll.c @@ -124,7 +124,7 @@ inline int32_t get_reading(void) stk_readb(STK_ALS_DT2_REG)); } -inline int32_t alscode2lux(int32_t alscode) +int32_t alscode2lux(int32_t alscode) { /*R-set Def --> 500KOhm ==> x 5 IT --> x1 diff --git a/drivers/amlogic/iomap/iomap.c b/drivers/amlogic/iomap/iomap.c index f2db1454e05b..8863c3c6b28d 100644 --- a/drivers/amlogic/iomap/iomap.c +++ b/drivers/amlogic/iomap/iomap.c @@ -30,6 +30,8 @@ #include #ifndef CONFIG_ARM64 #include +#else +#include #endif #if 0 void meson_regmap_lock(void *p) @@ -296,16 +298,7 @@ static noinline int __invoke_sec_fn_smc(u32 function_id, u32 arg0, u32 arg1, static noinline int __invoke_sec_fn_smc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) { - asm volatile( - __asmeq("%0", "x0") - __asmeq("%1", "x1") - __asmeq("%2", "x2") - __asmeq("%3", "x3") - "smc #0\n" - : "+r" (function_id) - : "r" (arg0), "r" (arg1), "r" (arg2)); - - return function_id; + return __invoke_psci_fn_smc(function_id, arg0, arg1, arg2); } #endif diff --git a/drivers/amlogic/mmc/aml_sdhc_m8.c b/drivers/amlogic/mmc/aml_sdhc_m8.c index 0f9bffaceef2..132d0a9b55d9 100644 --- a/drivers/amlogic/mmc/aml_sdhc_m8.c +++ b/drivers/amlogic/mmc/aml_sdhc_m8.c @@ -613,7 +613,7 @@ void aml_sdhc_clear_fifo(struct amlsd_host *host) } /*enable irq bit in reg SDHC_ICTL*/ -inline void aml_sdhc_enable_imask(struct amlsd_host *host, u32 irq) +void aml_sdhc_enable_imask(struct amlsd_host *host, u32 irq) { u32 ictl = readl(host->base+SDHC_ICTL); ictl |= irq; @@ -621,7 +621,7 @@ inline void aml_sdhc_enable_imask(struct amlsd_host *host, u32 irq) } /*disable irq bit in reg SDHC_ICTL*/ -inline void aml_sdhc_disable_imask(struct amlsd_host *host, u32 irq) +void aml_sdhc_disable_imask(struct amlsd_host *host, u32 irq) { u32 ictl = readl(host->base+SDHC_ICTL); ictl &= ~irq; diff --git a/drivers/amlogic/pm/gxbb_pm.c b/drivers/amlogic/pm/gxbb_pm.c index 46de6a924440..a50bfc787482 100644 --- a/drivers/amlogic/pm/gxbb_pm.c +++ b/drivers/amlogic/pm/gxbb_pm.c @@ -224,25 +224,6 @@ ssize_t time_out_store(struct device *dev, struct device_attribute *attr, DEVICE_ATTR(time_out, 0666, time_out_show, time_out_store); static int suspend_reason; -static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, - u64 arg2) -{ - register long x0 asm("x0") = function_id; - register long x1 asm("x1") = arg0; - register long x2 asm("x2") = arg1; - register long x3 asm("x3") = arg2; - asm volatile( - __asmeq("%0", "x0") - __asmeq("%1", "x1") - __asmeq("%2", "x2") - __asmeq("%3", "x3") - "smc #0\n" - : "+r" (x0) - : "r" (x1), "r" (x2), "r" (x3)); - - return x0; -} - ssize_t suspend_reason_show(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 5073cbc796d8..039d78b144a9 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -96,14 +96,13 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, if (req->cmd_flags & REQ_DISCARD) return tr->discard(dev, block, nsect); - switch(rq_data_dir(req)) { - case READ: + if (rq_data_dir(req) == READ) { for (; nsect > 0; nsect--, block++, buf += tr->blksize) if (tr->readsect(dev, block, buf)) return -EIO; rq_flush_dcache_pages(req); return 0; - case WRITE: + } else { if (!tr->writesect) return -EIO; @@ -112,9 +111,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, if (tr->writesect(dev, block, buf)) return -EIO; return 0; - default: - printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req)); - return -EIO; } } diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 2b9811dc2851..2e9f7d966177 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -683,7 +683,7 @@ static inline void early_init_dt_check_for_initrd(unsigned long node) #include int is_instabooting; -inline void early_init_dt_check_for_instaboot(unsigned long node) +void early_init_dt_check_for_instaboot(unsigned long node) { unsigned long version_code; int len; diff --git a/fs/namespace.c b/fs/namespace.c index 039f3802d70e..a793eec26b23 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2695,9 +2695,9 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data) { int ret; - char *kernel_type; + char *kernel_type = NULL; struct filename *kernel_dir; - char *kernel_dev; + char *kernel_dev = NULL; unsigned long data_page; ret = copy_mount_string(type, &kernel_type); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 58258ad50d5f..39c896c3d871 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2964,16 +2964,13 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *info, bool auth_probe) { - int status; + int status = 0; - switch (auth_probe) { - case false: + if (!auth_probe) status = nfs4_lookup_root(server, fhandle, info); - if (status != -NFS4ERR_WRONGSEC) - break; - default: + + if (auth_probe || status == NFS4ERR_WRONGSEC) status = nfs4_do_find_root_sec(server, fhandle, info); - } if (status == 0) status = nfs4_server_capabilities(server, fhandle); diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c index 960183d4258f..235c6d8bf502 100644 --- a/lib/decompress_unlzo.c +++ b/lib/decompress_unlzo.c @@ -51,7 +51,7 @@ static const unsigned char lzop_magic[] = { #define HEADER_SIZE_MIN (9 + 7 + 4 + 8 + 1 + 4) #define HEADER_SIZE_MAX (9 + 7 + 1 + 8 + 8 + 4 + 1 + 255 + 4) -STATIC inline int INIT parse_header(u8 *input, int *skip, int in_len) +STATIC int INIT parse_header(u8 *input, int *skip, int in_len) { int l; u8 *parse = input; @@ -108,7 +108,7 @@ STATIC inline int INIT parse_header(u8 *input, int *skip, int in_len) return 1; } -STATIC inline int INIT unlzo(u8 *input, int in_len, +STATIC int INIT unlzo(u8 *input, int in_len, int (*fill) (void *, unsigned int), int (*flush) (void *, unsigned int), u8 *output, int *posp, diff --git a/mm/rmap.c b/mm/rmap.c index cab982084e2b..45f18547e4eb 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -527,7 +527,7 @@ __vma_address(struct page *page, struct vm_area_struct *vma) return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); } -inline unsigned long +static inline unsigned long vma_address(struct page *page, struct vm_area_struct *vma) { unsigned long address = __vma_address(page, vma);