diff --git a/config/kernel/linux-rk3328-default.config b/config/kernel/linux-rk3328-default.config index b5c24bac3..970f3343a 100644 --- a/config/kernel/linux-rk3328-default.config +++ b/config/kernel/linux-rk3328-default.config @@ -1161,12 +1161,12 @@ CONFIG_BT_HCIUART_H4=y # CONFIG_BT_HCIUART_BCSP is not set CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_LL=y -# CONFIG_BT_HCIUART_3WIRE is not set -# CONFIG_BT_HCIUART_INTEL is not set -# CONFIG_BT_HCIUART_BCM is not set -# CONFIG_BT_HCIUART_QCA is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIBCM203X=y +CONFIG_BT_HCIBPA10X=y CONFIG_BT_HCIBFUSB=y CONFIG_BT_HCIVHCI=y CONFIG_BT_MRVL=y diff --git a/patch/kernel/rockchip-default/04-patch-4.4.135-136.patch b/patch/kernel/rockchip-default/04-patch-4.4.135-136.patch new file mode 100644 index 000000000..66c803b25 --- /dev/null +++ b/patch/kernel/rockchip-default/04-patch-4.4.135-136.patch @@ -0,0 +1,1421 @@ +diff --git a/Makefile b/Makefile +index 9b14a5a224c5..a05a7a005715 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 135 ++SUBLEVEL = 136 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h +index 197e06afbf71..e3438c623598 100644 +--- a/arch/arm64/include/asm/atomic_lse.h ++++ b/arch/arm64/include/asm/atomic_lse.h +@@ -114,7 +114,7 @@ static inline void atomic_and(int i, atomic_t *v) + /* LSE atomics */ + " mvn %w[i], %w[i]\n" + " stclr %w[i], %[v]") +- : [i] "+r" (w0), [v] "+Q" (v->counter) ++ : [i] "+&r" (w0), [v] "+Q" (v->counter) + : "r" (x1) + : "x30"); + } +@@ -131,7 +131,7 @@ static inline void atomic_sub(int i, atomic_t *v) + /* LSE atomics */ + " neg %w[i], %w[i]\n" + " stadd %w[i], %[v]") +- : [i] "+r" (w0), [v] "+Q" (v->counter) ++ : [i] "+&r" (w0), [v] "+Q" (v->counter) + : "r" (x1) + : "x30"); + } +@@ -151,7 +151,7 @@ static inline int atomic_sub_return##name(int i, atomic_t *v) \ + " neg %w[i], %w[i]\n" \ + " ldadd" #mb " %w[i], w30, %[v]\n" \ + " add %w[i], %w[i], w30") \ +- : [i] "+r" (w0), [v] "+Q" (v->counter) \ ++ : [i] "+&r" (w0), [v] "+Q" (v->counter) \ + : "r" (x1) \ + : "x30" , ##cl); \ + \ +@@ -255,7 +255,7 @@ static inline void atomic64_and(long i, atomic64_t *v) + /* LSE atomics */ + " mvn %[i], %[i]\n" + " stclr %[i], %[v]") +- : [i] "+r" (x0), [v] "+Q" (v->counter) ++ : [i] "+&r" (x0), [v] "+Q" (v->counter) + : "r" (x1) + : "x30"); + } +@@ -272,7 +272,7 @@ static inline void atomic64_sub(long i, atomic64_t *v) + /* LSE atomics */ + " neg %[i], %[i]\n" + " stadd %[i], %[v]") +- : [i] "+r" (x0), [v] "+Q" (v->counter) ++ : [i] "+&r" (x0), [v] "+Q" (v->counter) + : "r" (x1) + : "x30"); + } +@@ -292,7 +292,7 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \ + " neg %[i], %[i]\n" \ + " ldadd" #mb " %[i], x30, %[v]\n" \ + " add %[i], %[i], x30") \ +- : [i] "+r" (x0), [v] "+Q" (v->counter) \ ++ : [i] "+&r" (x0), [v] "+Q" (v->counter) \ + : "r" (x1) \ + : "x30" , ##cl); \ + \ +@@ -412,7 +412,7 @@ static inline long __cmpxchg_double##name(unsigned long old1, \ + " eor %[old1], %[old1], %[oldval1]\n" \ + " eor %[old2], %[old2], %[oldval2]\n" \ + " orr %[old1], %[old1], %[old2]") \ +- : [old1] "+r" (x0), [old2] "+r" (x1), \ ++ : [old1] "+&r" (x0), [old2] "+&r" (x1), \ + [v] "+Q" (*(unsigned long *)ptr) \ + : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \ + [oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \ +diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c +index fcbc4e57d765..1ee603d07847 100644 +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -680,6 +680,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) + if (value & ~known_bits) + return -EOPNOTSUPP; + ++ /* Setting FRE without FR is not supported. */ ++ if ((value & (PR_FP_MODE_FR | PR_FP_MODE_FRE)) == PR_FP_MODE_FRE) ++ return -EOPNOTSUPP; ++ + /* Avoid inadvertently triggering emulation */ + if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu && + !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64)) +diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c +index a9958b4d9194..32fa3ae1a0a6 100644 +--- a/arch/mips/kernel/ptrace.c ++++ b/arch/mips/kernel/ptrace.c +@@ -841,7 +841,7 @@ long arch_ptrace(struct task_struct *child, long request, + break; + } + #endif +- tmp = get_fpr32(&fregs[addr - FPR_BASE], 0); ++ tmp = get_fpr64(&fregs[addr - FPR_BASE], 0); + break; + case PC: + tmp = regs->cp0_epc; +diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c +index b4b7e02443e7..d95117e71f69 100644 +--- a/arch/mips/kernel/ptrace32.c ++++ b/arch/mips/kernel/ptrace32.c +@@ -107,7 +107,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + addr & 1); + break; + } +- tmp = get_fpr32(&fregs[addr - FPR_BASE], 0); ++ tmp = get_fpr64(&fregs[addr - FPR_BASE], 0); + break; + case PC: + tmp = regs->cp0_epc; +diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S +index 9c9b7411b28b..55eb3b752ca0 100644 +--- a/arch/powerpc/kernel/cpu_setup_power.S ++++ b/arch/powerpc/kernel/cpu_setup_power.S +@@ -27,6 +27,7 @@ _GLOBAL(__setup_cpu_power7) + beqlr + li r0,0 + mtspr SPRN_LPID,r0 ++ mtspr SPRN_PCR,r0 + mfspr r3,SPRN_LPCR + bl __init_LPCR + bl __init_tlb_power7 +@@ -40,6 +41,7 @@ _GLOBAL(__restore_cpu_power7) + beqlr + li r0,0 + mtspr SPRN_LPID,r0 ++ mtspr SPRN_PCR,r0 + mfspr r3,SPRN_LPCR + bl __init_LPCR + bl __init_tlb_power7 +@@ -55,6 +57,7 @@ _GLOBAL(__setup_cpu_power8) + beqlr + li r0,0 + mtspr SPRN_LPID,r0 ++ mtspr SPRN_PCR,r0 + mfspr r3,SPRN_LPCR + ori r3, r3, LPCR_PECEDH + bl __init_LPCR +@@ -74,6 +77,7 @@ _GLOBAL(__restore_cpu_power8) + beqlr + li r0,0 + mtspr SPRN_LPID,r0 ++ mtspr SPRN_PCR,r0 + mfspr r3,SPRN_LPCR + ori r3, r3, LPCR_PECEDH + bl __init_LPCR +diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c +index d77f2f6c7ff0..0b30b9dfc87f 100644 +--- a/arch/sh/kernel/sh_ksyms_32.c ++++ b/arch/sh/kernel/sh_ksyms_32.c +@@ -34,6 +34,9 @@ DECLARE_EXPORT(__sdivsi3); + DECLARE_EXPORT(__lshrsi3); + DECLARE_EXPORT(__ashrsi3); + DECLARE_EXPORT(__ashlsi3); ++DECLARE_EXPORT(__lshrsi3_r0); ++DECLARE_EXPORT(__ashrsi3_r0); ++DECLARE_EXPORT(__ashlsi3_r0); + DECLARE_EXPORT(__ashiftrt_r4_6); + DECLARE_EXPORT(__ashiftrt_r4_7); + DECLARE_EXPORT(__ashiftrt_r4_8); +diff --git a/arch/sh/lib/ashlsi3.S b/arch/sh/lib/ashlsi3.S +index bd47e9b403a5..70a6434945ab 100644 +--- a/arch/sh/lib/ashlsi3.S ++++ b/arch/sh/lib/ashlsi3.S +@@ -54,21 +54,38 @@ Boston, MA 02110-1301, USA. */ + ! + ! (none) + ! ++! __ashlsi3_r0 ++! ++! Entry: ++! ++! r4: Value to shift ++! r0: Shifts ++! ++! Exit: ++! ++! r0: Result ++! ++! Destroys: ++! ++! (none) ++ ++ + .global __ashlsi3 ++ .global __ashlsi3_r0 + + .align 2 + __ashlsi3: +- mov #31,r0 +- and r0,r5 ++ mov r5,r0 ++ .align 2 ++__ashlsi3_r0: ++ and #31,r0 ++ mov.l r4,@-r15 ++ mov r0,r4 + mova ashlsi3_table,r0 +- mov.b @(r0,r5),r5 +-#ifdef __sh1__ +- add r5,r0 ++ mov.b @(r0,r4),r4 ++ add r4,r0 + jmp @r0 +-#else +- braf r5 +-#endif +- mov r4,r0 ++ mov.l @r15+,r0 + + .align 2 + ashlsi3_table: +diff --git a/arch/sh/lib/ashrsi3.S b/arch/sh/lib/ashrsi3.S +index 6f3cf46b77c2..602599d80209 100644 +--- a/arch/sh/lib/ashrsi3.S ++++ b/arch/sh/lib/ashrsi3.S +@@ -54,22 +54,37 @@ Boston, MA 02110-1301, USA. */ + ! + ! (none) + ! ++! __ashrsi3_r0 ++! ++! Entry: ++! ++! r4: Value to shift ++! r0: Shifts ++! ++! Exit: ++! ++! r0: Result ++! ++! Destroys: ++! ++! (none) + + .global __ashrsi3 ++ .global __ashrsi3_r0 + + .align 2 + __ashrsi3: +- mov #31,r0 +- and r0,r5 ++ mov r5,r0 ++ .align 2 ++__ashrsi3_r0: ++ and #31,r0 ++ mov.l r4,@-r15 ++ mov r0,r4 + mova ashrsi3_table,r0 +- mov.b @(r0,r5),r5 +-#ifdef __sh1__ +- add r5,r0 ++ mov.b @(r0,r4),r4 ++ add r4,r0 + jmp @r0 +-#else +- braf r5 +-#endif +- mov r4,r0 ++ mov.l @r15+,r0 + + .align 2 + ashrsi3_table: +diff --git a/arch/sh/lib/lshrsi3.S b/arch/sh/lib/lshrsi3.S +index 1e7aaa557130..f2a6959f526d 100644 +--- a/arch/sh/lib/lshrsi3.S ++++ b/arch/sh/lib/lshrsi3.S +@@ -53,22 +53,38 @@ Boston, MA 02110-1301, USA. */ + ! Destroys: + ! + ! (none) ++! ++! __lshrsi3_r0 ++! ++! Entry: ++! ++! r0: Value to shift ++! r5: Shifts ++! ++! Exit: ++! ++! r0: Result ++! ++! Destroys: ++! ++! (none) + ! + .global __lshrsi3 ++ .global __lshrsi3_r0 + + .align 2 + __lshrsi3: +- mov #31,r0 +- and r0,r5 ++ mov r5,r0 ++ .align 2 ++__lshrsi3_r0: ++ and #31,r0 ++ mov.l r4,@-r15 ++ mov r0,r4 + mova lshrsi3_table,r0 +- mov.b @(r0,r5),r5 +-#ifdef __sh1__ +- add r5,r0 ++ mov.b @(r0,r4),r4 ++ add r4,r0 + jmp @r0 +-#else +- braf r5 +-#endif +- mov r4,r0 ++ mov.l @r15+,r0 + + .align 2 + lshrsi3_table: +diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c +index f87a55d77094..9b3f2e212b37 100644 +--- a/arch/sparc/kernel/ds.c ++++ b/arch/sparc/kernel/ds.c +@@ -908,7 +908,7 @@ static int register_services(struct ds_info *dp) + pbuf.req.handle = cp->handle; + pbuf.req.major = 1; + pbuf.req.minor = 0; +- strcpy(pbuf.req.svc_id, cp->service_id); ++ strcpy(pbuf.id_buf, cp->service_id); + + err = __ds_send(lp, &pbuf, msg_len); + if (err > 0) +diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c +index 56410ea75ac5..6682b3eec2b6 100644 +--- a/drivers/dma/sh/usb-dmac.c ++++ b/drivers/dma/sh/usb-dmac.c +@@ -448,7 +448,7 @@ usb_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + static int usb_dmac_chan_terminate_all(struct dma_chan *chan) + { + struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan); +- struct usb_dmac_desc *desc; ++ struct usb_dmac_desc *desc, *_desc; + unsigned long flags; + LIST_HEAD(head); + LIST_HEAD(list); +@@ -459,7 +459,7 @@ static int usb_dmac_chan_terminate_all(struct dma_chan *chan) + if (uchan->desc) + uchan->desc = NULL; + list_splice_init(&uchan->desc_got, &list); +- list_for_each_entry(desc, &list, node) ++ list_for_each_entry_safe(desc, _desc, &list, node) + list_move_tail(&desc->node, &uchan->desc_freed); + spin_unlock_irqrestore(&uchan->vc.lock, flags); + vchan_dma_desc_free_list(&uchan->vc, &head); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 7f39b8ad88ae..de6710fe3ff4 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -768,6 +768,14 @@ static const struct dmi_system_id intel_no_lvds[] = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"), + }, + }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Radiant P845", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P845"), ++ }, ++ }, + + { } /* terminating entry */ + }; +diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c +index d2dff159a471..99434f5be34c 100644 +--- a/drivers/hwtracing/stm/core.c ++++ b/drivers/hwtracing/stm/core.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include "stm.h" + + #include +@@ -602,7 +603,7 @@ static void stm_device_release(struct device *dev) + { + struct stm_device *stm = to_stm_device(dev); + +- kfree(stm); ++ vfree(stm); + } + + int stm_register_device(struct device *parent, struct stm_data *stm_data, +@@ -619,7 +620,7 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, + return -EINVAL; + + nmasters = stm_data->sw_end - stm_data->sw_start; +- stm = kzalloc(sizeof(*stm) + nmasters * sizeof(void *), GFP_KERNEL); ++ stm = vzalloc(sizeof(*stm) + nmasters * sizeof(void *)); + if (!stm) + return -ENOMEM; + +@@ -656,7 +657,7 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data, + err_device: + put_device(&stm->dev); + err_free: +- kfree(stm); ++ vfree(stm); + + return err; + } +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 599c0d7bd906..6f89484765e3 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -33,7 +33,6 @@ + #include + #include + #include +-#include + + /* register offsets */ + #define ICSCR 0x00 /* slave ctrl */ +@@ -84,6 +83,7 @@ + + #define RCAR_BUS_PHASE_START (MDBS | MIE | ESG) + #define RCAR_BUS_PHASE_DATA (MDBS | MIE) ++#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF) + #define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB) + + #define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE) +@@ -94,7 +94,6 @@ + #define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF) + + #define ID_LAST_MSG (1 << 0) +-#define ID_IOERROR (1 << 1) + #define ID_DONE (1 << 2) + #define ID_ARBLOST (1 << 3) + #define ID_NACK (1 << 4) +@@ -108,10 +107,10 @@ enum rcar_i2c_type { + struct rcar_i2c_priv { + void __iomem *io; + struct i2c_adapter adap; +- struct i2c_msg *msg; ++ struct i2c_msg *msg; ++ int msgs_left; + struct clk *clk; + +- spinlock_t lock; + wait_queue_head_t wait; + + int pos; +@@ -144,9 +143,10 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv) + { + /* reset master mode */ + rcar_i2c_write(priv, ICMIER, 0); +- rcar_i2c_write(priv, ICMCR, 0); ++ rcar_i2c_write(priv, ICMCR, MDBS); + rcar_i2c_write(priv, ICMSR, 0); +- rcar_i2c_write(priv, ICMAR, 0); ++ /* start clock */ ++ rcar_i2c_write(priv, ICCCR, priv->icccr); + } + + static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) +@@ -257,16 +257,28 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) + { + int read = !!rcar_i2c_is_recv(priv); + ++ priv->pos = 0; ++ priv->flags = 0; ++ if (priv->msgs_left == 1) ++ rcar_i2c_flags_set(priv, ID_LAST_MSG); ++ + rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); + rcar_i2c_write(priv, ICMSR, 0); + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); + rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND); + } + ++static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) ++{ ++ priv->msg++; ++ priv->msgs_left--; ++ rcar_i2c_prepare_msg(priv); ++} ++ + /* + * interrupt functions + */ +-static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) ++static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) + { + struct i2c_msg *msg = priv->msg; + +@@ -276,14 +288,7 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) + * Do nothing + */ + if (!(msr & MDE)) +- return 0; +- +- /* +- * If address transfer phase finished, +- * goto data phase. +- */ +- if (msr & MAT) +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); ++ return; + + if (priv->pos < msg->len) { + /* +@@ -305,29 +310,23 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) + * [ICRXTX] -> [SHIFT] -> [I2C bus] + */ + +- if (priv->flags & ID_LAST_MSG) ++ if (priv->flags & ID_LAST_MSG) { + /* + * If current msg is the _LAST_ msg, + * prepare stop condition here. + * ID_DONE will be set on STOP irq. + */ + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); +- else +- /* +- * If current msg is _NOT_ last msg, +- * it doesn't call stop phase. +- * thus, there is no STOP irq. +- * return ID_DONE here. +- */ +- return ID_DONE; ++ } else { ++ rcar_i2c_next_msg(priv); ++ return; ++ } + } + + rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND); +- +- return 0; + } + +-static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) ++static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) + { + struct i2c_msg *msg = priv->msg; + +@@ -337,14 +336,10 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) + * Do nothing + */ + if (!(msr & MDR)) +- return 0; ++ return; + + if (msr & MAT) { +- /* +- * Address transfer phase finished, +- * but, there is no data at this point. +- * Do nothing. +- */ ++ /* Address transfer phase finished, but no data at this point. */ + } else if (priv->pos < msg->len) { + /* + * get received data +@@ -360,12 +355,11 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) + */ + if (priv->pos + 1 >= msg->len) + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); +- else +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); + +- rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); +- +- return 0; ++ if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) ++ rcar_i2c_next_msg(priv); ++ else ++ rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); + } + + static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) +@@ -426,22 +420,21 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) + static irqreturn_t rcar_i2c_irq(int irq, void *ptr) + { + struct rcar_i2c_priv *priv = ptr; +- irqreturn_t result = IRQ_HANDLED; +- u32 msr; +- +- /*-------------- spin lock -----------------*/ +- spin_lock(&priv->lock); ++ u32 msr, val; + +- if (rcar_i2c_slave_irq(priv)) +- goto exit; ++ /* Clear START or STOP as soon as we can */ ++ val = rcar_i2c_read(priv, ICMCR); ++ rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA); + + msr = rcar_i2c_read(priv, ICMSR); + + /* Only handle interrupts that are currently enabled */ + msr &= rcar_i2c_read(priv, ICMIER); + if (!msr) { +- result = IRQ_NONE; +- goto exit; ++ if (rcar_i2c_slave_irq(priv)) ++ return IRQ_HANDLED; ++ ++ return IRQ_NONE; + } + + /* Arbitration lost */ +@@ -452,8 +445,7 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) + + /* Nack */ + if (msr & MNR) { +- /* go to stop phase */ +- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); ++ /* HW automatically sends STOP after received NACK */ + rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); + rcar_i2c_flags_set(priv, ID_NACK); + goto out; +@@ -461,14 +453,15 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) + + /* Stop */ + if (msr & MST) { ++ priv->msgs_left--; /* The last message also made it */ + rcar_i2c_flags_set(priv, ID_DONE); + goto out; + } + + if (rcar_i2c_is_recv(priv)) +- rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); ++ rcar_i2c_irq_recv(priv, msr); + else +- rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr)); ++ rcar_i2c_irq_send(priv, msr); + + out: + if (rcar_i2c_flags_has(priv, ID_DONE)) { +@@ -477,11 +470,7 @@ out: + wake_up(&priv->wait); + } + +-exit: +- spin_unlock(&priv->lock); +- /*-------------- spin unlock -----------------*/ +- +- return result; ++ return IRQ_HANDLED; + } + + static int rcar_i2c_master_xfer(struct i2c_adapter *adap, +@@ -490,22 +479,11 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, + { + struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); + struct device *dev = rcar_i2c_priv_to_dev(priv); +- unsigned long flags; + int i, ret; +- long timeout; ++ long time_left; + + pm_runtime_get_sync(dev); + +- /*-------------- spin lock -----------------*/ +- spin_lock_irqsave(&priv->lock, flags); +- +- rcar_i2c_init(priv); +- /* start clock */ +- rcar_i2c_write(priv, ICCCR, priv->icccr); +- +- spin_unlock_irqrestore(&priv->lock, flags); +- /*-------------- spin unlock -----------------*/ +- + ret = rcar_i2c_bus_barrier(priv); + if (ret < 0) + goto out; +@@ -514,48 +492,28 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, + /* This HW can't send STOP after address phase */ + if (msgs[i].len == 0) { + ret = -EOPNOTSUPP; +- break; +- } +- +- /*-------------- spin lock -----------------*/ +- spin_lock_irqsave(&priv->lock, flags); +- +- /* init each data */ +- priv->msg = &msgs[i]; +- priv->pos = 0; +- priv->flags = 0; +- if (i == num - 1) +- rcar_i2c_flags_set(priv, ID_LAST_MSG); +- +- rcar_i2c_prepare_msg(priv); +- +- spin_unlock_irqrestore(&priv->lock, flags); +- /*-------------- spin unlock -----------------*/ +- +- timeout = wait_event_timeout(priv->wait, +- rcar_i2c_flags_has(priv, ID_DONE), +- adap->timeout); +- if (!timeout) { +- ret = -ETIMEDOUT; +- break; +- } +- +- if (rcar_i2c_flags_has(priv, ID_NACK)) { +- ret = -ENXIO; +- break; +- } +- +- if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { +- ret = -EAGAIN; +- break; +- } +- +- if (rcar_i2c_flags_has(priv, ID_IOERROR)) { +- ret = -EIO; +- break; ++ goto out; + } ++ } + +- ret = i + 1; /* The number of transfer */ ++ /* init data */ ++ priv->msg = msgs; ++ priv->msgs_left = num; ++ ++ rcar_i2c_prepare_msg(priv); ++ ++ time_left = wait_event_timeout(priv->wait, ++ rcar_i2c_flags_has(priv, ID_DONE), ++ num * adap->timeout); ++ if (!time_left) { ++ rcar_i2c_init(priv); ++ ret = -ETIMEDOUT; ++ } else if (rcar_i2c_flags_has(priv, ID_NACK)) { ++ ret = -ENXIO; ++ } else if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { ++ ret = -EAGAIN; ++ } else { ++ ret = num - priv->msgs_left; /* The number of transfer */ + } + out: + pm_runtime_put(dev); +@@ -650,23 +608,27 @@ static int rcar_i2c_probe(struct platform_device *pdev) + return PTR_ERR(priv->clk); + } + ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ priv->io = devm_ioremap_resource(dev, res); ++ if (IS_ERR(priv->io)) ++ return PTR_ERR(priv->io); ++ + bus_speed = 100000; /* default 100 kHz */ + of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); + + priv->devtype = (enum rcar_i2c_type)of_match_device(rcar_i2c_dt_ids, dev)->data; + ++ pm_runtime_enable(dev); ++ pm_runtime_get_sync(dev); + ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); + if (ret < 0) +- return ret; ++ goto out_pm_put; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->io = devm_ioremap_resource(dev, res); +- if (IS_ERR(priv->io)) +- return PTR_ERR(priv->io); ++ rcar_i2c_init(priv); ++ pm_runtime_put(dev); + + irq = platform_get_irq(pdev, 0); + init_waitqueue_head(&priv->wait); +- spin_lock_init(&priv->lock); + + adap = &priv->adap; + adap->nr = pdev->id; +@@ -682,22 +644,26 @@ static int rcar_i2c_probe(struct platform_device *pdev) + dev_name(dev), priv); + if (ret < 0) { + dev_err(dev, "cannot get irq %d\n", irq); +- return ret; ++ goto out_pm_disable; + } + +- pm_runtime_enable(dev); + platform_set_drvdata(pdev, priv); + + ret = i2c_add_numbered_adapter(adap); + if (ret < 0) { + dev_err(dev, "reg adap failed: %d\n", ret); +- pm_runtime_disable(dev); +- return ret; ++ goto out_pm_disable; + } + + dev_info(dev, "probed\n"); + + return 0; ++ ++ out_pm_put: ++ pm_runtime_put(dev); ++ out_pm_disable: ++ pm_runtime_disable(dev); ++ return ret; + } + + static int rcar_i2c_remove(struct platform_device *pdev) +diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c +index c5b999f0c519..7ef9b13262a8 100644 +--- a/drivers/iio/buffer/kfifo_buf.c ++++ b/drivers/iio/buffer/kfifo_buf.c +@@ -24,6 +24,13 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, + if ((length == 0) || (bytes_per_datum == 0)) + return -EINVAL; + ++ /* ++ * Make sure we don't overflow an unsigned int after kfifo rounds up to ++ * the next power of 2. ++ */ ++ if (roundup_pow_of_two(length) > UINT_MAX / bytes_per_datum) ++ return -EINVAL; ++ + return __kfifo_alloc((struct __kfifo *)&buf->kf, length, + bytes_per_datum, GFP_KERNEL); + } +diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c +index cb6aecbc1dc2..25dba1d7aa57 100644 +--- a/drivers/input/mouse/elan_i2c_smbus.c ++++ b/drivers/input/mouse/elan_i2c_smbus.c +@@ -130,7 +130,7 @@ static int elan_smbus_get_baseline_data(struct i2c_client *client, + bool max_baseline, u8 *value) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + max_baseline ? +@@ -149,7 +149,7 @@ static int elan_smbus_get_version(struct i2c_client *client, + bool iap, u8 *version) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + iap ? ETP_SMBUS_IAP_VERSION_CMD : +@@ -169,7 +169,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client, + u8 *ic_type, u8 *version) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_SM_VERSION_CMD, val); +@@ -186,7 +186,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client, + static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_UNIQUEID_CMD, val); +@@ -203,7 +203,7 @@ static int elan_smbus_get_checksum(struct i2c_client *client, + bool iap, u16 *csum) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + iap ? ETP_SMBUS_FW_CHECKSUM_CMD : +@@ -223,7 +223,7 @@ static int elan_smbus_get_max(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val); + if (error) { +@@ -241,7 +241,7 @@ static int elan_smbus_get_resolution(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_RESOLUTION_CMD, val); +@@ -261,7 +261,7 @@ static int elan_smbus_get_num_traces(struct i2c_client *client, + unsigned int *y_traces) + { + int error; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_XY_TRACENUM_CMD, val); +@@ -288,7 +288,7 @@ static int elan_smbus_iap_get_mode(struct i2c_client *client, + { + int error; + u16 constant; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val); + if (error < 0) { +@@ -339,7 +339,7 @@ static int elan_smbus_prepare_fw_update(struct i2c_client *client) + int len; + int error; + enum tp_mode mode; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06}; + u16 password; + +@@ -413,7 +413,7 @@ static int elan_smbus_write_fw_block(struct i2c_client *client, + struct device *dev = &client->dev; + int error; + u16 result; +- u8 val[3]; ++ u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; + + /* + * Due to the limitation of smbus protocol limiting +diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c +index 4e3d2e7c697c..e8c3a8c32534 100644 +--- a/drivers/net/irda/w83977af_ir.c ++++ b/drivers/net/irda/w83977af_ir.c +@@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb, + + mtt = irda_get_mtt(skb); + pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt); +- if (mtt) ++ if (mtt > 1000) ++ mdelay(mtt/1000); ++ else if (mtt) + udelay(mtt); + + /* Enable DMA interrupt */ +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c +index 5624ade92cc0..c2a156a8acec 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c +@@ -304,9 +304,6 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + writeVal = 0x00000000; + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeVal = writeVal - 0x06060606; +- else if (rtlpriv->dm.dynamic_txhighpower_lvl == +- TXHIGHPWRLEVEL_BT2) +- writeVal = writeVal; + *(p_outwriteval + rf) = writeVal; + } + } +diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c +index e3cd3ece4412..c3d1891d2d3f 100644 +--- a/drivers/scsi/scsi_transport_srp.c ++++ b/drivers/scsi/scsi_transport_srp.c +@@ -52,6 +52,8 @@ struct srp_internal { + struct transport_container rport_attr_cont; + }; + ++static int scsi_is_srp_rport(const struct device *dev); ++ + #define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t) + + #define dev_to_rport(d) container_of(d, struct srp_rport, dev) +@@ -61,9 +63,24 @@ static inline struct Scsi_Host *rport_to_shost(struct srp_rport *r) + return dev_to_shost(r->dev.parent); + } + ++static int find_child_rport(struct device *dev, void *data) ++{ ++ struct device **child = data; ++ ++ if (scsi_is_srp_rport(dev)) { ++ WARN_ON_ONCE(*child); ++ *child = dev; ++ } ++ return 0; ++} ++ + static inline struct srp_rport *shost_to_rport(struct Scsi_Host *shost) + { +- return transport_class_to_srp_rport(&shost->shost_gendev); ++ struct device *child = NULL; ++ ++ WARN_ON_ONCE(device_for_each_child(&shost->shost_gendev, &child, ++ find_child_rport) < 0); ++ return child ? dev_to_rport(child) : NULL; + } + + /** +@@ -637,7 +654,8 @@ static enum blk_eh_timer_return srp_timed_out(struct scsi_cmnd *scmd) + struct srp_rport *rport = shost_to_rport(shost); + + pr_debug("timeout for sdev %s\n", dev_name(&sdev->sdev_gendev)); +- return rport->fast_io_fail_tmo < 0 && rport->dev_loss_tmo < 0 && ++ return rport && rport->fast_io_fail_tmo < 0 && ++ rport->dev_loss_tmo < 0 && + i->f->reset_timer_if_blocked && scsi_device_blocked(sdev) ? + BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED; + } +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 32cadca198b2..e7a051386b32 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -33,7 +33,7 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *); + static void cp210x_close(struct usb_serial_port *); + static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *); + static void cp210x_get_termios_port(struct usb_serial_port *port, +- unsigned int *cflagp, unsigned int *baudp); ++ tcflag_t *cflagp, unsigned int *baudp); + static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, + struct ktermios *); + static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, +@@ -515,7 +515,7 @@ static void cp210x_get_termios(struct tty_struct *tty, + &tty->termios.c_cflag, &baud); + tty_encode_baud_rate(tty, baud, baud); + } else { +- unsigned int cflag; ++ tcflag_t cflag; + cflag = 0; + cp210x_get_termios_port(port, &cflag, &baud); + } +@@ -526,10 +526,11 @@ static void cp210x_get_termios(struct tty_struct *tty, + * This is the heart of cp210x_get_termios which always uses a &usb_serial_port. + */ + static void cp210x_get_termios_port(struct usb_serial_port *port, +- unsigned int *cflagp, unsigned int *baudp) ++ tcflag_t *cflagp, unsigned int *baudp) + { + struct device *dev = &port->dev; +- unsigned int cflag, modem_ctl[4]; ++ tcflag_t cflag; ++ unsigned int modem_ctl[4]; + unsigned int baud; + unsigned int bits; + +diff --git a/fs/aio.c b/fs/aio.c +index 4efaf29354a6..c283eb03cb38 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -628,9 +628,8 @@ static void free_ioctx_users(struct percpu_ref *ref) + while (!list_empty(&ctx->active_reqs)) { + req = list_first_entry(&ctx->active_reqs, + struct aio_kiocb, ki_list); +- +- list_del_init(&req->ki_list); + kiocb_cancel(req); ++ list_del_init(&req->ki_list); + } + + spin_unlock_irq(&ctx->ctx_lock); +diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c +index e1e7fe3b5424..b663b756f552 100644 +--- a/fs/xfs/libxfs/xfs_alloc.c ++++ b/fs/xfs/libxfs/xfs_alloc.c +@@ -1923,6 +1923,93 @@ xfs_alloc_space_available( + return true; + } + ++/* ++ * Check the agfl fields of the agf for inconsistency or corruption. The purpose ++ * is to detect an agfl header padding mismatch between current and early v5 ++ * kernels. This problem manifests as a 1-slot size difference between the ++ * on-disk flcount and the active [first, last] range of a wrapped agfl. This ++ * may also catch variants of agfl count corruption unrelated to padding. Either ++ * way, we'll reset the agfl and warn the user. ++ * ++ * Return true if a reset is required before the agfl can be used, false ++ * otherwise. ++ */ ++static bool ++xfs_agfl_needs_reset( ++ struct xfs_mount *mp, ++ struct xfs_agf *agf) ++{ ++ uint32_t f = be32_to_cpu(agf->agf_flfirst); ++ uint32_t l = be32_to_cpu(agf->agf_fllast); ++ uint32_t c = be32_to_cpu(agf->agf_flcount); ++ int agfl_size = XFS_AGFL_SIZE(mp); ++ int active; ++ ++ /* no agfl header on v4 supers */ ++ if (!xfs_sb_version_hascrc(&mp->m_sb)) ++ return false; ++ ++ /* ++ * The agf read verifier catches severe corruption of these fields. ++ * Repeat some sanity checks to cover a packed -> unpacked mismatch if ++ * the verifier allows it. ++ */ ++ if (f >= agfl_size || l >= agfl_size) ++ return true; ++ if (c > agfl_size) ++ return true; ++ ++ /* ++ * Check consistency between the on-disk count and the active range. An ++ * agfl padding mismatch manifests as an inconsistent flcount. ++ */ ++ if (c && l >= f) ++ active = l - f + 1; ++ else if (c) ++ active = agfl_size - f + l + 1; ++ else ++ active = 0; ++ ++ return active != c; ++} ++ ++/* ++ * Reset the agfl to an empty state. Ignore/drop any existing blocks since the ++ * agfl content cannot be trusted. Warn the user that a repair is required to ++ * recover leaked blocks. ++ * ++ * The purpose of this mechanism is to handle filesystems affected by the agfl ++ * header padding mismatch problem. A reset keeps the filesystem online with a ++ * relatively minor free space accounting inconsistency rather than suffer the ++ * inevitable crash from use of an invalid agfl block. ++ */ ++static void ++xfs_agfl_reset( ++ struct xfs_trans *tp, ++ struct xfs_buf *agbp, ++ struct xfs_perag *pag) ++{ ++ struct xfs_mount *mp = tp->t_mountp; ++ struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); ++ ++ ASSERT(pag->pagf_agflreset); ++ trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_); ++ ++ xfs_warn(mp, ++ "WARNING: Reset corrupted AGFL on AG %u. %d blocks leaked. " ++ "Please unmount and run xfs_repair.", ++ pag->pag_agno, pag->pagf_flcount); ++ ++ agf->agf_flfirst = 0; ++ agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); ++ agf->agf_flcount = 0; ++ xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLLAST | ++ XFS_AGF_FLCOUNT); ++ ++ pag->pagf_flcount = 0; ++ pag->pagf_agflreset = false; ++} ++ + /* + * Decide whether to use this allocation group for this allocation. + * If so, fix up the btree freelist's size. +@@ -1983,6 +2070,10 @@ xfs_alloc_fix_freelist( + } + } + ++ /* reset a padding mismatched agfl before final free space check */ ++ if (pag->pagf_agflreset) ++ xfs_agfl_reset(tp, agbp, pag); ++ + /* If there isn't enough total space or single-extent, reject it. */ + need = xfs_alloc_min_freelist(mp, pag); + if (!xfs_alloc_space_available(args, need, flags)) +@@ -2121,6 +2212,7 @@ xfs_alloc_get_freelist( + agf->agf_flfirst = 0; + + pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); ++ ASSERT(!pag->pagf_agflreset); + be32_add_cpu(&agf->agf_flcount, -1); + xfs_trans_agflist_delta(tp, -1); + pag->pagf_flcount--; +@@ -2226,6 +2318,7 @@ xfs_alloc_put_freelist( + agf->agf_fllast = 0; + + pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); ++ ASSERT(!pag->pagf_agflreset); + be32_add_cpu(&agf->agf_flcount, 1); + xfs_trans_agflist_delta(tp, 1); + pag->pagf_flcount++; +@@ -2417,6 +2510,7 @@ xfs_alloc_read_agf( + pag->pagb_count = 0; + pag->pagb_tree = RB_ROOT; + pag->pagf_init = 1; ++ pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf); + } + #ifdef DEBUG + else if (!XFS_FORCED_SHUTDOWN(mp)) { +diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h +index b57098481c10..ae3e52749f20 100644 +--- a/fs/xfs/xfs_mount.h ++++ b/fs/xfs/xfs_mount.h +@@ -278,6 +278,7 @@ typedef struct xfs_perag { + char pagi_inodeok; /* The agi is ok for inodes */ + __uint8_t pagf_levels[XFS_BTNUM_AGF]; + /* # of levels in bno & cnt btree */ ++ bool pagf_agflreset; /* agfl requires reset before use */ + __uint32_t pagf_flcount; /* count of blocks in freelist */ + xfs_extlen_t pagf_freeblks; /* total free blocks */ + xfs_extlen_t pagf_longest; /* longest free space */ +diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h +index 877079eb0f8f..cc6fa64821d2 100644 +--- a/fs/xfs/xfs_trace.h ++++ b/fs/xfs/xfs_trace.h +@@ -1485,7 +1485,7 @@ TRACE_EVENT(xfs_trans_commit_lsn, + __entry->lsn) + ); + +-TRACE_EVENT(xfs_agf, ++DECLARE_EVENT_CLASS(xfs_agf_class, + TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, + unsigned long caller_ip), + TP_ARGS(mp, agf, flags, caller_ip), +@@ -1541,6 +1541,13 @@ TRACE_EVENT(xfs_agf, + __entry->longest, + (void *)__entry->caller_ip) + ); ++#define DEFINE_AGF_EVENT(name) \ ++DEFINE_EVENT(xfs_agf_class, name, \ ++ TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, \ ++ unsigned long caller_ip), \ ++ TP_ARGS(mp, agf, flags, caller_ip)) ++DEFINE_AGF_EVENT(xfs_agf); ++DEFINE_AGF_EVENT(xfs_agfl_reset); + + TRACE_EVENT(xfs_free_extent, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, +diff --git a/include/linux/tcp.h b/include/linux/tcp.h +index 2260f92f1492..5b6df1a8dc74 100644 +--- a/include/linux/tcp.h ++++ b/include/linux/tcp.h +@@ -324,7 +324,7 @@ struct tcp_sock { + + /* Receiver queue space */ + struct { +- int space; ++ u32 space; + u32 seq; + u32 time; + } rcvq_space; +diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h +index f4227173b5d8..d3aea4f10faf 100644 +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2195,7 +2195,7 @@ enum nl80211_attrs { + #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS + #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS + +-#define NL80211_WIPHY_NAME_MAXLEN 128 ++#define NL80211_WIPHY_NAME_MAXLEN 64 + + #define NL80211_MAX_SUPP_RATES 32 + #define NL80211_MAX_SUPP_HT_RATES 77 +diff --git a/init/Kconfig b/init/Kconfig +index ef2f97dc6010..47b0bdcf33c2 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1308,6 +1308,17 @@ source "usr/Kconfig" + + endif + ++choice ++ prompt "Compiler optimization level" ++ default CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE ++ ++config CC_OPTIMIZE_FOR_PERFORMANCE ++ bool "Optimize for performance" ++ help ++ This is the default optimization level for the kernel, building ++ with the "-O2" compiler flag for best performance and most ++ helpful compile-time warnings. ++ + config CC_OPTIMIZE_FOR_SIZE + bool "Optimize for size" + help +@@ -1316,6 +1327,8 @@ config CC_OPTIMIZE_FOR_SIZE + + If unsure, say N. + ++endchoice ++ + config SYSCTL + bool + +diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c +index 42a4009fd75a..2172dd61577e 100644 +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -469,9 +469,10 @@ clear_event_triggers(struct trace_array *tr) + struct trace_event_file *file; + + list_for_each_entry(file, &tr->events, list) { +- struct event_trigger_data *data; +- list_for_each_entry_rcu(data, &file->triggers, list) { ++ struct event_trigger_data *data, *n; ++ list_for_each_entry_safe(data, n, &file->triggers, list) { + trace_event_trigger_enable_disable(file, 0); ++ list_del_rcu(&data->list); + if (data->ops->free) + data->ops->free(data->ops, data); + } +diff --git a/mm/vmscan.c b/mm/vmscan.c +index b58ca729f20a..76853088f66b 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -1331,7 +1331,7 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode) + return ret; + + mapping = page_mapping(page); +- migrate_dirty = mapping && mapping->a_ops->migratepage; ++ migrate_dirty = !mapping || mapping->a_ops->migratepage; + unlock_page(page); + if (!migrate_dirty) + return ret; +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index ed018760502e..23b95aead897 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -557,8 +557,8 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk, + void tcp_rcv_space_adjust(struct sock *sk) + { + struct tcp_sock *tp = tcp_sk(sk); ++ u32 copied; + int time; +- int copied; + + time = tcp_time_stamp - tp->rcvq_space.time; + if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0) +@@ -580,12 +580,13 @@ void tcp_rcv_space_adjust(struct sock *sk) + + if (sysctl_tcp_moderate_rcvbuf && + !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) { +- int rcvwin, rcvmem, rcvbuf; ++ int rcvmem, rcvbuf; ++ u64 rcvwin; + + /* minimal window to cope with packet losses, assuming + * steady state. Add some cushion because of small variations. + */ +- rcvwin = (copied << 1) + 16 * tp->advmss; ++ rcvwin = ((u64)copied << 1) + 16 * tp->advmss; + + /* If rate increased by 25%, + * assume slow start, rcvwin = 3 * copied +@@ -605,7 +606,8 @@ void tcp_rcv_space_adjust(struct sock *sk) + while (tcp_win_from_space(rcvmem) < tp->advmss) + rcvmem += 128; + +- rcvbuf = min(rcvwin / tp->advmss * rcvmem, sysctl_tcp_rmem[2]); ++ do_div(rcvwin, tp->advmss); ++ rcvbuf = min_t(u64, rcvwin * rcvmem, sysctl_tcp_rmem[2]); + if (rcvbuf > sk->sk_rcvbuf) { + sk->sk_rcvbuf = rcvbuf; + +diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c +index 8da7c91b725d..c36b98b07d6b 100644 +--- a/security/integrity/ima/ima_appraise.c ++++ b/security/integrity/ima/ima_appraise.c +@@ -383,14 +383,10 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, + result = ima_protect_xattr(dentry, xattr_name, xattr_value, + xattr_value_len); + if (result == 1) { +- bool digsig; +- + if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) + return -EINVAL; +- digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG); +- if (!digsig && (ima_appraise & IMA_APPRAISE_ENFORCE)) +- return -EPERM; +- ima_reset_appraise_flags(d_backing_inode(dentry), digsig); ++ ima_reset_appraise_flags(d_backing_inode(dentry), ++ (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); + result = 0; + } + return result; +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index 23dca68ffe25..0a258c0602d1 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -1441,7 +1441,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, + scontext_len, &context, def_sid); + if (rc == -EINVAL && force) { + context.str = str; +- context.len = scontext_len; ++ context.len = strlen(str) + 1; + str = NULL; + } else if (rc) + goto out_unlock; +diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c +index 1636a1eeb002..be1b69c63bdf 100644 +--- a/sound/soc/intel/common/sst-firmware.c ++++ b/sound/soc/intel/common/sst-firmware.c +@@ -260,7 +260,6 @@ int sst_dma_new(struct sst_dsp *sst) + struct sst_pdata *sst_pdata = sst->pdata; + struct sst_dma *dma; + struct resource mem; +- const char *dma_dev_name; + int ret = 0; + + if (sst->pdata->resindex_dma_base == -1) +@@ -271,7 +270,6 @@ int sst_dma_new(struct sst_dsp *sst) + * is attached to the ADSP IP. */ + switch (sst->pdata->dma_engine) { + case SST_DMA_TYPE_DW: +- dma_dev_name = "dw_dmac"; + break; + default: + dev_err(sst->dev, "error: invalid DMA engine %d\n", diff --git a/patch/kernel/rockchip-default/04-patch-4.4.136-137.patch b/patch/kernel/rockchip-default/04-patch-4.4.136-137.patch new file mode 100644 index 000000000..6be99859e --- /dev/null +++ b/patch/kernel/rockchip-default/04-patch-4.4.136-137.patch @@ -0,0 +1,625 @@ +diff --git a/Documentation/networking/netdev-FAQ.txt b/Documentation/networking/netdev-FAQ.txt +index 0fe1c6e0dbcd..bfc6b3e68cc4 100644 +--- a/Documentation/networking/netdev-FAQ.txt ++++ b/Documentation/networking/netdev-FAQ.txt +@@ -168,6 +168,15 @@ A: No. See above answer. In short, if you think it really belongs in + dash marker line as described in Documentation/SubmittingPatches to + temporarily embed that information into the patch that you send. + ++Q: Are all networking bug fixes backported to all stable releases? ++ ++A: Due to capacity, Dave could only take care of the backports for the last ++ 2 stable releases. For earlier stable releases, each stable branch maintainer ++ is supposed to take care of them. If you find any patch is missing from an ++ earlier stable branch, please notify stable@vger.kernel.org with either a ++ commit ID or a formal patch backported, and CC Dave and other relevant ++ networking developers. ++ + Q: Someone said that the comment style and coding convention is different + for the networking content. Is this true? + +diff --git a/Makefile b/Makefile +index a05a7a005715..44efd1252ab8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 136 ++SUBLEVEL = 137 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c +index a0d9ac6b6cc9..e759100e41a7 100644 +--- a/drivers/char/tpm/tpm-chip.c ++++ b/drivers/char/tpm/tpm-chip.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include "tpm.h" + #include "tpm_eventlog.h" + +@@ -324,8 +325,20 @@ static void tpm1_chip_unregister(struct tpm_chip *chip) + */ + int tpm_chip_register(struct tpm_chip *chip) + { ++#ifdef CONFIG_OF ++ struct device_node *np; ++#endif + int rc; + ++#ifdef CONFIG_OF ++ np = of_find_node_by_name(NULL, "vtpm"); ++ if (np) { ++ if (of_property_read_bool(np, "powered-while-suspended")) ++ chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; ++ } ++ of_node_put(np); ++#endif ++ + rc = tpm1_chip_register(chip); + if (rc) + return rc; +diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c +index 36afc1a21699..95a40ec854ad 100644 +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -787,6 +787,10 @@ int tpm_do_selftest(struct tpm_chip *chip) + loops = jiffies_to_msecs(duration) / delay_msec; + + rc = tpm_continue_selftest(chip); ++ if (rc == TPM_ERR_INVALID_POSTINIT) { ++ chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; ++ dev_info(&chip->dev, "TPM not ready (%d)\n", rc); ++ } + /* This may fail if there was no TPM driver during a suspend/resume + * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST) + */ +@@ -931,6 +935,9 @@ int tpm_pm_suspend(struct device *dev) + if (chip == NULL) + return -ENODEV; + ++ if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) ++ return 0; ++ + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + tpm2_shutdown(chip, TPM2_SU_STATE); + return 0; +diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h +index 772d99b3a8e4..36e1abda00f9 100644 +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -168,6 +168,7 @@ struct tpm_vendor_specific { + enum tpm_chip_flags { + TPM_CHIP_FLAG_REGISTERED = BIT(0), + TPM_CHIP_FLAG_TPM2 = BIT(1), ++ TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), + }; + + struct tpm_chip { +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 6b5625e66119..88ceac091454 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -209,6 +209,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) + return -ENOMEM; + + filp->private_data = priv; ++ filp->f_mode |= FMODE_UNSIGNED_OFFSET; + priv->filp = filp; + priv->uid = current_euid(); + priv->pid = get_pid(task_pid(current)); +diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c +index d91dd580e978..37aaea88a6ad 100644 +--- a/drivers/isdn/hardware/eicon/diva.c ++++ b/drivers/isdn/hardware/eicon/diva.c +@@ -387,10 +387,10 @@ void divasa_xdi_driver_unload(void) + ** Receive and process command from user mode utility + */ + void *diva_xdi_open_adapter(void *os_handle, const void __user *src, +- int length, ++ int length, void *mptr, + divas_xdi_copy_from_user_fn_t cp_fn) + { +- diva_xdi_um_cfg_cmd_t msg; ++ diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr; + diva_os_xdi_adapter_t *a = NULL; + diva_os_spin_lock_magic_t old_irql; + struct list_head *tmp; +@@ -400,21 +400,21 @@ void *diva_xdi_open_adapter(void *os_handle, const void __user *src, + length, sizeof(diva_xdi_um_cfg_cmd_t))) + return NULL; + } +- if ((*cp_fn) (os_handle, &msg, src, sizeof(msg)) <= 0) { ++ if ((*cp_fn) (os_handle, msg, src, sizeof(*msg)) <= 0) { + DBG_ERR(("A: A(?) open, write error")) + return NULL; + } + diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter"); + list_for_each(tmp, &adapter_queue) { + a = list_entry(tmp, diva_os_xdi_adapter_t, link); +- if (a->controller == (int)msg.adapter) ++ if (a->controller == (int)msg->adapter) + break; + a = NULL; + } + diva_os_leave_spin_lock(&adapter_lock, &old_irql, "open_adapter"); + + if (!a) { +- DBG_ERR(("A: A(%d) open, adapter not found", msg.adapter)) ++ DBG_ERR(("A: A(%d) open, adapter not found", msg->adapter)) + } + + return (a); +@@ -436,8 +436,10 @@ void diva_xdi_close_adapter(void *adapter, void *os_handle) + + int + diva_xdi_write(void *adapter, void *os_handle, const void __user *src, +- int length, divas_xdi_copy_from_user_fn_t cp_fn) ++ int length, void *mptr, ++ divas_xdi_copy_from_user_fn_t cp_fn) + { ++ diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr; + diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter; + void *data; + +@@ -458,7 +460,13 @@ diva_xdi_write(void *adapter, void *os_handle, const void __user *src, + return (-2); + } + +- length = (*cp_fn) (os_handle, data, src, length); ++ if (msg) { ++ *(diva_xdi_um_cfg_cmd_t *)data = *msg; ++ length = (*cp_fn) (os_handle, (char *)data + sizeof(*msg), ++ src + sizeof(*msg), length - sizeof(*msg)); ++ } else { ++ length = (*cp_fn) (os_handle, data, src, length); ++ } + if (length > 0) { + if ((*(a->interface.cmd_proc)) + (a, (diva_xdi_um_cfg_cmd_t *) data, length)) { +diff --git a/drivers/isdn/hardware/eicon/diva.h b/drivers/isdn/hardware/eicon/diva.h +index e979085d1b89..a0a607c0c32e 100644 +--- a/drivers/isdn/hardware/eicon/diva.h ++++ b/drivers/isdn/hardware/eicon/diva.h +@@ -19,10 +19,11 @@ int diva_xdi_read(void *adapter, void *os_handle, void __user *dst, + int max_length, divas_xdi_copy_to_user_fn_t cp_fn); + + int diva_xdi_write(void *adapter, void *os_handle, const void __user *src, +- int length, divas_xdi_copy_from_user_fn_t cp_fn); ++ int length, void *msg, ++ divas_xdi_copy_from_user_fn_t cp_fn); + + void *diva_xdi_open_adapter(void *os_handle, const void __user *src, +- int length, ++ int length, void *msg, + divas_xdi_copy_from_user_fn_t cp_fn); + + void diva_xdi_close_adapter(void *adapter, void *os_handle); +diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c +index a2e0ed6c9a4d..91bd2ba0bdd8 100644 +--- a/drivers/isdn/hardware/eicon/divasmain.c ++++ b/drivers/isdn/hardware/eicon/divasmain.c +@@ -591,19 +591,22 @@ static int divas_release(struct inode *inode, struct file *file) + static ssize_t divas_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { ++ diva_xdi_um_cfg_cmd_t msg; + int ret = -EINVAL; + + if (!file->private_data) { + file->private_data = diva_xdi_open_adapter(file, buf, +- count, ++ count, &msg, + xdi_copy_from_user); +- } +- if (!file->private_data) { +- return (-ENODEV); ++ if (!file->private_data) ++ return (-ENODEV); ++ ret = diva_xdi_write(file->private_data, file, ++ buf, count, &msg, xdi_copy_from_user); ++ } else { ++ ret = diva_xdi_write(file->private_data, file, ++ buf, count, NULL, xdi_copy_from_user); + } + +- ret = diva_xdi_write(file->private_data, file, +- buf, count, xdi_copy_from_user); + switch (ret) { + case -1: /* Message should be removed from rx mailbox first */ + ret = -EBUSY; +@@ -622,11 +625,12 @@ static ssize_t divas_write(struct file *file, const char __user *buf, + static ssize_t divas_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) + { ++ diva_xdi_um_cfg_cmd_t msg; + int ret = -EINVAL; + + if (!file->private_data) { + file->private_data = diva_xdi_open_adapter(file, buf, +- count, ++ count, &msg, + xdi_copy_from_user); + } + if (!file->private_data) { +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +index d946bba43726..87534c6efd66 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +@@ -594,7 +594,7 @@ static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params, + * slots for the highest priority. + */ + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS : +- NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); ++ NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /* Mapping between the CREDIT_WEIGHT registers and actual client + * numbers + */ +diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c +index 0e3b2ebf87f1..029fa5bee520 100644 +--- a/drivers/net/ethernet/cisco/enic/enic_main.c ++++ b/drivers/net/ethernet/cisco/enic/enic_main.c +@@ -2543,11 +2543,11 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + pci_set_master(pdev); + + /* Query PCI controller on system for DMA addressing +- * limitation for the device. Try 64-bit first, and ++ * limitation for the device. Try 47-bit first, and + * fail to 32-bit. + */ + +- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); ++ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(47)); + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { +@@ -2561,10 +2561,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + goto err_out_release_regions; + } + } else { +- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); ++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(47)); + if (err) { + dev_err(dev, "Unable to obtain %u-bit DMA " +- "for consistent allocations, aborting\n", 64); ++ "for consistent allocations, aborting\n", 47); + goto err_out_release_regions; + } + using_dac = 1; +diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c +index 62f1a3433a62..d6d87dd8a28f 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/qp.c ++++ b/drivers/net/ethernet/mellanox/mlx4/qp.c +@@ -386,11 +386,11 @@ struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn) + struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; + struct mlx4_qp *qp; + +- spin_lock(&qp_table->lock); ++ spin_lock_irq(&qp_table->lock); + + qp = __mlx4_qp_lookup(dev, qpn); + +- spin_unlock(&qp_table->lock); ++ spin_unlock_irq(&qp_table->lock); + return qp; + } + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c +index 7ccdb46c6764..21e0af2620ee 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c +@@ -43,7 +43,7 @@ + #define ILT_CFG_REG(cli, reg) PSWRQ2_REG_ ## cli ## _ ## reg ## _RT_OFFSET + + /* ILT entry structure */ +-#define ILT_ENTRY_PHY_ADDR_MASK 0x000FFFFFFFFFFFULL ++#define ILT_ENTRY_PHY_ADDR_MASK (~0ULL >> 12) + #define ILT_ENTRY_PHY_ADDR_SHIFT 0 + #define ILT_ENTRY_VALID_MASK 0x1ULL + #define ILT_ENTRY_VALID_SHIFT 52 +diff --git a/drivers/net/phy/bcm-cygnus.c b/drivers/net/phy/bcm-cygnus.c +index 49bbc6826883..9a7dca2bb618 100644 +--- a/drivers/net/phy/bcm-cygnus.c ++++ b/drivers/net/phy/bcm-cygnus.c +@@ -61,17 +61,17 @@ static int bcm_cygnus_afe_config(struct phy_device *phydev) + return rc; + + /* make rcal=100, since rdb default is 000 */ +- rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB1, 0x10); ++ rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB1, 0x10); + if (rc < 0) + return rc; + + /* CORE_EXPB0, Reset R_CAL/RC_CAL Engine */ +- rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB0, 0x10); ++ rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB0, 0x10); + if (rc < 0) + return rc; + + /* CORE_EXPB0, Disable Reset R_CAL/RC_CAL Engine */ +- rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB0, 0x00); ++ rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB0, 0x00); + + return 0; + } +diff --git a/drivers/net/phy/bcm-phy-lib.h b/drivers/net/phy/bcm-phy-lib.h +index b2091c88b44d..ce16b26d49ff 100644 +--- a/drivers/net/phy/bcm-phy-lib.h ++++ b/drivers/net/phy/bcm-phy-lib.h +@@ -14,11 +14,18 @@ + #ifndef _LINUX_BCM_PHY_LIB_H + #define _LINUX_BCM_PHY_LIB_H + ++#include + #include + + int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val); + int bcm_phy_read_exp(struct phy_device *phydev, u16 reg); + ++static inline int bcm_phy_write_exp_sel(struct phy_device *phydev, ++ u16 reg, u16 val) ++{ ++ return bcm_phy_write_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER, val); ++} ++ + int bcm_phy_write_misc(struct phy_device *phydev, + u16 reg, u16 chl, u16 value); + int bcm_phy_read_misc(struct phy_device *phydev, +diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c +index 03d4809a9126..bffa70e46202 100644 +--- a/drivers/net/phy/bcm7xxx.c ++++ b/drivers/net/phy/bcm7xxx.c +@@ -48,10 +48,10 @@ + static void r_rc_cal_reset(struct phy_device *phydev) + { + /* Reset R_CAL/RC_CAL Engine */ +- bcm_phy_write_exp(phydev, 0x00b0, 0x0010); ++ bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0010); + + /* Disable Reset R_AL/RC_CAL Engine */ +- bcm_phy_write_exp(phydev, 0x00b0, 0x0000); ++ bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0000); + } + + static int bcm7xxx_28nm_b0_afe_config_init(struct phy_device *phydev) +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index e74709e4b5dd..49174837c2ba 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -983,7 +983,8 @@ static void team_port_disable(struct team *team, + static void ___team_compute_features(struct team *team) + { + struct team_port *port; +- u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL; ++ netdev_features_t vlan_features = TEAM_VLAN_FEATURES & ++ NETIF_F_ALL_FOR_ALL; + unsigned short max_hard_header_len = ETH_HLEN; + unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE | + IFF_XMIT_DST_RELEASE_PERM; +diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c +index 96a5028621c8..8edbccf06b7b 100644 +--- a/drivers/net/usb/cdc_mbim.c ++++ b/drivers/net/usb/cdc_mbim.c +@@ -593,7 +593,7 @@ static const struct driver_info cdc_mbim_info_zlp = { + */ + static const struct driver_info cdc_mbim_info_ndp_to_end = { + .description = "CDC MBIM", +- .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN, ++ .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP, + .bind = cdc_mbim_bind, + .unbind = cdc_mbim_unbind, + .manage_power = cdc_mbim_manage_power, +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +index 83e5aa6a9f28..ad35e760ed3f 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -6167,7 +6167,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, + req->alpha2[0], req->alpha2[1]); + + /* ignore non-ISO3166 country codes */ +- for (i = 0; i < sizeof(req->alpha2); i++) ++ for (i = 0; i < 2; i++) + if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { + brcmf_err("not a ISO3166 code\n"); + return; +diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c +index f52c72a1a06f..73b725f965eb 100644 +--- a/fs/xfs/xfs_log.c ++++ b/fs/xfs/xfs_log.c +@@ -3323,8 +3323,6 @@ maybe_sleep: + */ + if (iclog->ic_state & XLOG_STATE_IOERROR) + return -EIO; +- if (log_flushed) +- *log_flushed = 1; + } else { + + no_sleep: +@@ -3432,8 +3430,6 @@ try_again: + + xlog_wait(&iclog->ic_prev->ic_write_wait, + &log->l_icloglock); +- if (log_flushed) +- *log_flushed = 1; + already_slept = 1; + goto try_again; + } +@@ -3467,9 +3463,6 @@ try_again: + */ + if (iclog->ic_state & XLOG_STATE_IOERROR) + return -EIO; +- +- if (log_flushed) +- *log_flushed = 1; + } else { /* just return */ + spin_unlock(&log->l_icloglock); + } +diff --git a/mm/mmap.c b/mm/mmap.c +index cc84b97ca250..39f5fbd07486 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1275,6 +1275,35 @@ static inline int mlock_future_check(struct mm_struct *mm, + return 0; + } + ++static inline u64 file_mmap_size_max(struct file *file, struct inode *inode) ++{ ++ if (S_ISREG(inode->i_mode)) ++ return MAX_LFS_FILESIZE; ++ ++ if (S_ISBLK(inode->i_mode)) ++ return MAX_LFS_FILESIZE; ++ ++ /* Special "we do even unsigned file positions" case */ ++ if (file->f_mode & FMODE_UNSIGNED_OFFSET) ++ return 0; ++ ++ /* Yes, random drivers might want more. But I'm tired of buggy drivers */ ++ return ULONG_MAX; ++} ++ ++static inline bool file_mmap_ok(struct file *file, struct inode *inode, ++ unsigned long pgoff, unsigned long len) ++{ ++ u64 maxsize = file_mmap_size_max(file, inode); ++ ++ if (maxsize && len > maxsize) ++ return false; ++ maxsize -= len; ++ if (pgoff > maxsize >> PAGE_SHIFT) ++ return false; ++ return true; ++} ++ + /* + * The caller must hold down_write(¤t->mm->mmap_sem). + */ +@@ -1340,6 +1369,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, + if (file) { + struct inode *inode = file_inode(file); + ++ if (!file_mmap_ok(file, inode, pgoff, len)) ++ return -EOVERFLOW; ++ + switch (flags & MAP_TYPE) { + case MAP_SHARED: + if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE)) +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 5b3d611d8b5f..2017ffa5197a 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1691,6 +1691,10 @@ static int do_setlink(const struct sk_buff *skb, + const struct net_device_ops *ops = dev->netdev_ops; + int err; + ++ err = validate_linkmsg(dev, tb); ++ if (err < 0) ++ return err; ++ + if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) { + struct net *net = rtnl_link_get_net(dev_net(dev), tb); + if (IS_ERR(net)) { +@@ -1982,10 +1986,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) + goto errout; + } + +- err = validate_linkmsg(dev, tb); +- if (err < 0) +- goto errout; +- + err = do_setlink(skb, dev, ifm, tb, ifname, 0); + errout: + return err; +diff --git a/net/dccp/proto.c b/net/dccp/proto.c +index ff3b058cf58c..936dab12f99f 100644 +--- a/net/dccp/proto.c ++++ b/net/dccp/proto.c +@@ -280,9 +280,7 @@ int dccp_disconnect(struct sock *sk, int flags) + + dccp_clear_xmit_timers(sk); + ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk); +- ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); + dp->dccps_hc_rx_ccid = NULL; +- dp->dccps_hc_tx_ccid = NULL; + + __skb_queue_purge(&sk->sk_receive_queue); + __skb_queue_purge(&sk->sk_write_queue); +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index 44abc52bae13..9d144cbd4e62 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -979,6 +979,8 @@ fib_convert_metrics(struct fib_info *fi, const struct fib_config *cfg) + if (val == TCP_CA_UNSPEC) + return -EINVAL; + } else { ++ if (nla_len(nla) != sizeof(u32)) ++ return false; + val = nla_get_u32(nla); + } + if (type == RTAX_ADVMSS && val > 65535 - 40) +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +index 1b93ea766916..ce9a7fbb7c5f 100644 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -493,8 +493,6 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) + int err; + int copied; + +- WARN_ON_ONCE(sk->sk_family == AF_INET6); +- + err = -EAGAIN; + skb = sock_dequeue_err_skb(sk); + if (!skb) +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index e5846d1f9b55..9b92960f024d 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -1787,7 +1787,8 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns + ret = 0; + if (!ip6mr_new_table(net, v)) + ret = -ENOMEM; +- raw6_sk(sk)->ip6mr_table = v; ++ else ++ raw6_sk(sk)->ip6mr_table = v; + rtnl_unlock(); + return ret; + } +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 392d4e2c0a24..3a63f33698d3 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2779,7 +2779,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + if (unlikely(offset < 0)) + goto out_free; + } else if (reserve) { +- skb_push(skb, reserve); ++ skb_reserve(skb, -reserve); + } + + /* Returns -EFAULT on error */ +@@ -4198,7 +4198,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + goto out; + if (po->tp_version >= TPACKET_V3 && + req->tp_block_size <= +- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) ++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr)) + goto out; + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) +diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c +index dd243d2abd87..138d7f100f7e 100644 +--- a/scripts/kconfig/confdata.c ++++ b/scripts/kconfig/confdata.c +@@ -743,7 +743,7 @@ int conf_write(const char *name) + struct menu *menu; + const char *basename; + const char *str; +- char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; ++ char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; + char *env; + + dirname[0] = 0; diff --git a/patch/kernel/rockchip-default/04-patch-4.4.137-138.patch b/patch/kernel/rockchip-default/04-patch-4.4.137-138.patch new file mode 100644 index 000000000..3fb702177 --- /dev/null +++ b/patch/kernel/rockchip-default/04-patch-4.4.137-138.patch @@ -0,0 +1,1561 @@ +diff --git a/Makefile b/Makefile +index 44efd1252ab8..1a8c0fc6b997 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 137 ++SUBLEVEL = 138 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c +index 722bacea040e..8baaff5af0b5 100644 +--- a/arch/x86/crypto/chacha20_glue.c ++++ b/arch/x86/crypto/chacha20_glue.c +@@ -125,7 +125,7 @@ static struct crypto_alg alg = { + + static int __init chacha20_simd_mod_init(void) + { +- if (!cpu_has_ssse3) ++ if (!boot_cpu_has(X86_FEATURE_SSSE3)) + return -ENODEV; + + #ifdef CONFIG_AS_AVX2 +diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c +index 81a595d75cf5..15f5c7675d42 100644 +--- a/arch/x86/crypto/crc32c-intel_glue.c ++++ b/arch/x86/crypto/crc32c-intel_glue.c +@@ -58,16 +58,11 @@ + asmlinkage unsigned int crc_pcl(const u8 *buffer, int len, + unsigned int crc_init); + static int crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_EAGERFPU; +-#if defined(X86_FEATURE_EAGER_FPU) + #define set_pcl_breakeven_point() \ + do { \ + if (!use_eager_fpu()) \ + crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU; \ + } while (0) +-#else +-#define set_pcl_breakeven_point() \ +- (crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU) +-#endif + #endif /* CONFIG_X86_64 */ + + static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length) +@@ -257,7 +252,7 @@ static int __init crc32c_intel_mod_init(void) + if (!x86_match_cpu(crc32c_cpu_id)) + return -ENODEV; + #ifdef CONFIG_X86_64 +- if (cpu_has_pclmulqdq) { ++ if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) { + alg.update = crc32c_pcl_intel_update; + alg.finup = crc32c_pcl_intel_finup; + alg.digest = crc32c_pcl_intel_digest; +diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h +index f7e142926481..e4959d023af8 100644 +--- a/arch/x86/include/asm/cmpxchg_32.h ++++ b/arch/x86/include/asm/cmpxchg_32.h +@@ -109,6 +109,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new) + + #endif + +-#define system_has_cmpxchg_double() cpu_has_cx8 ++#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8) + + #endif /* _ASM_X86_CMPXCHG_32_H */ +diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h +index 1af94697aae5..caa23a34c963 100644 +--- a/arch/x86/include/asm/cmpxchg_64.h ++++ b/arch/x86/include/asm/cmpxchg_64.h +@@ -18,6 +18,6 @@ static inline void set_64bit(volatile u64 *ptr, u64 val) + cmpxchg_local((ptr), (o), (n)); \ + }) + +-#define system_has_cmpxchg_double() cpu_has_cx16 ++#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX16) + + #endif /* _ASM_X86_CMPXCHG_64_H */ +diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h +index 641f0f2c2982..232621c5e859 100644 +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -104,7 +104,7 @@ + #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ + #define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ + #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ +-#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ ++/* free, was #define X86_FEATURE_EAGER_FPU ( 3*32+29) * "eagerfpu" Non lazy FPU restore */ + #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +@@ -368,58 +368,29 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; + #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) + + #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) +-#define cpu_has_de boot_cpu_has(X86_FEATURE_DE) + #define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) + #define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) + #define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) + #define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) +-#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) +-#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) +-#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) + #define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) + #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) + #define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) +-#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) +-#define cpu_has_ssse3 boot_cpu_has(X86_FEATURE_SSSE3) + #define cpu_has_aes boot_cpu_has(X86_FEATURE_AES) + #define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX) + #define cpu_has_avx2 boot_cpu_has(X86_FEATURE_AVX2) +-#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) +-#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) +-#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) +-#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) +-#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) +-#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) +-#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2) +-#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN) +-#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE) +-#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) +-#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) +-#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) +-#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) +-#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) + #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH) +-#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) + #define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES) + #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) + #define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT) +-#define cpu_has_xmm4_1 boot_cpu_has(X86_FEATURE_XMM4_1) +-#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) + #define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) + #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) +-#define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT) + #define cpu_has_xsaves boot_cpu_has(X86_FEATURE_XSAVES) + #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) + #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) +-#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) +-#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) +-#define cpu_has_perfctr_nb boot_cpu_has(X86_FEATURE_PERFCTR_NB) +-#define cpu_has_perfctr_l2 boot_cpu_has(X86_FEATURE_PERFCTR_L2) +-#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) +-#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) +-#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) +-#define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) +-#define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT) ++/* ++ * Do not add any more of those clumsy macros - use static_cpu_has_safe() for ++ * fast paths and boot_cpu_has() otherwise! ++ */ + + #if __GNUC__ >= 4 + extern void warn_pre_alternatives(void); +diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h +index 3c3550c3a4a3..146d838e6ee7 100644 +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -42,6 +42,7 @@ extern void fpu__init_cpu_xstate(void); + extern void fpu__init_system(struct cpuinfo_x86 *c); + extern void fpu__init_check_bugs(void); + extern void fpu__resume_cpu(void); ++extern u64 fpu__get_supported_xfeatures_mask(void); + + /* + * Debugging facility: +@@ -57,7 +58,7 @@ extern void fpu__resume_cpu(void); + */ + static __always_inline __pure bool use_eager_fpu(void) + { +- return static_cpu_has_safe(X86_FEATURE_EAGER_FPU); ++ return true; + } + + static __always_inline __pure bool use_xsaveopt(void) +@@ -595,7 +596,8 @@ switch_fpu_prepare(struct fpu *old_fpu, struct fpu *new_fpu, int cpu) + * If the task has used the math, pre-load the FPU on xsave processors + * or if the past 5 consecutive context-switches used math. + */ +- fpu.preload = new_fpu->fpstate_active && ++ fpu.preload = static_cpu_has(X86_FEATURE_FPU) && ++ new_fpu->fpstate_active && + (use_eager_fpu() || new_fpu->counter > 5); + + if (old_fpu->fpregs_active) { +diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h +index 3a6c89b70307..f23cd8c80b1c 100644 +--- a/arch/x86/include/asm/fpu/xstate.h ++++ b/arch/x86/include/asm/fpu/xstate.h +@@ -22,7 +22,7 @@ + #define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \ + XFEATURE_MASK_SSE | \ + XFEATURE_MASK_YMM | \ +- XFEATURE_MASK_OPMASK | \ ++ XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_ZMM_Hi256 | \ + XFEATURE_MASK_Hi16_ZMM) + +diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h +index fc3c7e49c8e4..ae357d0afc91 100644 +--- a/arch/x86/include/asm/kvm_emulate.h ++++ b/arch/x86/include/asm/kvm_emulate.h +@@ -105,11 +105,12 @@ struct x86_emulate_ops { + * @addr: [IN ] Linear address from which to read. + * @val: [OUT] Value read from memory, zero-extended to 'u_long'. + * @bytes: [IN ] Number of bytes to read from memory. ++ * @system:[IN ] Whether the access is forced to be at CPL0. + */ + int (*read_std)(struct x86_emulate_ctxt *ctxt, + unsigned long addr, void *val, + unsigned int bytes, +- struct x86_exception *fault); ++ struct x86_exception *fault, bool system); + + /* + * read_phys: Read bytes of standard (non-emulated/special) memory. +@@ -127,10 +128,11 @@ struct x86_emulate_ops { + * @addr: [IN ] Linear address to which to write. + * @val: [OUT] Value write to memory, zero-extended to 'u_long'. + * @bytes: [IN ] Number of bytes to write to memory. ++ * @system:[IN ] Whether the access is forced to be at CPL0. + */ + int (*write_std)(struct x86_emulate_ctxt *ctxt, + unsigned long addr, void *val, unsigned int bytes, +- struct x86_exception *fault); ++ struct x86_exception *fault, bool system); + /* + * fetch: Read bytes of standard (non-emulated/special) memory. + * Used for instruction fetch. +diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h +index 222a6a3ca2b5..a438c5598a90 100644 +--- a/arch/x86/include/asm/smp.h ++++ b/arch/x86/include/asm/smp.h +@@ -21,15 +21,6 @@ + extern int smp_num_siblings; + extern unsigned int num_processors; + +-static inline bool cpu_has_ht_siblings(void) +-{ +- bool has_siblings = false; +-#ifdef CONFIG_SMP +- has_siblings = cpu_has_ht && smp_num_siblings > 1; +-#endif +- return has_siblings; +-} +- + DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); + DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); + /* cpus sharing the last level cache: */ +diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h +index 5a08bc8bff33..c54beb44c4c1 100644 +--- a/arch/x86/include/asm/xor_32.h ++++ b/arch/x86/include/asm/xor_32.h +@@ -553,7 +553,7 @@ do { \ + if (cpu_has_xmm) { \ + xor_speed(&xor_block_pIII_sse); \ + xor_speed(&xor_block_sse_pf64); \ +- } else if (cpu_has_mmx) { \ ++ } else if (boot_cpu_has(X86_FEATURE_MMX)) { \ + xor_speed(&xor_block_pII_mmx); \ + xor_speed(&xor_block_p5_mmx); \ + } else { \ +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 4bf9e77f3e05..f4fb8f5b0be4 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -304,7 +304,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c) + int cpu = smp_processor_id(); + + /* get information required for multi-node processors */ +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + u32 eax, ebx, ecx, edx; + + cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); +@@ -954,7 +954,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) + + void set_dr_addr_mask(unsigned long mask, int dr) + { +- if (!cpu_has_bpext) ++ if (!boot_cpu_has(X86_FEATURE_BPEXT)) + return; + + switch (dr) { +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index 8eabbafff213..0498ad3702f5 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -1539,7 +1539,9 @@ void cpu_init(void) + + printk(KERN_INFO "Initializing CPU#%d\n", cpu); + +- if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || cpu_has_de) ++ if (cpu_feature_enabled(X86_FEATURE_VME) || ++ cpu_has_tsc || ++ boot_cpu_has(X86_FEATURE_DE)) + cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); + + load_current_idt(); +diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c +index 209ac1e7d1f0..565648bc1a0a 100644 +--- a/arch/x86/kernel/cpu/intel.c ++++ b/arch/x86/kernel/cpu/intel.c +@@ -445,7 +445,8 @@ static void init_intel(struct cpuinfo_x86 *c) + + if (cpu_has_xmm2) + set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); +- if (cpu_has_ds) { ++ ++ if (boot_cpu_has(X86_FEATURE_DS)) { + unsigned int l1; + rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<11))) +diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c +index b4ca91cf55b0..3fa72317ad78 100644 +--- a/arch/x86/kernel/cpu/intel_cacheinfo.c ++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c +@@ -591,7 +591,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) + unsigned edx; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- if (cpu_has_topoext) ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) + cpuid_count(0x8000001d, index, &eax.full, + &ebx.full, &ecx.full, &edx); + else +@@ -637,7 +637,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) + void init_amd_cacheinfo(struct cpuinfo_x86 *c) + { + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + num_cache_leaves = find_num_cache_leaves(c); + } else if (c->extended_cpuid_level >= 0x80000006) { + if (cpuid_edx(0x80000006) & 0xf000) +@@ -809,7 +809,7 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, + struct cacheinfo *this_leaf; + int i, sibling; + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + unsigned int apicid, nshared, first, last; + + this_leaf = this_cpu_ci->info_list + index; +diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c +index b5624fafa44a..136ae86f4f5f 100644 +--- a/arch/x86/kernel/cpu/mtrr/generic.c ++++ b/arch/x86/kernel/cpu/mtrr/generic.c +@@ -349,7 +349,7 @@ static void get_fixed_ranges(mtrr_type *frs) + + void mtrr_save_fixed_ranges(void *info) + { +- if (cpu_has_mtrr) ++ if (boot_cpu_has(X86_FEATURE_MTRR)) + get_fixed_ranges(mtrr_state.fixed_ranges); + } + +diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c +index fa77ac8291f0..f924f41af89a 100644 +--- a/arch/x86/kernel/cpu/mtrr/main.c ++++ b/arch/x86/kernel/cpu/mtrr/main.c +@@ -682,7 +682,7 @@ void __init mtrr_bp_init(void) + + phys_addr = 32; + +- if (cpu_has_mtrr) { ++ if (boot_cpu_has(X86_FEATURE_MTRR)) { + mtrr_if = &generic_mtrr_ops; + size_or_mask = SIZE_OR_MASK_BITS(36); + size_and_mask = 0x00f00000; +diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c +index 1cee5d2d7ece..3ea177cb7366 100644 +--- a/arch/x86/kernel/cpu/perf_event_amd.c ++++ b/arch/x86/kernel/cpu/perf_event_amd.c +@@ -160,7 +160,7 @@ static inline int amd_pmu_addr_offset(int index, bool eventsel) + if (offset) + return offset; + +- if (!cpu_has_perfctr_core) ++ if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) + offset = index; + else + offset = index << 1; +@@ -652,7 +652,7 @@ static __initconst const struct x86_pmu amd_pmu = { + + static int __init amd_core_pmu_init(void) + { +- if (!cpu_has_perfctr_core) ++ if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) + return 0; + + switch (boot_cpu_data.x86) { +diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/kernel/cpu/perf_event_amd_uncore.c +index cc6cedb8f25d..49742746a6c9 100644 +--- a/arch/x86/kernel/cpu/perf_event_amd_uncore.c ++++ b/arch/x86/kernel/cpu/perf_event_amd_uncore.c +@@ -523,10 +523,10 @@ static int __init amd_uncore_init(void) + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + goto fail_nodev; + +- if (!cpu_has_topoext) ++ if (!boot_cpu_has(X86_FEATURE_TOPOEXT)) + goto fail_nodev; + +- if (cpu_has_perfctr_nb) { ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) { + amd_uncore_nb = alloc_percpu(struct amd_uncore *); + if (!amd_uncore_nb) { + ret = -ENOMEM; +@@ -540,7 +540,7 @@ static int __init amd_uncore_init(void) + ret = 0; + } + +- if (cpu_has_perfctr_l2) { ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) { + amd_uncore_l2 = alloc_percpu(struct amd_uncore *); + if (!amd_uncore_l2) { + ret = -ENOMEM; +@@ -583,10 +583,11 @@ fail_online: + + /* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */ + amd_uncore_nb = amd_uncore_l2 = NULL; +- if (cpu_has_perfctr_l2) ++ ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) + perf_pmu_unregister(&amd_l2_pmu); + fail_l2: +- if (cpu_has_perfctr_nb) ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) + perf_pmu_unregister(&amd_nb_pmu); + if (amd_uncore_l2) + free_percpu(amd_uncore_l2); +diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c +index d25097c3fc1d..6aa0b519c851 100644 +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -114,6 +114,10 @@ void __kernel_fpu_begin(void) + kernel_fpu_disable(); + + if (fpu->fpregs_active) { ++ /* ++ * Ignore return value -- we don't care if reg state ++ * is clobbered. ++ */ + copy_fpregs_to_fpstate(fpu); + } else { + this_cpu_write(fpu_fpregs_owner_ctx, NULL); +@@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu) + + preempt_disable(); + if (fpu->fpregs_active) { +- if (!copy_fpregs_to_fpstate(fpu)) +- fpregs_deactivate(fpu); ++ if (!copy_fpregs_to_fpstate(fpu)) { ++ if (use_eager_fpu()) ++ copy_kernel_to_fpregs(&fpu->state); ++ else ++ fpregs_deactivate(fpu); ++ } + } + preempt_enable(); + } +@@ -259,7 +267,11 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu) + preempt_disable(); + if (!copy_fpregs_to_fpstate(dst_fpu)) { + memcpy(&src_fpu->state, &dst_fpu->state, xstate_size); +- fpregs_deactivate(src_fpu); ++ ++ if (use_eager_fpu()) ++ copy_kernel_to_fpregs(&src_fpu->state); ++ else ++ fpregs_deactivate(src_fpu); + } + preempt_enable(); + } +@@ -409,8 +421,10 @@ static inline void copy_init_fpstate_to_fpregs(void) + { + if (use_xsave()) + copy_kernel_to_xregs(&init_fpstate.xsave, -1); +- else ++ else if (static_cpu_has(X86_FEATURE_FXSR)) + copy_kernel_to_fxregs(&init_fpstate.fxsave); ++ else ++ copy_kernel_to_fregs(&init_fpstate.fsave); + } + + /* +@@ -423,7 +437,7 @@ void fpu__clear(struct fpu *fpu) + { + WARN_ON_FPU(fpu != ¤t->thread.fpu); /* Almost certainly an anomaly */ + +- if (!use_eager_fpu()) { ++ if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) { + /* FPU state will be reallocated lazily at the first use. */ + fpu__drop(fpu); + } else { +diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c +index 1011c05b1bd5..954517285fa2 100644 +--- a/arch/x86/kernel/fpu/init.c ++++ b/arch/x86/kernel/fpu/init.c +@@ -3,8 +3,11 @@ + */ + #include + #include ++#include ++#include + + #include ++#include + + /* + * Initialize the TS bit in CR0 according to the style of context-switches +@@ -12,10 +15,7 @@ + */ + static void fpu__init_cpu_ctx_switch(void) + { +- if (!cpu_has_eager_fpu) +- stts(); +- else +- clts(); ++ clts(); + } + + /* +@@ -75,13 +75,15 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) + cr0 &= ~(X86_CR0_TS | X86_CR0_EM); + write_cr0(cr0); + +- asm volatile("fninit ; fnstsw %0 ; fnstcw %1" +- : "+m" (fsw), "+m" (fcw)); ++ if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { ++ asm volatile("fninit ; fnstsw %0 ; fnstcw %1" ++ : "+m" (fsw), "+m" (fcw)); + +- if (fsw == 0 && (fcw & 0x103f) == 0x003f) +- set_cpu_cap(c, X86_FEATURE_FPU); +- else +- clear_cpu_cap(c, X86_FEATURE_FPU); ++ if (fsw == 0 && (fcw & 0x103f) == 0x003f) ++ set_cpu_cap(c, X86_FEATURE_FPU); ++ else ++ clear_cpu_cap(c, X86_FEATURE_FPU); ++ } + + #ifndef CONFIG_MATH_EMULATION + if (!cpu_has_fpu) { +@@ -130,7 +132,7 @@ static void __init fpu__init_system_generic(void) + * Set up the legacy init FPU context. (xstate init might overwrite this + * with a more modern format, if the CPU supports it.) + */ +- fpstate_init_fxstate(&init_fpstate.fxsave); ++ fpstate_init(&init_fpstate); + + fpu__init_system_mxcsr(); + } +@@ -230,53 +232,16 @@ static void __init fpu__init_system_xstate_size_legacy(void) + } + + /* +- * FPU context switching strategies: +- * +- * Against popular belief, we don't do lazy FPU saves, due to the +- * task migration complications it brings on SMP - we only do +- * lazy FPU restores. +- * +- * 'lazy' is the traditional strategy, which is based on setting +- * CR0::TS to 1 during context-switch (instead of doing a full +- * restore of the FPU state), which causes the first FPU instruction +- * after the context switch (whenever it is executed) to fault - at +- * which point we lazily restore the FPU state into FPU registers. +- * +- * Tasks are of course under no obligation to execute FPU instructions, +- * so it can easily happen that another context-switch occurs without +- * a single FPU instruction being executed. If we eventually switch +- * back to the original task (that still owns the FPU) then we have +- * not only saved the restores along the way, but we also have the +- * FPU ready to be used for the original task. +- * +- * 'eager' switching is used on modern CPUs, there we switch the FPU +- * state during every context switch, regardless of whether the task +- * has used FPU instructions in that time slice or not. This is done +- * because modern FPU context saving instructions are able to optimize +- * state saving and restoration in hardware: they can detect both +- * unused and untouched FPU state and optimize accordingly. +- * +- * [ Note that even in 'lazy' mode we might optimize context switches +- * to use 'eager' restores, if we detect that a task is using the FPU +- * frequently. See the fpu->counter logic in fpu/internal.h for that. ] ++ * Find supported xfeatures based on cpu features and command-line input. ++ * This must be called after fpu__init_parse_early_param() is called and ++ * xfeatures_mask is enumerated. + */ +-static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; +- +-static int __init eager_fpu_setup(char *s) ++u64 __init fpu__get_supported_xfeatures_mask(void) + { +- if (!strcmp(s, "on")) +- eagerfpu = ENABLE; +- else if (!strcmp(s, "off")) +- eagerfpu = DISABLE; +- else if (!strcmp(s, "auto")) +- eagerfpu = AUTO; +- return 1; ++ return XCNTXT_MASK; + } +-__setup("eagerfpu=", eager_fpu_setup); + +-/* +- * Pick the FPU context switching strategy: +- */ ++/* Legacy code to initialize eager fpu mode. */ + static void __init fpu__init_system_ctx_switch(void) + { + static bool on_boot_cpu = 1; +@@ -286,25 +251,31 @@ static void __init fpu__init_system_ctx_switch(void) + + WARN_ON_FPU(current->thread.fpu.fpstate_active); + current_thread_info()->status = 0; ++} + +- /* Auto enable eagerfpu for xsaveopt */ +- if (cpu_has_xsaveopt && eagerfpu != DISABLE) +- eagerfpu = ENABLE; +- +- if (xfeatures_mask & XFEATURE_MASK_EAGER) { +- if (eagerfpu == DISABLE) { +- pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n", +- xfeatures_mask & XFEATURE_MASK_EAGER); +- xfeatures_mask &= ~XFEATURE_MASK_EAGER; +- } else { +- eagerfpu = ENABLE; +- } ++/* ++ * We parse fpu parameters early because fpu__init_system() is executed ++ * before parse_early_param(). ++ */ ++static void __init fpu__init_parse_early_param(void) ++{ ++ if (cmdline_find_option_bool(boot_command_line, "no387")) ++ setup_clear_cpu_cap(X86_FEATURE_FPU); ++ ++ if (cmdline_find_option_bool(boot_command_line, "nofxsr")) { ++ setup_clear_cpu_cap(X86_FEATURE_FXSR); ++ setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); ++ setup_clear_cpu_cap(X86_FEATURE_XMM); + } + +- if (eagerfpu == ENABLE) +- setup_force_cpu_cap(X86_FEATURE_EAGER_FPU); ++ if (cmdline_find_option_bool(boot_command_line, "noxsave")) ++ fpu__xstate_clear_all_cpu_caps(); ++ ++ if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) ++ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); + +- printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy"); ++ if (cmdline_find_option_bool(boot_command_line, "noxsaves")) ++ setup_clear_cpu_cap(X86_FEATURE_XSAVES); + } + + /* +@@ -313,6 +284,7 @@ static void __init fpu__init_system_ctx_switch(void) + */ + void __init fpu__init_system(struct cpuinfo_x86 *c) + { ++ fpu__init_parse_early_param(); + fpu__init_system_early_generic(c); + + /* +@@ -336,62 +308,3 @@ void __init fpu__init_system(struct cpuinfo_x86 *c) + + fpu__init_system_ctx_switch(); + } +- +-/* +- * Boot parameter to turn off FPU support and fall back to math-emu: +- */ +-static int __init no_387(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_FPU); +- return 1; +-} +-__setup("no387", no_387); +- +-/* +- * Disable all xstate CPU features: +- */ +-static int __init x86_noxsave_setup(char *s) +-{ +- if (strlen(s)) +- return 0; +- +- fpu__xstate_clear_all_cpu_caps(); +- +- return 1; +-} +-__setup("noxsave", x86_noxsave_setup); +- +-/* +- * Disable the XSAVEOPT instruction specifically: +- */ +-static int __init x86_noxsaveopt_setup(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); +- +- return 1; +-} +-__setup("noxsaveopt", x86_noxsaveopt_setup); +- +-/* +- * Disable the XSAVES instruction: +- */ +-static int __init x86_noxsaves_setup(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_XSAVES); +- +- return 1; +-} +-__setup("noxsaves", x86_noxsaves_setup); +- +-/* +- * Disable FX save/restore and SSE support: +- */ +-static int __init x86_nofxsr_setup(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_FXSR); +- setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); +- setup_clear_cpu_cap(X86_FEATURE_XMM); +- +- return 1; +-} +-__setup("nofxsr", x86_nofxsr_setup); +diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c +index 70fc312221fc..3fa200ecca62 100644 +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -632,8 +632,7 @@ void __init fpu__init_system_xstate(void) + BUG(); + } + +- /* Support only the state known to the OS: */ +- xfeatures_mask = xfeatures_mask & XCNTXT_MASK; ++ xfeatures_mask &= fpu__get_supported_xfeatures_mask(); + + /* Enable xstate instructions to be able to continue with initialization: */ + fpu__init_cpu_xstate(); +diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c +index 50a3fad5b89f..2bcfb5f2bc44 100644 +--- a/arch/x86/kernel/hw_breakpoint.c ++++ b/arch/x86/kernel/hw_breakpoint.c +@@ -300,6 +300,10 @@ static int arch_build_bp_info(struct perf_event *bp) + return -EINVAL; + if (bp->attr.bp_addr & (bp->attr.bp_len - 1)) + return -EINVAL; ++ ++ if (!boot_cpu_has(X86_FEATURE_BPEXT)) ++ return -EOPNOTSUPP; ++ + /* + * It's impossible to use a range breakpoint to fake out + * user vs kernel detection because bp_len - 1 can't +@@ -307,8 +311,6 @@ static int arch_build_bp_info(struct perf_event *bp) + * breakpoints, then we'll have to check for kprobe-blacklisted + * addresses anywhere in the range. + */ +- if (!cpu_has_bpext) +- return -EOPNOTSUPP; + info->mask = bp->attr.bp_len - 1; + info->len = X86_BREAKPOINT_LEN_1; + } +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 48ca93242bfd..1f7aefc7b0b4 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -295,7 +295,7 @@ do { \ + + static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) + { +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + int cpu1 = c->cpu_index, cpu2 = o->cpu_index; + + if (c->phys_proc_id == o->phys_proc_id && +diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c +index 1fbd2631be60..8c73bf1492b8 100644 +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -751,7 +751,6 @@ dotraplinkage void + do_device_not_available(struct pt_regs *regs, long error_code) + { + RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); +- BUG_ON(use_eager_fpu()); + + #ifdef CONFIG_MATH_EMULATION + if (read_cr0() & X86_CR0_EM) { +diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c +index af57736a0309..d6d64a519559 100644 +--- a/arch/x86/kernel/vm86_32.c ++++ b/arch/x86/kernel/vm86_32.c +@@ -357,8 +357,10 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) + tss = &per_cpu(cpu_tss, get_cpu()); + /* make room for real-mode segments */ + tsk->thread.sp0 += 16; +- if (cpu_has_sep) ++ ++ if (static_cpu_has_safe(X86_FEATURE_SEP)) + tsk->thread.sysenter_cs = 0; ++ + load_sp0(tss, &tsk->thread); + put_cpu(); + +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 8864fec63a20..f1507626ed36 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -790,6 +790,19 @@ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) + return assign_eip_near(ctxt, ctxt->_eip + rel); + } + ++static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear, ++ void *data, unsigned size) ++{ ++ return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, true); ++} ++ ++static int linear_write_system(struct x86_emulate_ctxt *ctxt, ++ ulong linear, void *data, ++ unsigned int size) ++{ ++ return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, true); ++} ++ + static int segmented_read_std(struct x86_emulate_ctxt *ctxt, + struct segmented_address addr, + void *data, +@@ -801,7 +814,7 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt, + rc = linearize(ctxt, addr, size, false, &linear); + if (rc != X86EMUL_CONTINUE) + return rc; +- return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception); ++ return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, false); + } + + static int segmented_write_std(struct x86_emulate_ctxt *ctxt, +@@ -815,7 +828,7 @@ static int segmented_write_std(struct x86_emulate_ctxt *ctxt, + rc = linearize(ctxt, addr, size, true, &linear); + if (rc != X86EMUL_CONTINUE) + return rc; +- return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception); ++ return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, false); + } + + /* +@@ -1488,8 +1501,7 @@ static int read_interrupt_descriptor(struct x86_emulate_ctxt *ctxt, + return emulate_gp(ctxt, index << 3 | 0x2); + + addr = dt.address + index * 8; +- return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc, +- &ctxt->exception); ++ return linear_read_system(ctxt, addr, desc, sizeof *desc); + } + + static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, +@@ -1552,8 +1564,7 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, + if (rc != X86EMUL_CONTINUE) + return rc; + +- return ctxt->ops->read_std(ctxt, *desc_addr_p, desc, sizeof(*desc), +- &ctxt->exception); ++ return linear_read_system(ctxt, *desc_addr_p, desc, sizeof(*desc)); + } + + /* allowed just for 8 bytes segments */ +@@ -1567,8 +1578,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, + if (rc != X86EMUL_CONTINUE) + return rc; + +- return ctxt->ops->write_std(ctxt, addr, desc, sizeof *desc, +- &ctxt->exception); ++ return linear_write_system(ctxt, addr, desc, sizeof *desc); + } + + static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, +@@ -1729,8 +1739,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, + return ret; + } + } else if (ctxt->mode == X86EMUL_MODE_PROT64) { +- ret = ctxt->ops->read_std(ctxt, desc_addr+8, &base3, +- sizeof(base3), &ctxt->exception); ++ ret = linear_read_system(ctxt, desc_addr+8, &base3, sizeof(base3)); + if (ret != X86EMUL_CONTINUE) + return ret; + if (is_noncanonical_address(get_desc_base(&seg_desc) | +@@ -2043,11 +2052,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq) + eip_addr = dt.address + (irq << 2); + cs_addr = dt.address + (irq << 2) + 2; + +- rc = ops->read_std(ctxt, cs_addr, &cs, 2, &ctxt->exception); ++ rc = linear_read_system(ctxt, cs_addr, &cs, 2); + if (rc != X86EMUL_CONTINUE) + return rc; + +- rc = ops->read_std(ctxt, eip_addr, &eip, 2, &ctxt->exception); ++ rc = linear_read_system(ctxt, eip_addr, &eip, 2); + if (rc != X86EMUL_CONTINUE) + return rc; + +@@ -2891,12 +2900,12 @@ static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, + #ifdef CONFIG_X86_64 + base |= ((u64)base3) << 32; + #endif +- r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL); ++ r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true); + if (r != X86EMUL_CONTINUE) + return false; + if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg)) + return false; +- r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL); ++ r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, true); + if (r != X86EMUL_CONTINUE) + return false; + if ((perm >> bit_idx) & mask) +@@ -3025,35 +3034,30 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, + u16 tss_selector, u16 old_tss_sel, + ulong old_tss_base, struct desc_struct *new_desc) + { +- const struct x86_emulate_ops *ops = ctxt->ops; + struct tss_segment_16 tss_seg; + int ret; + u32 new_tss_base = get_desc_base(new_desc); + +- ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + save_state_to_tss16(ctxt, &tss_seg); + +- ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + +- ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + if (old_tss_sel != 0xffff) { + tss_seg.prev_task_link = old_tss_sel; + +- ret = ops->write_std(ctxt, new_tss_base, +- &tss_seg.prev_task_link, +- sizeof tss_seg.prev_task_link, +- &ctxt->exception); ++ ret = linear_write_system(ctxt, new_tss_base, ++ &tss_seg.prev_task_link, ++ sizeof tss_seg.prev_task_link); + if (ret != X86EMUL_CONTINUE) + return ret; + } +@@ -3169,38 +3173,34 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, + u16 tss_selector, u16 old_tss_sel, + ulong old_tss_base, struct desc_struct *new_desc) + { +- const struct x86_emulate_ops *ops = ctxt->ops; + struct tss_segment_32 tss_seg; + int ret; + u32 new_tss_base = get_desc_base(new_desc); + u32 eip_offset = offsetof(struct tss_segment_32, eip); + u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector); + +- ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + save_state_to_tss32(ctxt, &tss_seg); + + /* Only GP registers and segment selectors are saved */ +- ret = ops->write_std(ctxt, old_tss_base + eip_offset, &tss_seg.eip, +- ldt_sel_offset - eip_offset, &ctxt->exception); ++ ret = linear_write_system(ctxt, old_tss_base + eip_offset, &tss_seg.eip, ++ ldt_sel_offset - eip_offset); + if (ret != X86EMUL_CONTINUE) + return ret; + +- ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + if (old_tss_sel != 0xffff) { + tss_seg.prev_task_link = old_tss_sel; + +- ret = ops->write_std(ctxt, new_tss_base, +- &tss_seg.prev_task_link, +- sizeof tss_seg.prev_task_link, +- &ctxt->exception); ++ ret = linear_write_system(ctxt, new_tss_base, ++ &tss_seg.prev_task_link, ++ sizeof tss_seg.prev_task_link); + if (ret != X86EMUL_CONTINUE) + return ret; + } +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index a750fc7c7458..63c44a9bf6bb 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6692,8 +6692,7 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, + vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva)) + return 1; + +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vmptr, +- sizeof(vmptr), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &vmptr, sizeof(vmptr), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7211,8 +7210,8 @@ static int handle_vmread(struct kvm_vcpu *vcpu) + vmx_instruction_info, true, &gva)) + return 1; + /* _system ok, as nested_vmx_check_permission verified cpl=0 */ +- kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva, +- &field_value, (is_long_mode(vcpu) ? 8 : 4), NULL); ++ kvm_write_guest_virt_system(vcpu, gva, &field_value, ++ (is_long_mode(vcpu) ? 8 : 4), NULL); + } + + nested_vmx_succeed(vcpu); +@@ -7247,8 +7246,8 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + if (get_vmx_mem_address(vcpu, exit_qualification, + vmx_instruction_info, false, &gva)) + return 1; +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, +- &field_value, (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &field_value, ++ (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7338,9 +7337,9 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) + vmx_instruction_info, true, &vmcs_gva)) + return 1; + /* ok to use *_system, as nested_vmx_check_permission verified cpl=0 */ +- if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva, +- (void *)&to_vmx(vcpu)->nested.current_vmptr, +- sizeof(u64), &e)) { ++ if (kvm_write_guest_virt_system(vcpu, vmcs_gva, ++ (void *)&to_vmx(vcpu)->nested.current_vmptr, ++ sizeof(u64), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7394,8 +7393,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) + if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), + vmx_instruction_info, false, &gva)) + return 1; +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand, +- sizeof(operand), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7454,8 +7452,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) + if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), + vmx_instruction_info, false, &gva)) + return 1; +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vpid, +- sizeof(u32), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &vpid, sizeof(u32), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 9cea09597d66..53d43d22a84b 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -4245,11 +4245,10 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt, + return X86EMUL_CONTINUE; + } + +-int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, ++int kvm_read_guest_virt(struct kvm_vcpu *vcpu, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception) + { +- struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + + return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, +@@ -4257,12 +4256,17 @@ int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, + } + EXPORT_SYMBOL_GPL(kvm_read_guest_virt); + +-static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt, +- gva_t addr, void *val, unsigned int bytes, +- struct x86_exception *exception) ++static int emulator_read_std(struct x86_emulate_ctxt *ctxt, ++ gva_t addr, void *val, unsigned int bytes, ++ struct x86_exception *exception, bool system) + { + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); +- return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception); ++ u32 access = 0; ++ ++ if (!system && kvm_x86_ops->get_cpl(vcpu) == 3) ++ access |= PFERR_USER_MASK; ++ ++ return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception); + } + + static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, +@@ -4274,18 +4278,16 @@ static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, + return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE; + } + +-int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, +- gva_t addr, void *val, +- unsigned int bytes, +- struct x86_exception *exception) ++static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, ++ struct kvm_vcpu *vcpu, u32 access, ++ struct x86_exception *exception) + { +- struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + void *data = val; + int r = X86EMUL_CONTINUE; + + while (bytes) { + gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, +- PFERR_WRITE_MASK, ++ access, + exception); + unsigned offset = addr & (PAGE_SIZE-1); + unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); +@@ -4306,6 +4308,27 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, + out: + return r; + } ++ ++static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val, ++ unsigned int bytes, struct x86_exception *exception, ++ bool system) ++{ ++ struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); ++ u32 access = PFERR_WRITE_MASK; ++ ++ if (!system && kvm_x86_ops->get_cpl(vcpu) == 3) ++ access |= PFERR_USER_MASK; ++ ++ return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, ++ access, exception); ++} ++ ++int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, ++ unsigned int bytes, struct x86_exception *exception) ++{ ++ return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, ++ PFERR_WRITE_MASK, exception); ++} + EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); + + static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, +@@ -5025,8 +5048,8 @@ static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_fla + static const struct x86_emulate_ops emulate_ops = { + .read_gpr = emulator_read_gpr, + .write_gpr = emulator_write_gpr, +- .read_std = kvm_read_guest_virt_system, +- .write_std = kvm_write_guest_virt_system, ++ .read_std = emulator_read_std, ++ .write_std = emulator_write_std, + .read_phys = kvm_read_guest_phys_system, + .fetch = kvm_fetch_guest_virt, + .read_emulated = emulator_read_emulated, +diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h +index f2afa5fe48a6..53a750a10598 100644 +--- a/arch/x86/kvm/x86.h ++++ b/arch/x86/kvm/x86.h +@@ -164,11 +164,11 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); + + void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); + +-int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, ++int kvm_read_guest_virt(struct kvm_vcpu *vcpu, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception); + +-int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, ++int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception); + +diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c +index 90555bf60aa4..92e2eacb3321 100644 +--- a/arch/x86/mm/setup_nx.c ++++ b/arch/x86/mm/setup_nx.c +@@ -31,7 +31,7 @@ early_param("noexec", noexec_setup); + + void x86_configure_nx(void) + { +- if (cpu_has_nx && !disable_nx) ++ if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) + __supported_pte_mask |= _PAGE_NX; + else + __supported_pte_mask &= ~_PAGE_NX; +@@ -39,7 +39,7 @@ void x86_configure_nx(void) + + void __init x86_report_nx(void) + { +- if (!cpu_has_nx) { ++ if (!boot_cpu_has(X86_FEATURE_NX)) { + printk(KERN_NOTICE "Notice: NX (Execute Disable) protection " + "missing in CPU!\n"); + } else { +diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c +index 0c98a9d51a24..44ce80606944 100644 +--- a/drivers/char/hw_random/via-rng.c ++++ b/drivers/char/hw_random/via-rng.c +@@ -140,7 +140,7 @@ static int via_rng_init(struct hwrng *rng) + * RNG configuration like it used to be the case in this + * register */ + if ((c->x86 == 6) && (c->x86_model >= 0x0f)) { +- if (!cpu_has_xstore_enabled) { ++ if (!boot_cpu_has(X86_FEATURE_XSTORE_EN)) { + pr_err(PFX "can't enable hardware RNG " + "if XSTORE is not enabled\n"); + return -ENODEV; +@@ -200,8 +200,9 @@ static int __init mod_init(void) + { + int err; + +- if (!cpu_has_xstore) ++ if (!boot_cpu_has(X86_FEATURE_XSTORE)) + return -ENODEV; ++ + pr_info("VIA RNG detected\n"); + err = hwrng_register(&via_rng); + if (err) { +diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c +index da2d6777bd09..97a364694bfc 100644 +--- a/drivers/crypto/padlock-aes.c ++++ b/drivers/crypto/padlock-aes.c +@@ -515,7 +515,7 @@ static int __init padlock_init(void) + if (!x86_match_cpu(padlock_cpu_id)) + return -ENODEV; + +- if (!cpu_has_xcrypt_enabled) { ++ if (!boot_cpu_has(X86_FEATURE_XCRYPT_EN)) { + printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + return -ENODEV; + } +diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c +index 4e154c9b9206..8c5f90647b7a 100644 +--- a/drivers/crypto/padlock-sha.c ++++ b/drivers/crypto/padlock-sha.c +@@ -540,7 +540,7 @@ static int __init padlock_init(void) + struct shash_alg *sha1; + struct shash_alg *sha256; + +- if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled) ++ if (!x86_match_cpu(padlock_sha_ids) || !boot_cpu_has(X86_FEATURE_PHE_EN)) + return -ENODEV; + + /* Register the newly added algorithm module if on * +diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c +index 263af709e536..b907e4b1bbe2 100644 +--- a/drivers/crypto/vmx/aes.c ++++ b/drivers/crypto/vmx/aes.c +@@ -53,8 +53,6 @@ static int p8_aes_init(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); + + crypto_cipher_set_flags(fallback, + crypto_cipher_get_flags((struct +diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c +index 3f8bb9a40df1..9506e8693c81 100644 +--- a/drivers/crypto/vmx/aes_cbc.c ++++ b/drivers/crypto/vmx/aes_cbc.c +@@ -55,8 +55,6 @@ static int p8_aes_cbc_init(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); + + crypto_blkcipher_set_flags( + fallback, +diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c +index d83ab4bac8b1..7d070201b3d3 100644 +--- a/drivers/crypto/vmx/aes_ctr.c ++++ b/drivers/crypto/vmx/aes_ctr.c +@@ -53,8 +53,6 @@ static int p8_aes_ctr_init(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); + + crypto_blkcipher_set_flags( + fallback, +diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c +index 9cb3a0b715e2..84b9389bf1ed 100644 +--- a/drivers/crypto/vmx/ghash.c ++++ b/drivers/crypto/vmx/ghash.c +@@ -64,8 +64,6 @@ static int p8_ghash_init_tfm(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name(crypto_shash_tfm(fallback))); + + crypto_shash_set_flags(fallback, + crypto_shash_get_flags((struct crypto_shash +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 759a39906a52..fe89fd56eabf 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -2117,6 +2117,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, + struct gpio_desc *desc = NULL; + int status; + enum gpio_lookup_flags lookupflags = 0; ++ /* Maybe we have a device name, maybe not */ ++ const char *devname = dev ? dev_name(dev) : "?"; + + dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id); + +@@ -2145,8 +2147,11 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, + return desc; + } + +- /* If a connection label was passed use that, else use the device name as label */ +- status = gpiod_request(desc, con_id ? con_id : dev_name(dev)); ++ /* ++ * If a connection label was passed use that, else attempt to use ++ * the device name as label ++ */ ++ status = gpiod_request(desc, con_id ? con_id : devname); + if (status < 0) + return ERR_PTR(status); + +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index 3851d5715772..aeb8250ab079 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1249,6 +1249,7 @@ static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN060B", 0 }, + { "ELAN060C", 0 }, + { "ELAN0611", 0 }, ++ { "ELAN0612", 0 }, + { "ELAN1000", 0 }, + { } + }; +diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c +index 4d113c9e4b77..7bf2597ce44c 100644 +--- a/drivers/input/touchscreen/goodix.c ++++ b/drivers/input/touchscreen/goodix.c +@@ -425,6 +425,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id); + #ifdef CONFIG_ACPI + static const struct acpi_device_id goodix_acpi_match[] = { + { "GDIX1001", 0 }, ++ { "GDIX1002", 0 }, + { } + }; + MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); +diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c +index e9b241b1c9dd..ac596928f6b4 100644 +--- a/drivers/iommu/intel_irq_remapping.c ++++ b/drivers/iommu/intel_irq_remapping.c +@@ -753,7 +753,7 @@ static inline void set_irq_posting_cap(void) + * should have X86_FEATURE_CX16 support, this has been confirmed + * with Intel hardware guys. + */ +- if ( cpu_has_cx16 ) ++ if (boot_cpu_has(X86_FEATURE_CX16)) + intel_irq_remap_ops.capability |= 1 << IRQ_POSTING_CAP; + + for_each_iommu(iommu, drhd) +diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c +index 1e688bfec567..fe90b7e04427 100644 +--- a/drivers/misc/vmw_balloon.c ++++ b/drivers/misc/vmw_balloon.c +@@ -576,15 +576,9 @@ static void vmballoon_pop(struct vmballoon *b) + } + } + +- if (b->batch_page) { +- vunmap(b->batch_page); +- b->batch_page = NULL; +- } +- +- if (b->page) { +- __free_page(b->page); +- b->page = NULL; +- } ++ /* Clearing the batch_page unconditionally has no adverse effect */ ++ free_page((unsigned long)b->batch_page); ++ b->batch_page = NULL; + } + + /* +@@ -991,16 +985,13 @@ static const struct vmballoon_ops vmballoon_batched_ops = { + + static bool vmballoon_init_batching(struct vmballoon *b) + { +- b->page = alloc_page(VMW_PAGE_ALLOC_NOSLEEP); +- if (!b->page) +- return false; ++ struct page *page; + +- b->batch_page = vmap(&b->page, 1, VM_MAP, PAGE_KERNEL); +- if (!b->batch_page) { +- __free_page(b->page); ++ page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ if (!page) + return false; +- } + ++ b->batch_page = page_address(page); + return true; + } + +diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c +index 312343beb249..4d532a085db9 100644 +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -860,15 +860,12 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) + dma->rx_conf.direction = DMA_DEV_TO_MEM; + dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH; +- dma->rx_conf.src_maxburst = 16; ++ dma->rx_conf.src_maxburst = 1; + + dma->tx_conf.direction = DMA_MEM_TO_DEV; + dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH; +- if (dma_get_cache_alignment() >= 16) +- dma->tx_conf.dst_maxburst = 16; +- else +- dma->tx_conf.dst_maxburst = 1; ++ dma->tx_conf.dst_maxburst = 1; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 208b3f5ffb3f..7efd70bfeaf7 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -923,7 +923,7 @@ static int check_async_write(struct inode *inode, unsigned long bio_flags) + if (bio_flags & EXTENT_BIO_TREE_LOG) + return 0; + #ifdef CONFIG_X86 +- if (cpu_has_xmm4_2) ++ if (static_cpu_has_safe(X86_FEATURE_XMM4_2)) + return 0; + #endif + return 1; +diff --git a/include/linux/fs.h b/include/linux/fs.h +index da79e9d66e5b..240cbaee819f 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -926,9 +926,9 @@ static inline struct file *get_file(struct file *f) + /* Page cache limit. The filesystems should put that into their s_maxbytes + limits, otherwise bad things can happen in VM. */ + #if BITS_PER_LONG==32 +-#define MAX_LFS_FILESIZE (((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) ++#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT) + #elif BITS_PER_LONG==64 +-#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL) ++#define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX) + #endif + + #define FL_POSIX 1 +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 15150b412930..3ba903ff2bb0 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -437,6 +437,24 @@ static int verify_address_len(const void *p) + return 0; + } + ++static inline int sadb_key_len(const struct sadb_key *key) ++{ ++ int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8); ++ ++ return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes, ++ sizeof(uint64_t)); ++} ++ ++static int verify_key_len(const void *p) ++{ ++ const struct sadb_key *key = p; ++ ++ if (sadb_key_len(key) > key->sadb_key_len) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) + { + return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + +@@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void * + return -EINVAL; + if (ext_hdrs[ext_type-1] != NULL) + return -EINVAL; +- if (ext_type == SADB_EXT_ADDRESS_SRC || +- ext_type == SADB_EXT_ADDRESS_DST || +- ext_type == SADB_EXT_ADDRESS_PROXY || +- ext_type == SADB_X_EXT_NAT_T_OA) { ++ switch (ext_type) { ++ case SADB_EXT_ADDRESS_SRC: ++ case SADB_EXT_ADDRESS_DST: ++ case SADB_EXT_ADDRESS_PROXY: ++ case SADB_X_EXT_NAT_T_OA: + if (verify_address_len(p)) + return -EINVAL; +- } +- if (ext_type == SADB_X_EXT_SEC_CTX) { ++ break; ++ case SADB_X_EXT_SEC_CTX: + if (verify_sec_ctx_len(p)) + return -EINVAL; ++ break; ++ case SADB_EXT_KEY_AUTH: ++ case SADB_EXT_KEY_ENCRYPT: ++ if (verify_key_len(p)) ++ return -EINVAL; ++ break; ++ default: ++ break; + } + ext_hdrs[ext_type-1] = (void *) p; + } +@@ -1111,14 +1138,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, + key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; + if (key != NULL && + sa->sadb_sa_auth != SADB_X_AALG_NULL && +- ((key->sadb_key_bits+7) / 8 == 0 || +- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) ++ key->sadb_key_bits == 0) + return ERR_PTR(-EINVAL); + key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; + if (key != NULL && + sa->sadb_sa_encrypt != SADB_EALG_NULL && +- ((key->sadb_key_bits+7) / 8 == 0 || +- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) ++ key->sadb_key_bits == 0) + return ERR_PTR(-EINVAL); + + x = xfrm_state_alloc(net);