From bc86cf7af2ebda88056538e8edff852ee627f76a Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 9 Oct 2012 23:26:06 -0700 Subject: mtd: nand: fix Samsung SLC NAND identification regression A combination of the following two commits caused a regression in 3.7-rc1 when identifying some Samsung NAND, so that some previously working NAND were no longer detected properly: commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a mtd: nand: add generic READ ID length calculation functions commit e2d3a35ee427aaba99b6c68a56609ce276c51270 mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID Particularly, a regression was seen on Samsung K9F2G08U0B, with the following full 8-byte READ ID string: ec da 10 95 44 00 ec da The basic problem is that Samsung manufactures both SLC and MLC NAND that use a non-standard decoding table for deriving information from their IDs. I have heuristically determined that all the chips that use the new table have ID strings which wrap around after the 6th byte. Unfortunately, I overlooked the fact that some older Samsung SLC (which use a different decoding table) have "5 byte ID strings" which also wrap around after the 6th byte. This patch re-introduces a distinction between these old and new Samsung NAND by checking that the 6th byte is non-zero, allowing both old and new Samsung NAND to be detected properly. Signed-off-by: Brian Norris Tested-by: Brian Norris Reported-by: Marek Vasut Tested-by: Marek Vasut Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ec6841d..d5ece6e 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2983,13 +2983,14 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) - * New style (6 byte ID): Samsung K9GAG08U0F (p.44) + * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * - * Check for ID length, cell type, and Hynix/Samsung ID to decide what - * to do. + * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung + * ID to decide what to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { + if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && + id_data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; -- cgit v1.1 From 5a6ea4af0907f995dc06df21a9c9ef764c7cd3bc Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 25 Sep 2012 15:27:13 +0530 Subject: mtd: ofpart: Fix incorrect NULL check in parse_ofoldpart_partitions() The pointer returned by kzalloc should be tested for NULL to avoid potential NULL pointer dereference later. Incorrect pointer was being tested for NULL. Bug introduced by commit fbcf62a3 (mtd: physmap_of: move parse_obsolete_partitions to become separate parser). This patch fixes this bug. Cc: Dmitry Eremin-Solenikov Cc: Artem Bityutskiy Cc: stable@kernel.org Signed-off-by: Sachin Kamat Signed-off-by: David Woodhouse --- drivers/mtd/ofpart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 64be8f08..d9127e2 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, nr_parts = plen / sizeof(part[0]); *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); - if (!pparts) + if (!*pparts) return -ENOMEM; names = of_get_property(dp, "partition-names", &plen); -- cgit v1.1 From a736427fa1103158338839813139b20763c7b13e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 20 Oct 2012 21:39:44 -0400 Subject: missing const in alpha callers of do_mount() Signed-off-by: Al Viro --- arch/alpha/kernel/osf_sys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 9eb0905..ac2ae13 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -445,7 +445,7 @@ struct procfs_args { * unhappy with OSF UFS. [CHECKME] */ static int -osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) +osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) } static int -osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) +osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) } static int -osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) +osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) { struct procfs_args tmp; -- cgit v1.1 From bad9955db1b73d7286f74a8136a0628a9b1ac017 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Sun, 21 Oct 2012 05:27:53 -0400 Subject: menuconfig: Replace CIRCLEQ by list_head-style lists. sys/queue.h and CIRCLEQ in particular have proven to cause portability problems (reported on Debian Sarge, Cygwin and FreeBSD) Reported-by: Tetsuo Handa Tested-by: Tetsuo Handa Tested-by: Yaakov Selkowitz Signed-off-by: Benjamin Poirier Signed-off-by: "Yann E. MORIN" Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 5 +-- scripts/kconfig/list.h | 91 +++++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/lkc_proto.h | 4 +- scripts/kconfig/mconf.c | 6 +-- scripts/kconfig/menu.c | 14 ++++--- 5 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 scripts/kconfig/list.h diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index bd2e098..cdd4860 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -12,7 +12,7 @@ extern "C" { #include #include -#include +#include "list.h" #ifndef __cplusplus #include #endif @@ -175,12 +175,11 @@ struct menu { #define MENU_ROOT 0x0002 struct jump_key { - CIRCLEQ_ENTRY(jump_key) entries; + struct list_head entries; size_t offset; struct menu *target; int index; }; -CIRCLEQ_HEAD(jk_head, jump_key); #define JUMP_NB 9 diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h new file mode 100644 index 0000000..0ae730b --- /dev/null +++ b/scripts/kconfig/list.h @@ -0,0 +1,91 @@ +#ifndef LIST_H +#define LIST_H + +/* + * Copied from include/linux/... + */ + +#undef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + + +struct list_head { + struct list_head *next, *prev; +}; + + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *_new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = _new; + _new->next = next; + _new->prev = prev; + prev->next = _new; +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} + +#endif diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 1d1c085..ef1a738 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); P(menu_get_parent_menu,struct menu *,(struct menu *menu)); P(menu_has_help,bool,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu)); -P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head *head)); -P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head +P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head *head)); P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 48f6744..53975cf 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) struct search_data { - struct jk_head *head; + struct list_head *head; struct menu **targets; int *keys; }; @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) struct jump_key *pos; int k = 0; - CIRCLEQ_FOREACH(pos, data->head, entries) { + list_for_each_entry(pos, data->head, entries) { if (pos->offset >= start && pos->offset < end) { char header[4]; @@ -375,7 +375,7 @@ again: sym_arr = sym_re_search(dialog_input); do { - struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); + LIST_HEAD(head); struct menu *targets[JUMP_NB]; int keys[JUMP_NB + 1], i; struct search_data data = { diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index a3cade6..e98a05c 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) } static void get_prompt_str(struct gstr *r, struct property *prop, - struct jk_head *head) + struct list_head *head) { int i, j; struct menu *submenu[8], *menu, *location = NULL; @@ -544,12 +544,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } else jump->target = location; - if (CIRCLEQ_EMPTY(head)) + if (list_empty(head)) jump->index = 0; else - jump->index = CIRCLEQ_LAST(head)->index + 1; + jump->index = list_entry(head->prev, struct jump_key, + entries)->index + 1; - CIRCLEQ_INSERT_TAIL(head, jump, entries); + list_add_tail(&jump->entries, head); } if (i > 0) { @@ -573,7 +574,8 @@ static void get_prompt_str(struct gstr *r, struct property *prop, /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) +void get_symbol_str(struct gstr *r, struct symbol *sym, + struct list_head *head) { bool hit; struct property *prop; @@ -612,7 +614,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) str_append(r, "\n\n"); } -struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) { struct symbol *sym; struct gstr res = str_new(); -- cgit v1.1 From ea29c4ea2b04462e92f409cd852dfe0d6d04f0fc Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 15 Oct 2012 12:48:11 +0300 Subject: OMAPDSS: DSI: fix dsi_get_dsidev_from_id() If dsi_get_dsidev_from_id() is called with a DSI module id that does not exist on the board, the function will crash as omap_dss_get_output() will return NULL. This happens on omap3 boards when dumping DSI clocks, as the dumping code will try to get the dsidev for DSI modules 0 and 1, but omap3 only has DSI module 0. Also clean up the id -> output mapping, so that if the function is called with invalid module ID it will return NULL. Signed-off-by: Tomi Valkeinen Cc: Archit Taneja --- drivers/video/omap2/dss/dsi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d64ac38..bee9284 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module) struct omap_dss_output *out; enum omap_dss_output_id id; - id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; + switch (module) { + case 0: + id = OMAP_DSS_OUTPUT_DSI1; + break; + case 1: + id = OMAP_DSS_OUTPUT_DSI2; + break; + default: + return NULL; + } out = omap_dss_get_output(id); - return out->pdev; + return out ? out->pdev : NULL; } static inline void dsi_write_reg(struct platform_device *dsidev, -- cgit v1.1 From 43993e4af02ec99908d6d99176773fc2a3ee4c57 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 25 Oct 2012 10:30:34 -0700 Subject: ARM: OMAP2+: PM: add missing newline to VC warning message Add missing newline to warning message to avoid annoying wrapping problems during kernel boot like this one: omap_vc_i2c_init: I2C config for vdd_iva does not match other channels (0). omap_vc_i2c_init: I2C config for vdd_mpu does not match other channels (0).Power Management for TI OMAP4. Reported-by: Russell King Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 880249b..75878c3 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) if (initialized) { if (voltdm->pmic->i2c_high_speed != i2c_high_speed) - pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", __func__, voltdm->name, i2c_high_speed); return; } -- cgit v1.1 From f4221a7a63abd1b6e358d19fe4d05e4d2e44e11a Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Mon, 24 Sep 2012 12:16:47 +0000 Subject: powerpc/pcm030: add pcm030-audio-fabric to dts Add a node for the pcm030-audio-fabric ASoC driver Signed-off-by: Eric Millbrandt Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/pcm030.dts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 9e35499..96512c0 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts @@ -59,7 +59,7 @@ #gpio-cells = <2>; }; - psc@2000 { /* PSC1 in ac97 mode */ + audioplatform: psc@2000 { /* PSC1 in ac97 mode */ compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; cell-index = <0>; }; @@ -134,4 +134,9 @@ localbus { status = "disabled"; }; + + sound { + compatible = "phytec,pcm030-audio-fabric"; + asoc-platform = <&audioplatform>; + }; }; -- cgit v1.1 From e34298c9a29a4b5bdcbb9a8994cc61f6ba506a94 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 10 Oct 2012 23:19:15 +0000 Subject: powerpc: 52xx: nop out unsupported critical IRQs Currently, when booting MPC52xx based platforms, we get: mpc52xx_irqhost_map: invalid irq: virq=16, l1=0, l2=3 irq: irq-16==>hwirq-0x3 mapping failed: -22 [WARNing skipped] The warning is wrong since the mapping itself is valid. However, there is no support for that type of IRQ currently. Print a proper warning and bind the irq to a no_irq chip. Signed-off-by: Wolfram Sang Cc: John Bonesio Cc: Anatolij Gustschin Cc: Grant Likely Signed-off-by: Anatolij Gustschin --- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 8520b58..b89ef65 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; - default: - pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", - __func__, virq, l1irq, l2irq); - return -EINVAL; + case MPC52xx_IRQ_L1_CRIT: + pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", + __func__, l2irq); + irq_set_chip(virq, &no_irq_chip); + return 0; } irq_set_chip_and_handler(virq, irqchip, handle_level_irq); -- cgit v1.1 From 7dfb736ec9917883fc9cfe6d0081987b8b110afe Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 5 Oct 2012 10:23:10 +0000 Subject: powerpc/mpc5200: move lpbfifo node and fix its interrupt property The LPB FIFO interrupt is a peripheral interrupt, thus its L1 cell has to be 2 instead of 3. Fix it and while at it, move the lpbfifo node to the common dtsi file. This patch fixes the irqdomain warning: ... WARNING: at kernel/irq/irqdomain.c:766 Modules linked in: NIP: c00587fc LR: c0058e0c CTR: c0014e54 REGS: c7837c10 TRAP: 0700 Tainted: G W (3.7.0-rc1-00003-g6e51414) MSR: 00029032 CR: 82cd8322 XER: 00000000 TASK = c7834000[1] 'swapper' THREAD: c7836000 GPR00: 00000001 c7837cc0 c7834000 c7806080 000000d7 c7837d20 00000003 c7837cec GPR08: c7837ce8 00000000 00000000 00000008 82cd3342 00000000 c0003f88 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c7850ec0 GPR24: c782b010 00000000 00000001 c7852900 00000003 c7df5be0 c7806080 000000d7 NIP [c00587fc] irq_linear_revmap+0x2c/0x4c LR [c0058e0c] irq_create_mapping+0x28/0x124 Reported-by: Stefan Roese Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/mpc5200b.dtsi | 6 ++++++ arch/powerpc/boot/dts/o2d.dtsi | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi index 7ab286a..39ed65a 100644 --- a/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/arch/powerpc/boot/dts/mpc5200b.dtsi @@ -231,6 +231,12 @@ interrupts = <2 7 0>; }; + sclpc@3c00 { + compatible = "fsl,mpc5200-lpbfifo"; + reg = <0x3c00 0x60>; + interrupts = <2 23 0>; + }; + i2c@3d00 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi index 3444eb8..24f6680 100644 --- a/arch/powerpc/boot/dts/o2d.dtsi +++ b/arch/powerpc/boot/dts/o2d.dtsi @@ -86,12 +86,6 @@ reg = <0>; }; }; - - sclpc@3c00 { - compatible = "fsl,mpc5200-lpbfifo"; - reg = <0x3c00 0x60>; - interrupts = <3 23 0>; - }; }; localbus { -- cgit v1.1 From f65e384bec59ef35dfa77455181af2ecf7a7ef44 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 25 Oct 2012 20:42:10 +0200 Subject: omapdss: dss: Fix clocks on OMAP363x Commit 185bae1095188aa199c9be64d6030d8dbfc65e0a ("OMAPDSS: DSS: Cleanup cpu_is_xxxx checks") broke the DSS clocks configuration by erroneously using the clock parameters applicable to all other OMAP34xx SoCs for the OMAP363x. This went unnoticed probably because the cpu_is_omap34xx() class check wasn't seen as matching the OMAP363x subclass. Fix it by checking for the OMAP363x subclass before checking for the OMAP34xx class. Signed-off-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 2ab1c3e..0bb7406 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -805,10 +805,10 @@ static int __init dss_init_features(struct device *dev) if (cpu_is_omap24xx()) src = &omap24xx_dss_feats; - else if (cpu_is_omap34xx()) - src = &omap34xx_dss_feats; else if (cpu_is_omap3630()) src = &omap3630_dss_feats; + else if (cpu_is_omap34xx()) + src = &omap34xx_dss_feats; else if (cpu_is_omap44xx()) src = &omap44xx_dss_feats; else if (soc_is_omap54xx()) -- cgit v1.1 From dffc70ade1d13edd186f542718c4d78a31d92fb8 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 21 Oct 2012 20:54:26 +0800 Subject: OMAPDSS: HDMI: fix missing unlock on error in hdmi_dump_regs() Add the missing unlock on the error handling path in function hdmi_dump_regs(). Signed-off-by: Wei Yongjun Reviewed-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a48a7dd..8c9b8b3 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s) { mutex_lock(&hdmi.lock); - if (hdmi_runtime_get()) + if (hdmi_runtime_get()) { + mutex_unlock(&hdmi.lock); return; + } hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); -- cgit v1.1 From 00a89180e5419f6567135d86e66a989a1b610b45 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 26 Oct 2012 09:55:31 +0300 Subject: Revert "usb: musb: use DMA mode 1 whenever possible" This reverts commit 4f3e8d263d34e52e75b5adfa14811467d3033d8e. it turns out that current implementation of Mode 1 DMA added a few regressions to some users, so we need to revert this patch and let author work on a better version of Mode 1 DMA support. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d0b87e7..b6b84da 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req) fifo_count = musb_readw(epio, MUSB_RXCOUNT); /* - * use mode 1 only if we expect data of at least ep packet_sz - * and have not yet received a short packet + * Enable Mode 1 on RX transfers only when short_not_ok flag + * is set. Currently short_not_ok flag is set only from + * file_storage and f_mass_storage drivers */ - if ((request->length - request->actual >= musb_ep->packet_sz) && - (fifo_count >= musb_ep->packet_sz)) + + if (request->short_not_ok && fifo_count == musb_ep->packet_sz) use_mode_1 = 1; else use_mode_1 = 0; @@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req) c = musb->dma_controller; channel = musb_ep->dma; + /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in + * mode 0 only. So we do not get endpoint interrupts due to DMA + * completion. We only get interrupts from DMA controller. + * + * We could operate in DMA mode 1 if we knew the size of the tranfer + * in advance. For mass storage class, request->length = what the host + * sends, so that'd work. But for pretty much everything else, + * request->length is routinely more than what the host sends. For + * most these gadgets, end of is signified either by a short packet, + * or filling the last byte of the buffer. (Sending extra data in + * that last pckate should trigger an overflow fault.) But in mode 1, + * we don't get DMA completion interrupt for short packets. + * + * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), + * to get endpoint interrupt on every DMA req, but that didn't seem + * to work reliably. + * + * REVISIT an updated g_file_storage can set req->short_not_ok, which + * then becomes usable as a runtime "use mode 1" hint... + */ + /* Experimental: Mode1 works with mass storage use cases */ if (use_mode_1) { csr |= MUSB_RXCSR_AUTOCLEAR; -- cgit v1.1 From 9a65d162e449145706aa7309a1be00e3c3d5c80e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 14:12:37 +0800 Subject: usb: musb: ux500: fix 'musbid' undeclared error in ux500_remove() commit 65b3d52d02a558fbfe08e43688e15390c5ab3067 (usb: musb: add musb_ida for multi instance support) used musbid in ux500_remove() but nerver declared it. I found this in x86_64 platform, but not sure whether this is a error on the correct ARCH. $ make drivers/usb/musb/ux500.o make[1]: Nothing to be done for `all'. make[1]: Nothing to be done for `relocs'. CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h UPD include/generated/utsrelease.h CALL scripts/checksyscalls.sh CC drivers/usb/musb/ux500.o drivers/usb/musb/ux500.c: In function 'ux500_probe': drivers/usb/musb/ux500.c:78:2: error: 'musbid' undeclared (first use in this function) drivers/usb/musb/ux500.c:78:2: note: each undeclared identifier is reported only once for each function it appears in make[1]: *** [drivers/usb/musb/ux500.o] Error 1 make: *** [drivers/usb/musb/ux500.o] Error 2 Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d62a91f..0e62f50 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev) struct platform_device *musb; struct ux500_glue *glue; struct clk *clk; - + int musbid; int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); -- cgit v1.1 From 98a1eebda3cb2a84ecf1f219bb3a95769033d1bf Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 10 Oct 2012 10:55:28 +0300 Subject: UBIFS: introduce categorized lprops counter This commit is a preparation for a subsequent bugfix. We introduce a counter for categorized lprops. Signed-off-by: Artem Bityutskiy Cc: stable@vger.kernel.org --- fs/ubifs/lprops.c | 6 ++++++ fs/ubifs/ubifs.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index e5a2a35..46190a7 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c @@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, default: ubifs_assert(0); } + lprops->flags &= ~LPROPS_CAT_MASK; lprops->flags |= cat; + c->in_a_category_cnt += 1; + ubifs_assert(c->in_a_category_cnt <= c->main_lebs); } /** @@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c, default: ubifs_assert(0); } + + c->in_a_category_cnt -= 1; + ubifs_assert(c->in_a_category_cnt >= 0); } /** diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 5486346..d133c27 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1183,6 +1183,8 @@ struct ubifs_debug_info; * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) * @freeable_cnt: number of freeable LEBs in @freeable_list + * @in_a_category_cnt: count of lprops which are in a certain category, which + * basically meants that they were loaded from the flash * * @ltab_lnum: LEB number of LPT's own lprops table * @ltab_offs: offset of LPT's own lprops table @@ -1412,6 +1414,7 @@ struct ubifs_info { struct list_head freeable_list; struct list_head frdi_idx_list; int freeable_cnt; + int in_a_category_cnt; int ltab_lnum; int ltab_offs; -- cgit v1.1 From a28ad42a4a0c6f302f488f26488b8b37c9b30024 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 9 Oct 2012 16:20:15 +0300 Subject: UBIFS: fix mounting problems after power cuts This is a bugfix for a problem with the following symptoms: 1. A power cut happens 2. After reboot, we try to mount UBIFS 3. Mount fails with "No space left on device" error message UBIFS complains like this: UBIFS error (pid 28225): grab_empty_leb: could not find an empty LEB The root cause of this problem is that when we mount, not all LEBs are categorized. Only those which were read are. However, the 'ubifs_find_free_leb_for_idx()' function assumes that all LEBs were categorized and 'c->freeable_cnt' is valid, which is a false assumption. This patch fixes the problem by teaching 'ubifs_find_free_leb_for_idx()' to always fall back to LPT scanning if no freeable LEBs were found. This problem was reported by few people in the past, but Brent Taylor was able to reproduce it and send me a flash image which cannot be mounted, which made it easy to hunt the bug. Kudos to Brent. Reported-by: Brent Taylor Signed-off-by: Artem Bityutskiy Cc: stable@vger.kernel.org --- fs/ubifs/find.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 28ec13a..2dcf3d4 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c @@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c) if (!lprops) { lprops = ubifs_fast_find_freeable(c); if (!lprops) { - ubifs_assert(c->freeable_cnt == 0); - if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { + /* + * The first condition means the following: go scan the + * LPT if there are uncategorized lprops, which means + * there may be freeable LEBs there (UBIFS does not + * store the information about freeable LEBs in the + * master node). + */ + if (c->in_a_category_cnt != c->main_lebs || + c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { + ubifs_assert(c->freeable_cnt == 0); lprops = scan_for_leb_for_idx(c); if (IS_ERR(lprops)) { err = PTR_ERR(lprops); -- cgit v1.1 From 8d6b00f5d639cfc28487ef412589e35b4e6ac7c7 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Fri, 19 Oct 2012 13:15:30 +0100 Subject: ARM: pxa: hx4700: Fix backlight PWM device number Recent changes to PXA PWM support changed the PXA27X PWM device numbering scheme. The linux-3.5 PXA PWM driver followed the hardware numbering scheme for the 4 PWMs, while the linux-3.6-rc1 PXA PWM driver has adopted a linear numbering scheme: Address Hardware 3.5 pwm_id 3.6-rc1 pwm_id 0x40b00000 PWM0 0 0 0x40b00010 PWM2 2 1 0x40c00000 PWM1 1 2 0x40c00010 PWM3 3 3 The hx4700 backlight uses PWM1 at 0x40c00000. Consequently the pwm_id must be changed from 1 to 2. This patch fixes the backlight PWM device number and at the same time moves from the legacy PWM API (pwm_id) to the new PWM API (pwm_lookup). Signed-off-by: Paul Parsons Cc: Thierry Reding Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/hx4700.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 5ecbd17..e2c6391 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = { */ static struct platform_pwm_backlight_data backlight_data = { - .pwm_id = 1, + .pwm_id = -1, /* Superseded by pwm_lookup */ .max_brightness = 200, .dft_brightness = 100, .pwm_period_ns = 30923, @@ -571,6 +572,10 @@ static struct platform_device backlight = { }, }; +static struct pwm_lookup hx4700_pwm_lookup[] = { + PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), +}; + /* * USB "Transceiver" */ @@ -872,6 +877,7 @@ static void __init hx4700_init(void) pxa_set_stuart_info(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); + pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); pxa_set_ficp_info(&ficp_info); pxa27x_set_i2c_power_info(NULL); -- cgit v1.1 From 510fcb0d331f314cd20d0067d56f29302846f47b Mon Sep 17 00:00:00 2001 From: Marko Katic Date: Thu, 25 Oct 2012 18:51:38 +0200 Subject: ARM: pxa/spitz_pm: Fix hang when resuming from STR Devices that use spitz_pm.c will fail to resume from STR (Suspend To Ram) when the charger plug is inserted or removed when a device is in STR mode. The culprit is a misconfigured gpio line - GPIO18. GPIO18 should be configured as a regular GPIO input but it gets configured as an alternate function GPIO18_RDY. And then later in postsuspend() it gets configured as a regular GPIO18 input line. Fix this by removing the GPIO18_RDY configuration so that GPIO18 only gets configured as a regular gpio input. Signed-off-by: Marko Katic Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/spitz_pm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 438f02f..842596d 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -86,10 +86,7 @@ static void spitz_discharge1(int on) gpio_set_value(SPITZ_GPIO_LED_GREEN, on); } -static unsigned long gpio18_config[] = { - GPIO18_RDY, - GPIO18_GPIO, -}; +static unsigned long gpio18_config = GPIO18_GPIO; static void spitz_presuspend(void) { @@ -112,7 +109,7 @@ static void spitz_presuspend(void) PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); - pxa2xx_mfp_config(&gpio18_config[0], 1); + pxa2xx_mfp_config(&gpio18_config, 1); gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); gpio_free(18); @@ -131,7 +128,6 @@ static void spitz_presuspend(void) static void spitz_postsuspend(void) { - pxa2xx_mfp_config(&gpio18_config[1], 1); } static int spitz_should_wakeup(unsigned int resume_on_alarm) -- cgit v1.1 From b2da55d9441cbdaf73c12403ed801b644d5ae5e3 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 28 Oct 2012 16:01:11 +0100 Subject: Regulator: core: Unregister when gpio request fails. If the gpio_request_one() fails, or returns EPROBE_DEFER, the regulator must be device_unregister()ed. When this is not done, there are WARNING: from sysfs: WARNING: at fs/sysfs/file.c:343 sysfs_open_file+0x238/0x268() Signed-off-by: Andrew Lunn Signed-off-by: Mark Brown --- drivers/regulator/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829c..aa4d28b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3365,7 +3365,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", config->ena_gpio, ret); - goto clean; + goto wash; } rdev->ena_gpio = config->ena_gpio; @@ -3449,6 +3449,7 @@ scrub: if (rdev->ena_gpio) gpio_free(rdev->ena_gpio); kfree(rdev->constraints); +wash: device_unregister(&rdev->dev); /* device core frees rdev */ rdev = ERR_PTR(ret); -- cgit v1.1 From 74549de1e439f59465b61b13b6b9de4eff76937f Mon Sep 17 00:00:00 2001 From: Miguel Vadillo Date: Mon, 29 Oct 2012 22:02:13 -0600 Subject: ARM: OMAP2+: clockdomain: Fix OMAP4 ISS clk domain to support only SWSUP Since CAM domain (ISS) has no module wake-up dependency with any other clock domain of the device and the dynamic dependency from L3_main_2 is always disabled, the domain needs to be in force wakeup in order to be able to access it for configure (sysconfig) it or use it. Also since there is no clock in the domain managed automatically by the hardware, there is no use to configure automatic clock domain transition. SW should keep the SW_WKUP domain transition as long as a module in the domain is required to be functional. Signed-off-by: Miguel Vadillo Signed-off-by: Benoit Cousson --- arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index b56d06b..95192a06 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, .wkdep_srcs = iss_wkup_sleep_deps, .sleepdep_srcs = iss_wkup_sleep_deps, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain l3_dss_44xx_clkdm = { -- cgit v1.1 From 613ad0e98c3596cd2524172fae2a795c3fc57e4a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 29 Oct 2012 22:02:13 -0600 Subject: ARM: OMAP: hwmod: wait for sysreset complete after enabling hwmod When waking up from off-mode, some IP blocks are reset automatically by hardware. For this reason, software must wait until the reset has completed before attempting to access the IP block. This patch fixes for example the bug introduced by commit 6c31b2150ff96755d24e0ab6d6fea08a7bf5c44c ("mmc: omap_hsmmc: remove access to SYSCONFIG register"), in which the MMC IP block is reset during off-mode entry, but the code expects the module to be already available during the execution of context restore. This version includes a fix from Kevin Hilman for GPIO problems on the 37xx EVM - thanks Kevin. Signed-off-by: Tero Kristo Cc: Paul Walmsley Cc: Benoit Cousson Cc: Venkatraman S Tested-by: Kevin Hilman Cc: Kevin Hilman [paul@pwsan.com: moved softreset wait code into separate function; call from top of _enable_sysc() rather than the bottom; include fix from Kevin Hilman for GPIO sluggishness] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 60 ++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b969ab1..70267d2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -422,6 +422,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) } /** + * _wait_softreset_complete - wait for an OCP softreset to complete + * @oh: struct omap_hwmod * to wait on + * + * Wait until the IP block represented by @oh reports that its OCP + * softreset is complete. This can be triggered by software (see + * _ocp_softreset()) or by hardware upon returning from off-mode (one + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT + * microseconds. Returns the number of microseconds waited. + */ +static int _wait_softreset_complete(struct omap_hwmod *oh) +{ + struct omap_hwmod_class_sysconfig *sysc; + u32 softrst_mask; + int c = 0; + + sysc = oh->class->sysc; + + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) + & softrst_mask), + MAX_MODULE_SOFTRESET_WAIT, c); + } + + return c; +} + +/** * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v * @oh: struct omap_hwmod * * @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) if (!oh->class->sysc) return; + /* + * Wait until reset has completed, this is needed as the IP + * block is reset automatically by hardware in some cases + * (off-mode for example), and the drivers require the + * IP to be ready when they access it + */ + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _enable_optional_clocks(oh); + _wait_softreset_complete(oh); + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _disable_optional_clocks(oh); + v = oh->_sysc_cache; sf = oh->class->sysc->sysc_flags; @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v, softrst_mask; + u32 v; int c = 0; int ret = 0; @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) if (oh->class->sysc->srst_udelay) udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) - omap_test_timeout((omap_hwmod_read(oh, - oh->class->sysc->syss_offs) - & SYSS_RESETDONE_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { - softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); - omap_test_timeout(!(omap_hwmod_read(oh, - oh->class->sysc->sysc_offs) - & softrst_mask), - MAX_MODULE_SOFTRESET_WAIT, c); - } - + c = _wait_softreset_complete(oh); if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", oh->name, MAX_MODULE_SOFTRESET_WAIT); -- cgit v1.1 From e6d41e8c697e07832efa4a85bf23438bc4c4e1b2 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:08 +0100 Subject: x86, AMD: Change Boris' email address Move to private email and put in maintained status. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-1-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 698b6ec..1ac581f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -6,7 +6,7 @@ * * Written by Jacob Shin - AMD, Inc. * - * Support: borislav.petkov@amd.com + * Maintained by: Borislav Petkov * * April 2006 * - added support for AMD Family 0x10 processors -- cgit v1.1 From 43aff26ce1684dae4bf75437b2733371106aa767 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:09 +0100 Subject: EDAC: Change Boris' email address My @amd.com address will be invalid soon so move to private email address. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-2-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- drivers/edac/amd64_edac.h | 2 +- drivers/edac/edac_stub.c | 2 +- drivers/edac/mce_amd_inj.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 8d48047..8c41396 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h @@ -33,7 +33,7 @@ * detection. The mods to Rev F required more family * information detection. * - * Changes/Fixes by Borislav Petkov : + * Changes/Fixes by Borislav Petkov : * - misc fixes and code cleanups * * This module is based on the following documents diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c index 6c86f6e..351945f 100644 --- a/drivers/edac/edac_stub.c +++ b/drivers/edac/edac_stub.c @@ -5,7 +5,7 @@ * * 2007 (c) MontaVista Software, Inc. * 2010 (c) Advanced Micro Devices Inc. - * Borislav Petkov + * Borislav Petkov * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 66b5151..2ae78f2 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c @@ -6,7 +6,7 @@ * This file may be distributed under the terms of the GNU General Public * License version 2. * - * Copyright (c) 2010: Borislav Petkov + * Copyright (c) 2010: Borislav Petkov * Advanced Micro Devices Inc. */ @@ -168,6 +168,6 @@ module_init(edac_init_mce_inject); module_exit(edac_exit_mce_inject); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Borislav Petkov "); +MODULE_AUTHOR("Borislav Petkov "); MODULE_AUTHOR("AMD Inc."); MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); -- cgit v1.1 From 487ba8e82ab98320e5d7c0f6ff6da3067505ff92 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:10 +0100 Subject: MAINTAINERS: Change Boris' email address Move to private mail address. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-3-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- MAINTAINERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1fa9074..e775b87 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2707,10 +2707,10 @@ F: include/linux/edac.h EDAC-AMD64 M: Doug Thompson -M: Borislav Petkov +M: Borislav Petkov L: linux-edac@vger.kernel.org W: bluesmoke.sourceforge.net -S: Supported +S: Maintained F: drivers/edac/amd64_edac* EDAC-E752X @@ -3703,7 +3703,7 @@ S: Maintained F: drivers/platform/x86/ideapad-laptop.c IDE/ATAPI DRIVERS -M: Borislav Petkov +M: Borislav Petkov L: linux-ide@vger.kernel.org S: Maintained F: Documentation/cdrom/ide-cd @@ -8147,7 +8147,7 @@ F: drivers/platform/x86 X86 MCE INFRASTRUCTURE M: Tony Luck -M: Borislav Petkov +M: Borislav Petkov L: linux-edac@vger.kernel.org S: Maintained F: arch/x86/kernel/cpu/mcheck/* -- cgit v1.1 From 943482d07e926128eed0482b879736f912c429e4 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 29 Oct 2012 18:51:38 +0100 Subject: x86, microcode_amd: Change email addresses, MAINTAINERS entry Signed-off-by: Andreas Herrmann Cc: lm-sensors@lm-sensors.org Cc: oprofile-list@lists.sf.net Cc: Stephane Eranian Cc: Robert Richter Cc: Borislav Petkov Cc: Jorg Roedel Cc: Rafael J. Wysocki Cc: Jean Delvare Cc: Guenter Roeck Link: http://lkml.kernel.org/r/20121029175138.GC5024@tweety Signed-off-by: Ingo Molnar --- MAINTAINERS | 4 ++-- arch/x86/kernel/microcode_amd.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index e775b87..1740370 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -534,9 +534,9 @@ F: drivers/iommu/amd_iommu*.[ch] F: include/linux/amd-iommu.h AMD MICROCODE UPDATE SUPPORT -M: Andreas Herrmann +M: Andreas Herrmann L: amd64-microcode@amd64.org -S: Supported +S: Maintained F: arch/x86/kernel/microcode_amd.c AMS (Apple Motion Sensor) DRIVER diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 7720ff5..b3e67ba 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -8,8 +8,8 @@ * Tigran Aivazian * * Maintainers: - * Andreas Herrmann - * Borislav Petkov + * Andreas Herrmann + * Borislav Petkov * * This driver allows to upgrade microcode on F10h AMD * CPUs and later. -- cgit v1.1 From 4cf7e71869268d5c9fa7e8005155aef94e140eb5 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 29 Oct 2012 18:53:25 +0100 Subject: MAINTAINERS: Update email address for Robert Richter Signed-off-by: Robert Richter Signed-off-by: Andreas Herrmann Cc: lm-sensors@lm-sensors.org Cc: oprofile-list@lists.sf.net Cc: Stephane Eranian Cc: Borislav Petkov Cc: =?iso-8859-1?Q?J=F6rg_R=F6del?= Cc: Rafael J. Wysocki Cc: Jean Delvare Cc: Guenter Roeck Link: http://lkml.kernel.org/r/20121029175325.GE5024@tweety Signed-off-by: Ingo Molnar --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1740370..a41344b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5363,7 +5363,7 @@ S: Maintained F: sound/drivers/opl4/ OPROFILE -M: Robert Richter +M: Robert Richter L: oprofile-list@lists.sf.net S: Maintained F: arch/*/include/asm/oprofile*.h -- cgit v1.1 From f49f4ab95c301dbccad0efe85296d908b8ae7ad4 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 29 Oct 2012 14:40:18 +0100 Subject: x86/ce4100: Fix pm_poweroff The CE4100 platform is currently missing a proper pm_poweroff implementation leading to poweroff making the CPU spin forever and the CE4100 platform does not enter a low-power mode where the external Power Management Unit can properly power off the system. Power off on this platform is implemented pretty much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at I/O port 0xcf9, the value 0x4. Signed-off-by: Florian Fainelli Acked-by: Sebastian Andrzej Siewior Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-2-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/platform/ce4100/ce4100.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 4c61b52..5de16e3 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -27,6 +27,18 @@ static int ce4100_i8042_detect(void) return 0; } +/* + * The CE4100 platform has an internal 8051 Microcontroller which is + * responsible for signaling to the external Power Management Unit the + * intention to reset, reboot or power off the system. This 8051 device has + * its command register mapped at I/O port 0xcf9 and the value 0x4 is used + * to power off the system. + */ +static void ce4100_power_off(void) +{ + outb(0x4, 0xcf9); +} + #ifdef CONFIG_SERIAL_8250 static unsigned int mem_serial_in(struct uart_port *p, int offset) @@ -143,4 +155,6 @@ void __init x86_ce4100_early_setup(void) x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; #endif + + pm_power_off = ce4100_power_off; } -- cgit v1.1 From d7959916026aaae60e1878ae33c7503b2cc4471d Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 29 Oct 2012 14:40:19 +0100 Subject: x86/ce4100: Fix reboot by forcing the reboot method to be KBD The default reboot is via ACPI for this platform, and the CEFDK bootloader actually supports this, but will issue a system power off instead of a real reboot. Setting the reboot method to be KBD instead of ACPI ensures proper system reboot. Acked-by: Sebastian Andrzej Siewior Signed-off-by: Maxime Bizon Signed-off-by: Florian Fainelli Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-3-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 5de16e3..92525cb 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -21,6 +21,7 @@ #include #include #include +#include static int ce4100_i8042_detect(void) { @@ -151,6 +152,15 @@ void __init x86_ce4100_early_setup(void) x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.pci.init = ce4100_pci_init; + /* + * By default, the reboot method is ACPI which is supported by the + * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue + * the bootloader will however issue a system power off instead of + * reboot. By using BOOT_KBD we ensure proper system reboot as + * expected. + */ + reboot_type = BOOT_KBD; + #ifdef CONFIG_X86_IO_APIC x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; -- cgit v1.1 From 37aeec36220c39f1b2e7118287d951fd9cfdd6b7 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 29 Oct 2012 14:40:20 +0100 Subject: x86/ce4100: Fix PCI configuration register access for devices without interrupts Some CE4100 devices such as the: - DFX module (01:0b.7) - entertainment encryption device (01:10.0) - multimedia controller (01:12.0) do not have a device interrupt at all. This patch fixes the PCI controller code to declare the missing PCI configuration register space, as well as a fixup method for forcing the interrupt pin to be 0 for these devices. This is required to ensure that pci drivers matching on these devices will be able to honor the various PCI subsystem calls touching the configuration space. Signed-off-by: Maxime Bizon Signed-off-by: Florian Fainelli Acked-by: Sebastian Andrzej Siewior Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-4-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/pci/ce4100.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 41bd2a2..b914e20 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c @@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value) reg_read(reg, value); } +static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&pci_config_lock, flags); + /* force interrupt pin value to 0 */ + *value = reg->sim_reg.value & 0xfff00ff; + raw_spin_unlock_irqrestore(&pci_config_lock, flags); +} + static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) @@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) + DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) @@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) + DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) + DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) }; static void __init init_sim_regs(void) -- cgit v1.1 From fe81ad1c2d8149323e4a63c5a3bf8b170597c8b7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 8 Oct 2012 15:15:46 +0900 Subject: ASoC: wm5102: Write register value corrections after SYSCLK is enabled Evalation of the WM5102 has identified a number of register values which should be written after SYSCLK is enabled on revision A in order to improve performance. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 552 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 551 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 1722b58..7394e73 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -42,6 +42,556 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); +static const struct reg_default wm5102_sysclk_reva_patch[] = { + { 0x3000, 0x2225 }, + { 0x3001, 0x3a03 }, + { 0x3002, 0x0225 }, + { 0x3003, 0x0801 }, + { 0x3004, 0x6249 }, + { 0x3005, 0x0c04 }, + { 0x3006, 0x0225 }, + { 0x3007, 0x5901 }, + { 0x3008, 0xe249 }, + { 0x3009, 0x030d }, + { 0x300a, 0x0249 }, + { 0x300b, 0x2c01 }, + { 0x300c, 0xe249 }, + { 0x300d, 0x4342 }, + { 0x300e, 0xe249 }, + { 0x300f, 0x73c0 }, + { 0x3010, 0x4249 }, + { 0x3011, 0x0c00 }, + { 0x3012, 0x0225 }, + { 0x3013, 0x1f01 }, + { 0x3014, 0x0225 }, + { 0x3015, 0x1e01 }, + { 0x3016, 0x0225 }, + { 0x3017, 0xfa00 }, + { 0x3018, 0x0000 }, + { 0x3019, 0xf000 }, + { 0x301a, 0x0000 }, + { 0x301b, 0xf000 }, + { 0x301c, 0x0000 }, + { 0x301d, 0xf000 }, + { 0x301e, 0x0000 }, + { 0x301f, 0xf000 }, + { 0x3020, 0x0000 }, + { 0x3021, 0xf000 }, + { 0x3022, 0x0000 }, + { 0x3023, 0xf000 }, + { 0x3024, 0x0000 }, + { 0x3025, 0xf000 }, + { 0x3026, 0x0000 }, + { 0x3027, 0xf000 }, + { 0x3028, 0x0000 }, + { 0x3029, 0xf000 }, + { 0x302a, 0x0000 }, + { 0x302b, 0xf000 }, + { 0x302c, 0x0000 }, + { 0x302d, 0xf000 }, + { 0x302e, 0x0000 }, + { 0x302f, 0xf000 }, + { 0x3030, 0x0225 }, + { 0x3031, 0x1a01 }, + { 0x3032, 0x0225 }, + { 0x3033, 0x1e00 }, + { 0x3034, 0x0225 }, + { 0x3035, 0x1f00 }, + { 0x3036, 0x6225 }, + { 0x3037, 0xf800 }, + { 0x3038, 0x0000 }, + { 0x3039, 0xf000 }, + { 0x303a, 0x0000 }, + { 0x303b, 0xf000 }, + { 0x303c, 0x0000 }, + { 0x303d, 0xf000 }, + { 0x303e, 0x0000 }, + { 0x303f, 0xf000 }, + { 0x3040, 0x2226 }, + { 0x3041, 0x3a03 }, + { 0x3042, 0x0226 }, + { 0x3043, 0x0801 }, + { 0x3044, 0x6249 }, + { 0x3045, 0x0c06 }, + { 0x3046, 0x0226 }, + { 0x3047, 0x5901 }, + { 0x3048, 0xe249 }, + { 0x3049, 0x030d }, + { 0x304a, 0x0249 }, + { 0x304b, 0x2c01 }, + { 0x304c, 0xe249 }, + { 0x304d, 0x4342 }, + { 0x304e, 0xe249 }, + { 0x304f, 0x73c0 }, + { 0x3050, 0x4249 }, + { 0x3051, 0x0c00 }, + { 0x3052, 0x0226 }, + { 0x3053, 0x1f01 }, + { 0x3054, 0x0226 }, + { 0x3055, 0x1e01 }, + { 0x3056, 0x0226 }, + { 0x3057, 0xfa00 }, + { 0x3058, 0x0000 }, + { 0x3059, 0xf000 }, + { 0x305a, 0x0000 }, + { 0x305b, 0xf000 }, + { 0x305c, 0x0000 }, + { 0x305d, 0xf000 }, + { 0x305e, 0x0000 }, + { 0x305f, 0xf000 }, + { 0x3060, 0x0000 }, + { 0x3061, 0xf000 }, + { 0x3062, 0x0000 }, + { 0x3063, 0xf000 }, + { 0x3064, 0x0000 }, + { 0x3065, 0xf000 }, + { 0x3066, 0x0000 }, + { 0x3067, 0xf000 }, + { 0x3068, 0x0000 }, + { 0x3069, 0xf000 }, + { 0x306a, 0x0000 }, + { 0x306b, 0xf000 }, + { 0x306c, 0x0000 }, + { 0x306d, 0xf000 }, + { 0x306e, 0x0000 }, + { 0x306f, 0xf000 }, + { 0x3070, 0x0226 }, + { 0x3071, 0x1a01 }, + { 0x3072, 0x0226 }, + { 0x3073, 0x1e00 }, + { 0x3074, 0x0226 }, + { 0x3075, 0x1f00 }, + { 0x3076, 0x6226 }, + { 0x3077, 0xf800 }, + { 0x3078, 0x0000 }, + { 0x3079, 0xf000 }, + { 0x307a, 0x0000 }, + { 0x307b, 0xf000 }, + { 0x307c, 0x0000 }, + { 0x307d, 0xf000 }, + { 0x307e, 0x0000 }, + { 0x307f, 0xf000 }, + { 0x3080, 0x2227 }, + { 0x3081, 0x3a03 }, + { 0x3082, 0x0227 }, + { 0x3083, 0x0801 }, + { 0x3084, 0x6255 }, + { 0x3085, 0x0c04 }, + { 0x3086, 0x0227 }, + { 0x3087, 0x5901 }, + { 0x3088, 0xe255 }, + { 0x3089, 0x030d }, + { 0x308a, 0x0255 }, + { 0x308b, 0x2c01 }, + { 0x308c, 0xe255 }, + { 0x308d, 0x4342 }, + { 0x308e, 0xe255 }, + { 0x308f, 0x73c0 }, + { 0x3090, 0x4255 }, + { 0x3091, 0x0c00 }, + { 0x3092, 0x0227 }, + { 0x3093, 0x1f01 }, + { 0x3094, 0x0227 }, + { 0x3095, 0x1e01 }, + { 0x3096, 0x0227 }, + { 0x3097, 0xfa00 }, + { 0x3098, 0x0000 }, + { 0x3099, 0xf000 }, + { 0x309a, 0x0000 }, + { 0x309b, 0xf000 }, + { 0x309c, 0x0000 }, + { 0x309d, 0xf000 }, + { 0x309e, 0x0000 }, + { 0x309f, 0xf000 }, + { 0x30a0, 0x0000 }, + { 0x30a1, 0xf000 }, + { 0x30a2, 0x0000 }, + { 0x30a3, 0xf000 }, + { 0x30a4, 0x0000 }, + { 0x30a5, 0xf000 }, + { 0x30a6, 0x0000 }, + { 0x30a7, 0xf000 }, + { 0x30a8, 0x0000 }, + { 0x30a9, 0xf000 }, + { 0x30aa, 0x0000 }, + { 0x30ab, 0xf000 }, + { 0x30ac, 0x0000 }, + { 0x30ad, 0xf000 }, + { 0x30ae, 0x0000 }, + { 0x30af, 0xf000 }, + { 0x30b0, 0x0227 }, + { 0x30b1, 0x1a01 }, + { 0x30b2, 0x0227 }, + { 0x30b3, 0x1e00 }, + { 0x30b4, 0x0227 }, + { 0x30b5, 0x1f00 }, + { 0x30b6, 0x6227 }, + { 0x30b7, 0xf800 }, + { 0x30b8, 0x0000 }, + { 0x30b9, 0xf000 }, + { 0x30ba, 0x0000 }, + { 0x30bb, 0xf000 }, + { 0x30bc, 0x0000 }, + { 0x30bd, 0xf000 }, + { 0x30be, 0x0000 }, + { 0x30bf, 0xf000 }, + { 0x30c0, 0x2228 }, + { 0x30c1, 0x3a03 }, + { 0x30c2, 0x0228 }, + { 0x30c3, 0x0801 }, + { 0x30c4, 0x6255 }, + { 0x30c5, 0x0c06 }, + { 0x30c6, 0x0228 }, + { 0x30c7, 0x5901 }, + { 0x30c8, 0xe255 }, + { 0x30c9, 0x030d }, + { 0x30ca, 0x0255 }, + { 0x30cb, 0x2c01 }, + { 0x30cc, 0xe255 }, + { 0x30cd, 0x4342 }, + { 0x30ce, 0xe255 }, + { 0x30cf, 0x73c0 }, + { 0x30d0, 0x4255 }, + { 0x30d1, 0x0c00 }, + { 0x30d2, 0x0228 }, + { 0x30d3, 0x1f01 }, + { 0x30d4, 0x0228 }, + { 0x30d5, 0x1e01 }, + { 0x30d6, 0x0228 }, + { 0x30d7, 0xfa00 }, + { 0x30d8, 0x0000 }, + { 0x30d9, 0xf000 }, + { 0x30da, 0x0000 }, + { 0x30db, 0xf000 }, + { 0x30dc, 0x0000 }, + { 0x30dd, 0xf000 }, + { 0x30de, 0x0000 }, + { 0x30df, 0xf000 }, + { 0x30e0, 0x0000 }, + { 0x30e1, 0xf000 }, + { 0x30e2, 0x0000 }, + { 0x30e3, 0xf000 }, + { 0x30e4, 0x0000 }, + { 0x30e5, 0xf000 }, + { 0x30e6, 0x0000 }, + { 0x30e7, 0xf000 }, + { 0x30e8, 0x0000 }, + { 0x30e9, 0xf000 }, + { 0x30ea, 0x0000 }, + { 0x30eb, 0xf000 }, + { 0x30ec, 0x0000 }, + { 0x30ed, 0xf000 }, + { 0x30ee, 0x0000 }, + { 0x30ef, 0xf000 }, + { 0x30f0, 0x0228 }, + { 0x30f1, 0x1a01 }, + { 0x30f2, 0x0228 }, + { 0x30f3, 0x1e00 }, + { 0x30f4, 0x0228 }, + { 0x30f5, 0x1f00 }, + { 0x30f6, 0x6228 }, + { 0x30f7, 0xf800 }, + { 0x30f8, 0x0000 }, + { 0x30f9, 0xf000 }, + { 0x30fa, 0x0000 }, + { 0x30fb, 0xf000 }, + { 0x30fc, 0x0000 }, + { 0x30fd, 0xf000 }, + { 0x30fe, 0x0000 }, + { 0x30ff, 0xf000 }, + { 0x3100, 0x222b }, + { 0x3101, 0x3a03 }, + { 0x3102, 0x222b }, + { 0x3103, 0x5803 }, + { 0x3104, 0xe26f }, + { 0x3105, 0x030d }, + { 0x3106, 0x626f }, + { 0x3107, 0x2c01 }, + { 0x3108, 0xe26f }, + { 0x3109, 0x4342 }, + { 0x310a, 0xe26f }, + { 0x310b, 0x73c0 }, + { 0x310c, 0x026f }, + { 0x310d, 0x0c00 }, + { 0x310e, 0x022b }, + { 0x310f, 0x1f01 }, + { 0x3110, 0x022b }, + { 0x3111, 0x1e01 }, + { 0x3112, 0x022b }, + { 0x3113, 0xfa00 }, + { 0x3114, 0x0000 }, + { 0x3115, 0xf000 }, + { 0x3116, 0x0000 }, + { 0x3117, 0xf000 }, + { 0x3118, 0x0000 }, + { 0x3119, 0xf000 }, + { 0x311a, 0x0000 }, + { 0x311b, 0xf000 }, + { 0x311c, 0x0000 }, + { 0x311d, 0xf000 }, + { 0x311e, 0x0000 }, + { 0x311f, 0xf000 }, + { 0x3120, 0x022b }, + { 0x3121, 0x0a01 }, + { 0x3122, 0x022b }, + { 0x3123, 0x1e00 }, + { 0x3124, 0x022b }, + { 0x3125, 0x1f00 }, + { 0x3126, 0x622b }, + { 0x3127, 0xf800 }, + { 0x3128, 0x0000 }, + { 0x3129, 0xf000 }, + { 0x312a, 0x0000 }, + { 0x312b, 0xf000 }, + { 0x312c, 0x0000 }, + { 0x312d, 0xf000 }, + { 0x312e, 0x0000 }, + { 0x312f, 0xf000 }, + { 0x3130, 0x0000 }, + { 0x3131, 0xf000 }, + { 0x3132, 0x0000 }, + { 0x3133, 0xf000 }, + { 0x3134, 0x0000 }, + { 0x3135, 0xf000 }, + { 0x3136, 0x0000 }, + { 0x3137, 0xf000 }, + { 0x3138, 0x0000 }, + { 0x3139, 0xf000 }, + { 0x313a, 0x0000 }, + { 0x313b, 0xf000 }, + { 0x313c, 0x0000 }, + { 0x313d, 0xf000 }, + { 0x313e, 0x0000 }, + { 0x313f, 0xf000 }, + { 0x3140, 0x0000 }, + { 0x3141, 0xf000 }, + { 0x3142, 0x0000 }, + { 0x3143, 0xf000 }, + { 0x3144, 0x0000 }, + { 0x3145, 0xf000 }, + { 0x3146, 0x0000 }, + { 0x3147, 0xf000 }, + { 0x3148, 0x0000 }, + { 0x3149, 0xf000 }, + { 0x314a, 0x0000 }, + { 0x314b, 0xf000 }, + { 0x314c, 0x0000 }, + { 0x314d, 0xf000 }, + { 0x314e, 0x0000 }, + { 0x314f, 0xf000 }, + { 0x3150, 0x0000 }, + { 0x3151, 0xf000 }, + { 0x3152, 0x0000 }, + { 0x3153, 0xf000 }, + { 0x3154, 0x0000 }, + { 0x3155, 0xf000 }, + { 0x3156, 0x0000 }, + { 0x3157, 0xf000 }, + { 0x3158, 0x0000 }, + { 0x3159, 0xf000 }, + { 0x315a, 0x0000 }, + { 0x315b, 0xf000 }, + { 0x315c, 0x0000 }, + { 0x315d, 0xf000 }, + { 0x315e, 0x0000 }, + { 0x315f, 0xf000 }, + { 0x3160, 0x0000 }, + { 0x3161, 0xf000 }, + { 0x3162, 0x0000 }, + { 0x3163, 0xf000 }, + { 0x3164, 0x0000 }, + { 0x3165, 0xf000 }, + { 0x3166, 0x0000 }, + { 0x3167, 0xf000 }, + { 0x3168, 0x0000 }, + { 0x3169, 0xf000 }, + { 0x316a, 0x0000 }, + { 0x316b, 0xf000 }, + { 0x316c, 0x0000 }, + { 0x316d, 0xf000 }, + { 0x316e, 0x0000 }, + { 0x316f, 0xf000 }, + { 0x3170, 0x0000 }, + { 0x3171, 0xf000 }, + { 0x3172, 0x0000 }, + { 0x3173, 0xf000 }, + { 0x3174, 0x0000 }, + { 0x3175, 0xf000 }, + { 0x3176, 0x0000 }, + { 0x3177, 0xf000 }, + { 0x3178, 0x0000 }, + { 0x3179, 0xf000 }, + { 0x317a, 0x0000 }, + { 0x317b, 0xf000 }, + { 0x317c, 0x0000 }, + { 0x317d, 0xf000 }, + { 0x317e, 0x0000 }, + { 0x317f, 0xf000 }, + { 0x3180, 0x2001 }, + { 0x3181, 0xf101 }, + { 0x3182, 0x0000 }, + { 0x3183, 0xf000 }, + { 0x3184, 0x0000 }, + { 0x3185, 0xf000 }, + { 0x3186, 0x0000 }, + { 0x3187, 0xf000 }, + { 0x3188, 0x0000 }, + { 0x3189, 0xf000 }, + { 0x318a, 0x0000 }, + { 0x318b, 0xf000 }, + { 0x318c, 0x0000 }, + { 0x318d, 0xf000 }, + { 0x318e, 0x0000 }, + { 0x318f, 0xf000 }, + { 0x3190, 0x0000 }, + { 0x3191, 0xf000 }, + { 0x3192, 0x0000 }, + { 0x3193, 0xf000 }, + { 0x3194, 0x0000 }, + { 0x3195, 0xf000 }, + { 0x3196, 0x0000 }, + { 0x3197, 0xf000 }, + { 0x3198, 0x0000 }, + { 0x3199, 0xf000 }, + { 0x319a, 0x0000 }, + { 0x319b, 0xf000 }, + { 0x319c, 0x0000 }, + { 0x319d, 0xf000 }, + { 0x319e, 0x0000 }, + { 0x319f, 0xf000 }, + { 0x31a0, 0x0000 }, + { 0x31a1, 0xf000 }, + { 0x31a2, 0x0000 }, + { 0x31a3, 0xf000 }, + { 0x31a4, 0x0000 }, + { 0x31a5, 0xf000 }, + { 0x31a6, 0x0000 }, + { 0x31a7, 0xf000 }, + { 0x31a8, 0x0000 }, + { 0x31a9, 0xf000 }, + { 0x31aa, 0x0000 }, + { 0x31ab, 0xf000 }, + { 0x31ac, 0x0000 }, + { 0x31ad, 0xf000 }, + { 0x31ae, 0x0000 }, + { 0x31af, 0xf000 }, + { 0x31b0, 0x0000 }, + { 0x31b1, 0xf000 }, + { 0x31b2, 0x0000 }, + { 0x31b3, 0xf000 }, + { 0x31b4, 0x0000 }, + { 0x31b5, 0xf000 }, + { 0x31b6, 0x0000 }, + { 0x31b7, 0xf000 }, + { 0x31b8, 0x0000 }, + { 0x31b9, 0xf000 }, + { 0x31ba, 0x0000 }, + { 0x31bb, 0xf000 }, + { 0x31bc, 0x0000 }, + { 0x31bd, 0xf000 }, + { 0x31be, 0x0000 }, + { 0x31bf, 0xf000 }, + { 0x31c0, 0x0000 }, + { 0x31c1, 0xf000 }, + { 0x31c2, 0x0000 }, + { 0x31c3, 0xf000 }, + { 0x31c4, 0x0000 }, + { 0x31c5, 0xf000 }, + { 0x31c6, 0x0000 }, + { 0x31c7, 0xf000 }, + { 0x31c8, 0x0000 }, + { 0x31c9, 0xf000 }, + { 0x31ca, 0x0000 }, + { 0x31cb, 0xf000 }, + { 0x31cc, 0x0000 }, + { 0x31cd, 0xf000 }, + { 0x31ce, 0x0000 }, + { 0x31cf, 0xf000 }, + { 0x31d0, 0x0000 }, + { 0x31d1, 0xf000 }, + { 0x31d2, 0x0000 }, + { 0x31d3, 0xf000 }, + { 0x31d4, 0x0000 }, + { 0x31d5, 0xf000 }, + { 0x31d6, 0x0000 }, + { 0x31d7, 0xf000 }, + { 0x31d8, 0x0000 }, + { 0x31d9, 0xf000 }, + { 0x31da, 0x0000 }, + { 0x31db, 0xf000 }, + { 0x31dc, 0x0000 }, + { 0x31dd, 0xf000 }, + { 0x31de, 0x0000 }, + { 0x31df, 0xf000 }, + { 0x31e0, 0x0000 }, + { 0x31e1, 0xf000 }, + { 0x31e2, 0x0000 }, + { 0x31e3, 0xf000 }, + { 0x31e4, 0x0000 }, + { 0x31e5, 0xf000 }, + { 0x31e6, 0x0000 }, + { 0x31e7, 0xf000 }, + { 0x31e8, 0x0000 }, + { 0x31e9, 0xf000 }, + { 0x31ea, 0x0000 }, + { 0x31eb, 0xf000 }, + { 0x31ec, 0x0000 }, + { 0x31ed, 0xf000 }, + { 0x31ee, 0x0000 }, + { 0x31ef, 0xf000 }, + { 0x31f0, 0x0000 }, + { 0x31f1, 0xf000 }, + { 0x31f2, 0x0000 }, + { 0x31f3, 0xf000 }, + { 0x31f4, 0x0000 }, + { 0x31f5, 0xf000 }, + { 0x31f6, 0x0000 }, + { 0x31f7, 0xf000 }, + { 0x31f8, 0x0000 }, + { 0x31f9, 0xf000 }, + { 0x31fa, 0x0000 }, + { 0x31fb, 0xf000 }, + { 0x31fc, 0x0000 }, + { 0x31fd, 0xf000 }, + { 0x31fe, 0x0000 }, + { 0x31ff, 0xf000 }, + { 0x024d, 0xff50 }, + { 0x0252, 0xff50 }, + { 0x0259, 0x0112 }, + { 0x025e, 0x0112 }, +}; + +static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct arizona *arizona = dev_get_drvdata(codec->dev); + struct regmap *regmap = codec->control_data; + const struct reg_default *patch = NULL; + int i, patch_size; + + switch (arizona->rev) { + case 0: + patch = wm5102_sysclk_reva_patch; + patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch); + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (patch) + for (i = 0; i < patch_size; i++) + regmap_write(regmap, patch[i].reg, + patch[i].def); + break; + + default: + break; + } + + return 0; +} + static const struct snd_kcontrol_new wm5102_snd_controls[] = { SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT, 1, 0), @@ -297,7 +847,7 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux = static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, - 0, NULL, 0), + 0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, -- cgit v1.1 From f6bc8c29383456b89ac1b6f1aa768d195670fb53 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 29 Oct 2012 16:44:46 +0200 Subject: usb: otg: Fix build errors if USB_MUSB_OMAP2PLUS is selected as module TWL4030_USB & TWL6030_USB must depend on USB_MUSB_OMAP2PLUS in Kconfig else we get build errors with CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_OMAP2PLUS=m CONFIG_TWL4030_USB=y CONFIG_TWL6030_USB=y LD init/built-in.o drivers/built-in.o: In function `twl4030_usb_irq': drivers/usb/otg/twl4030-usb.c:518: undefined reference to `omap_musb_mailbox' drivers/built-in.o: In function `twl4030_usb_phy_init': drivers/usb/otg/twl4030-usb.c:540: undefined reference to `omap_musb_mailbox' drivers/built-in.o: In function `twl6030_usb_irq': drivers/usb/otg/twl6030-usb.c:230: undefined reference to `omap_musb_mailbox' drivers/usb/otg/twl6030-usb.c:225: undefined reference to `omap_musb_mailbox' drivers/built-in.o: In function `twl6030_usbotg_irq': drivers/usb/otg/twl6030-usb.c:259: undefined reference to `omap_musb_mailbox' CC: Peter Meerwald Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index d8c8a42..6223062 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" - depends on TWL4030_CORE && REGULATOR_TWL4030 + depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL4030 @@ -68,7 +68,7 @@ config TWL4030_USB config TWL6030_USB tristate "TWL6030 USB Transceiver Driver" - depends on TWL4030_CORE && OMAP_USB2 + depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL6030 -- cgit v1.1 From 8e493ca1767d4951ed1322abaa74d6edbca29918 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 26 Oct 2012 18:44:20 +0200 Subject: USB: usb_wwan: fix bulk-urb allocation Make sure we do not allocate urbs if we do not have a bulk endpoint. Legacy code used incorrect assumption to test for bulk endpoints. Reported-by: Dan Carpenter Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 61a73ad..a3e9c09 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -455,9 +455,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, struct usb_serial *serial = port->serial; struct urb *urb; - if (endpoint == -1) - return NULL; /* endpoint not needed */ - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ if (urb == NULL) { dev_dbg(&serial->interface->dev, @@ -489,6 +486,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port) init_usb_anchor(&portdata->delayed); for (i = 0; i < N_IN_URB; i++) { + if (!port->bulk_in_size) + break; + buffer = (u8 *)__get_free_page(GFP_KERNEL); if (!buffer) goto bail_out_error; @@ -502,8 +502,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port) } for (i = 0; i < N_OUT_URB; i++) { - if (port->bulk_out_endpointAddress == -1) - continue; + if (!port->bulk_out_size) + break; buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); if (!buffer) -- cgit v1.1 From d99e65bda806f49e192dd31e9b01959974dea3cd Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 29 Oct 2012 16:45:54 +0000 Subject: USB: fix build with XEN and EARLY_PRINTK_DBGP enabled but USB_SUPPORT disabled Since there's no possible caller of dbgp_external_startup() and dbgp_reset_prep() when !USB_EHCI_HCD, there's no point in building and exporting these functions in that case. This eliminates a build error under the conditions listed in the subject, introduced with the merge f1c6872e4980bc4078cfaead05f892b3d78dea64. Reported-by: Randy Dunlap Signed-off-by: Jan Beulich Cc: Stefano Stabellini Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index e426ad6..4bfa78a 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -614,12 +615,6 @@ err: return -ENODEV; } -int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); -} -EXPORT_SYMBOL_GPL(dbgp_external_startup); - static int ehci_reset_port(int port) { u32 portsc; @@ -979,6 +974,7 @@ struct console early_dbgp_console = { .index = -1, }; +#if IS_ENABLED(CONFIG_USB_EHCI_HCD) int dbgp_reset_prep(struct usb_hcd *hcd) { int ret = xen_dbgp_reset_prep(hcd); @@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(dbgp_reset_prep); +int dbgp_external_startup(struct usb_hcd *hcd) +{ + return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); +} +EXPORT_SYMBOL_GPL(dbgp_external_startup); +#endif /* USB_EHCI_HCD */ + #ifdef CONFIG_KGDB static char kgdbdbgp_buf[DBGP_MAX_PACKET]; -- cgit v1.1 From 322337b8fbd8c392246529d5db924820fc0c7381 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Tue, 30 Oct 2012 15:37:09 +0530 Subject: ARM: dt: tegra: fix length of pad control and mux registers The reg property contains not . Fix the length values to be length not last_offset. Cc: stable@vger.kernel.org Signed-off-by: Pritesh Raithatha Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra30.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index b1497c7..df7f227 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -73,8 +73,8 @@ pinmux: pinmux { compatible = "nvidia,tegra30-pinmux"; - reg = <0x70000868 0xd0 /* Pad control registers */ - 0x70003000 0x3e0>; /* Mux registers */ + reg = <0x70000868 0xd4 /* Pad control registers */ + 0x70003000 0x3e4>; /* Mux registers */ }; serial@70006000 { -- cgit v1.1 From 85b97637bb40a9f486459dd254598759af9c3d50 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Mon, 29 Oct 2012 11:01:50 +0800 Subject: x86/mce: Do not change worker's running cpu in cmci_rediscover(). cmci_rediscover() used set_cpus_allowed_ptr() to change the current process's running cpu, and migrate itself to the dest cpu. But worker processes are not allowed to be migrated. If current is a worker, the worker will be migrated to another cpu, but the corresponding worker_pool is still on the original cpu. In this case, the following BUG_ON in try_to_wake_up_local() will be triggered: BUG_ON(rq != this_rq()); This will cause the kernel panic. The call trace is like the following: [ 6155.451107] ------------[ cut here ]------------ [ 6155.452019] kernel BUG at kernel/sched/core.c:1654! ...... [ 6155.452019] RIP: 0010:[] [] try_to_wake_up_local+0x115/0x130 ...... [ 6155.452019] Call Trace: [ 6155.452019] [] __schedule+0x764/0x880 [ 6155.452019] [] schedule+0x29/0x70 [ 6155.452019] [] schedule_timeout+0x235/0x2d0 [ 6155.452019] [] ? mark_held_locks+0x8d/0x140 [ 6155.452019] [] ? __lock_release+0x133/0x1a0 [ 6155.452019] [] ? _raw_spin_unlock_irq+0x30/0x50 [ 6155.452019] [] ? trace_hardirqs_on_caller+0x105/0x190 [ 6155.452019] [] wait_for_common+0x12b/0x180 [ 6155.452019] [] ? try_to_wake_up+0x2f0/0x2f0 [ 6155.452019] [] wait_for_completion+0x1d/0x20 [ 6155.452019] [] stop_one_cpu+0x8a/0xc0 [ 6155.452019] [] ? __migrate_task+0x1a0/0x1a0 [ 6155.452019] [] ? complete+0x28/0x60 [ 6155.452019] [] set_cpus_allowed_ptr+0x128/0x130 [ 6155.452019] [] cmci_rediscover+0xf5/0x140 [ 6155.452019] [] mce_cpu_callback+0x18d/0x19d [ 6155.452019] [] notifier_call_chain+0x67/0x150 [ 6155.452019] [] __raw_notifier_call_chain+0xe/0x10 [ 6155.452019] [] __cpu_notify+0x20/0x40 [ 6155.452019] [] cpu_notify_nofail+0x15/0x30 [ 6155.452019] [] _cpu_down+0x262/0x2e0 [ 6155.452019] [] cpu_down+0x36/0x50 [ 6155.452019] [] acpi_processor_remove+0x50/0x11e [ 6155.452019] [] acpi_device_remove+0x90/0xb2 [ 6155.452019] [] __device_release_driver+0x7c/0xf0 [ 6155.452019] [] device_release_driver+0x2f/0x50 [ 6155.452019] [] acpi_bus_remove+0x32/0x6d [ 6155.452019] [] acpi_bus_trim+0x87/0xee [ 6155.452019] [] acpi_bus_hot_remove_device+0x88/0x16b [ 6155.452019] [] acpi_os_execute_deferred+0x27/0x34 [ 6155.452019] [] process_one_work+0x219/0x680 [ 6155.452019] [] ? process_one_work+0x1b8/0x680 [ 6155.452019] [] ? acpi_os_wait_events_complete+0x23/0x23 [ 6155.452019] [] worker_thread+0x12e/0x320 [ 6155.452019] [] ? manage_workers+0x110/0x110 [ 6155.452019] [] kthread+0xc6/0xd0 [ 6155.452019] [] kernel_thread_helper+0x4/0x10 [ 6155.452019] [] ? retint_restore_args+0x13/0x13 [ 6155.452019] [] ? __init_kthread_worker+0x70/0x70 [ 6155.452019] [] ? gs_change+0x13/0x13 This patch removes the set_cpus_allowed_ptr() call, and put the cmci rediscover jobs onto all the other cpus using system_wq. This could bring some delay for the jobs. Signed-off-by: Tang Chen Signed-off-by: Miao Xie Signed-off-by: Tony Luck --- arch/x86/kernel/cpu/mcheck/mce_intel.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 5f88abf..4f9a3cb 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -285,34 +285,39 @@ void cmci_clear(void) raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); } +static long cmci_rediscover_work_func(void *arg) +{ + int banks; + + /* Recheck banks in case CPUs don't all have the same */ + if (cmci_supported(&banks)) + cmci_discover(banks); + + return 0; +} + /* * After a CPU went down cycle through all the others and rediscover * Must run in process context. */ void cmci_rediscover(int dying) { - int banks; - int cpu; - cpumask_var_t old; + int cpu, banks; if (!cmci_supported(&banks)) return; - if (!alloc_cpumask_var(&old, GFP_KERNEL)) - return; - cpumask_copy(old, ¤t->cpus_allowed); for_each_online_cpu(cpu) { if (cpu == dying) continue; - if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) + + if (cpu == smp_processor_id()) { + cmci_rediscover_work_func(NULL); continue; - /* Recheck banks in case CPUs don't all have the same */ - if (cmci_supported(&banks)) - cmci_discover(banks); - } + } - set_cpus_allowed_ptr(current, old); - free_cpumask_var(old); + work_on_cpu(cpu, cmci_rediscover_work_func, NULL); + } } /* -- cgit v1.1 From 5fb3d522efca4b3a369040d37d1380103411db74 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 29 Oct 2012 22:11:50 -0600 Subject: ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add HWMOD_EXT_OPT_MAIN_CLK flag to indicate that this IP block is dependent on an off-chip functional clock that is not guaranteed to be present during initialization. IP blocks marked with this flag are left in the INITIALIZED state during kernel init. This is a workaround for a hardware problem. It should be possible to guarantee that at least one clock source will be present and active for any IP block's main functional clock. This ensures that the hwmod code can enable and reset the IP block. Resetting the IP block during kernel init prevents any bogus bootloader, ROM code, or previous OS configuration from affecting the kernel. Hopefully a clock multiplexer can be added on future SoCs. N.B., at some point in the future, it should be possible to query the clock framework for this type of information. Then this flag should no longer be needed. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod.c | 3 +++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 70267d2..87cc6d0 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2384,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) if (oh->_state != _HWMOD_STATE_INITIALIZED) return -EINVAL; + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) + return -EPERM; + if (oh->rst_lines_cnt == 0) { r = _enable(oh); if (r) { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index b3349f7..1db0294 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for + * this IP block comes from an off-chip source and is not always + * enabled. This prevents the hwmod code from being able to + * enable and reset the IP block early. XXX Eventually it should + * be possible to query the clock framework for this information. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) /* * omap_hwmod._int_flags definitions -- cgit v1.1 From bc05244e65f26b7b6f87e0964bfe277803914ed9 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 29 Oct 2012 22:02:14 -0600 Subject: ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve this kernel boot message: omap_hwmod: mcpdm: cannot be enabled for reset (3) The McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init. At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code. This patch works around the issue by marking the McPDM hwmod record with the HWMOD_EXT_OPT_MAIN_CLK flag. This prevents the hwmod code from touching the device early during boot. Signed-off-by: Paul Walmsley Cc: Péter Ujfalusi Cc: Benoît Cousson Acked-by: Peter Ujfalusi --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d028..7bddfa5 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", + /* + * It's suspected that the McPDM requires an off-chip main + * functional clock, controlled via I2C. This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. + */ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", -- cgit v1.1 From 35f5149ead73e8e635b417b6c3aece43ffdfe5bc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 31 Oct 2012 15:50:34 +0100 Subject: mac80211: do not call ieee80211_configure_filter if no interfaces are up Drivers are not expected to handle it before drv_start has been called. It will be called again after an interface has been brought up. Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 05f3a31..7371f67 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2594,6 +2594,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, else local->probe_req_reg--; + if (!local->open_count) + break; + ieee80211_queue_work(&local->hw, &local->reconfig_filter); break; default: -- cgit v1.1 From bca1e29fb54c51856dda6772d488d41b10ed91da Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 29 Oct 2012 14:49:41 +0200 Subject: mac80211: init sched_scan_ies In case that there is an unsupported band, the ie will be unallocated and the free will crash. Cc: stable@vger.kernel.org Signed-off-by: David Spinadel Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c4cdbde..43e60b5 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -917,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, struct cfg80211_sched_scan_request *req) { struct ieee80211_local *local = sdata->local; - struct ieee80211_sched_scan_ies sched_scan_ies; + struct ieee80211_sched_scan_ies sched_scan_ies = {}; int ret, i; mutex_lock(&local->mtx); -- cgit v1.1 From 2bbf0a1427c377350f001fbc6260995334739ad7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 31 Oct 2012 17:20:50 +0100 Subject: x86, amd: Disable way access filter on Piledriver CPUs The Way Access Filter in recent AMD CPUs may hurt the performance of some workloads, caused by aliasing issues in the L1 cache. This patch disables it on the affected CPUs. The issue is similar to that one of last year: http://lkml.indiana.edu/hypermail/linux/kernel/1107.3/00041.html This new patch does not replace the old one, we just need another quirk for newer CPUs. The performance penalty without the patch depends on the circumstances, but is a bit less than the last year's 3%. The workloads affected would be those that access code from the same physical page under different virtual addresses, so different processes using the same libraries with ASLR or multiple instances of PIE-binaries. The code needs to be accessed simultaneously from both cores of the same compute unit. More details can be found here: http://developer.amd.com/Assets/SharedL1InstructionCacheonAMD15hCPU.pdf CPUs affected are anything with the core known as Piledriver. That includes the new parts of the AMD A-Series (aka Trinity) and the just released new CPUs of the FX-Series (aka Vishera). The model numbering is a bit odd here: FX CPUs have model 2, A-Series has model 10h, with possible extensions to 1Fh. Hence the range of model ids. Signed-off-by: Andre Przywara Link: http://lkml.kernel.org/r/1351700450-9277-1-git-send-email-osp@andrep.de Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/amd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f7e98a2..1b7d165 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } + /* + * The way access filter has a performance penalty on some workloads. + * Disable it on the affected CPUs. + */ + if ((c->x86 == 0x15) && + (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { + u64 val; + + if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { + val |= 0x1E; + wrmsrl_safe(0xc0011021, val); + } + } + cpu_detect_cache_sizes(c); /* Multi core CPU? */ -- cgit v1.1 From 39300ffb9b6666714c60735cf854e1280e4e75f4 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Nov 2012 00:16:34 -0400 Subject: tools/power turbostat: Repair Segmentation fault when using -i option Fix regression caused by commit 8e180f3cb6b7510a3bdf14e16ce87c9f5d86f102 (tools/power turbostat: add [-d MSR#][-D MSR#] options to print counter deltas) Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 2655ae9..9942dee 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1594,7 +1594,7 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { + while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) { switch (opt) { case 'p': show_core_only++; -- cgit v1.1 From d91bb17c2a874493603c4d99db305d8caf2d180c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Nov 2012 00:08:19 -0400 Subject: tools/power turbostat: graceful fail on garbage input When invald MSR's are specified on the command line, turbostat should simply print an error and exit. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 9942dee..ea095ab 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -206,8 +206,10 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) retval = pread(fd, msr, sizeof *msr, offset); close(fd); - if (retval != sizeof *msr) + if (retval != sizeof *msr) { + fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset); return -1; + } return 0; } @@ -1101,7 +1103,9 @@ void turbostat_loop() restart: retval = for_all_cpus(get_counters, EVEN_COUNTERS); - if (retval) { + if (retval < -1) { + exit(retval); + } else if (retval == -1) { re_initialize(); goto restart; } @@ -1114,7 +1118,9 @@ restart: } sleep(interval_sec); retval = for_all_cpus(get_counters, ODD_COUNTERS); - if (retval) { + if (retval < -1) { + exit(retval); + } else if (retval == -1) { re_initialize(); goto restart; } @@ -1126,7 +1132,9 @@ restart: flush_stdout(); sleep(interval_sec); retval = for_all_cpus(get_counters, EVEN_COUNTERS); - if (retval) { + if (retval < -1) { + exit(retval); + } else if (retval == -1) { re_initialize(); goto restart; } @@ -1545,8 +1553,11 @@ void turbostat_init() int fork_it(char **argv) { pid_t child_pid; + int status; - for_all_cpus(get_counters, EVEN_COUNTERS); + status = for_all_cpus(get_counters, EVEN_COUNTERS); + if (status) + exit(status); /* clear affinity side-effect of get_counters() */ sched_setaffinity(0, cpu_present_setsize, cpu_present_set); gettimeofday(&tv_even, (struct timezone *)NULL); @@ -1556,7 +1567,6 @@ int fork_it(char **argv) /* child */ execvp(argv[0], argv); } else { - int status; /* parent */ if (child_pid == -1) { @@ -1568,7 +1578,7 @@ int fork_it(char **argv) signal(SIGQUIT, SIG_IGN); if (waitpid(child_pid, &status, 0) == -1) { perror("wait"); - exit(1); + exit(status); } } /* @@ -1585,7 +1595,7 @@ int fork_it(char **argv) fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); - return 0; + return status; } void cmdline(int argc, char **argv) -- cgit v1.1 From 59fa6245192159ab5e1e17b8e31f15afa9cff4bf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 23 Oct 2012 22:29:38 +0200 Subject: futex: Handle futex_pi OWNER_DIED take over correctly Siddhesh analyzed a failure in the take over of pi futexes in case the owner died and provided a workaround. See: http://sourceware.org/bugzilla/show_bug.cgi?id=14076 The detailed problem analysis shows: Futex F is initialized with PTHREAD_PRIO_INHERIT and PTHREAD_MUTEX_ROBUST_NP attributes. T1 lock_futex_pi(F); T2 lock_futex_pi(F); --> T2 blocks on the futex and creates pi_state which is associated to T1. T1 exits --> exit_robust_list() runs --> Futex F userspace value TID field is set to 0 and FUTEX_OWNER_DIED bit is set. T3 lock_futex_pi(F); --> Succeeds due to the check for F's userspace TID field == 0 --> Claims ownership of the futex and sets its own TID into the userspace TID field of futex F --> returns to user space T1 --> exit_pi_state_list() --> Transfers pi_state to waiter T2 and wakes T2 via rt_mutex_unlock(&pi_state->mutex) T2 --> acquires pi_state->mutex and gains real ownership of the pi_state --> Claims ownership of the futex and sets its own TID into the userspace TID field of futex F --> returns to user space T3 --> observes inconsistent state This problem is independent of UP/SMP, preemptible/non preemptible kernels, or process shared vs. private. The only difference is that certain configurations are more likely to expose it. So as Siddhesh correctly analyzed the following check in futex_lock_pi_atomic() is the culprit: if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { We check the userspace value for a TID value of 0 and take over the futex unconditionally if that's true. AFAICT this check is there as it is correct for a different corner case of futexes: the WAITERS bit became stale. Now the proposed change - if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { + if (unlikely(ownerdied || + !(curval & (FUTEX_TID_MASK | FUTEX_WAITERS)))) { solves the problem, but it's not obvious why and it wreckages the "stale WAITERS bit" case. What happens is, that due to the WAITERS bit being set (T2 is blocked on that futex) it enforces T3 to go through lookup_pi_state(), which in the above case returns an existing pi_state and therefor forces T3 to legitimately fight with T2 over the ownership of the pi_state (via pi_state->mutex). Probelm solved! Though that does not work for the "WAITERS bit is stale" problem because if lookup_pi_state() does not find existing pi_state it returns -ERSCH (due to TID == 0) which causes futex_lock_pi() to return -ESRCH to user space because the OWNER_DIED bit is not set. Now there is a different solution to that problem. Do not look at the user space value at all and enforce a lookup of possibly available pi_state. If pi_state can be found, then the new incoming locker T3 blocks on that pi_state and legitimately races with T2 to acquire the rt_mutex and the pi_state and therefor the proper ownership of the user space futex. lookup_pi_state() has the correct order of checks. It first tries to find a pi_state associated with the user space futex and only if that fails it checks for futex TID value = 0. If no pi_state is available nothing can create new state at that point because this happens with the hash bucket lock held. So the above scenario changes to: T1 lock_futex_pi(F); T2 lock_futex_pi(F); --> T2 blocks on the futex and creates pi_state which is associated to T1. T1 exits --> exit_robust_list() runs --> Futex F userspace value TID field is set to 0 and FUTEX_OWNER_DIED bit is set. T3 lock_futex_pi(F); --> Finds pi_state and blocks on pi_state->rt_mutex T1 --> exit_pi_state_list() --> Transfers pi_state to waiter T2 and wakes it via rt_mutex_unlock(&pi_state->mutex) T2 --> acquires pi_state->mutex and gains ownership of the pi_state --> Claims ownership of the futex and sets its own TID into the userspace TID field of futex F --> returns to user space This covers all gazillion points on which T3 might come in between T1's exit_robust_list() clearing the TID field and T2 fixing it up. It also solves the "WAITERS bit stale" problem by forcing the take over. Another benefit of changing the code this way is that it makes it less dependent on untrusted user space values and therefor minimizes the possible wreckage which might be inflicted. As usual after staring for too long at the futex code my brain hurts so much that I really want to ditch that whole optimization of avoiding the syscall for the non contended case for PI futexes and rip out the maze of corner case handling code. Unfortunately we can't as user space relies on that existing behaviour, but at least thinking about it helps me to preserve my mental sanity. Maybe we should nevertheless :) Reported-and-tested-by: Siddhesh Poyarekar Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1210232138540.2756@ionos Acked-by: Darren Hart Cc: stable@vger.kernel.org Signed-off-by: Thomas Gleixner --- kernel/futex.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 3717e7b..20ef219 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, struct futex_pi_state **ps, struct task_struct *task, int set_waiters) { - int lock_taken, ret, ownerdied = 0; + int lock_taken, ret, force_take = 0; u32 uval, newval, curval, vpid = task_pid_vnr(task); retry: @@ -755,17 +755,15 @@ retry: newval = curval | FUTEX_WAITERS; /* - * There are two cases, where a futex might have no owner (the - * owner TID is 0): OWNER_DIED. We take over the futex in this - * case. We also do an unconditional take over, when the owner - * of the futex died. - * - * This is safe as we are protected by the hash bucket lock ! + * Should we force take the futex? See below. */ - if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { - /* Keep the OWNER_DIED bit */ + if (unlikely(force_take)) { + /* + * Keep the OWNER_DIED and the WAITERS bit and set the + * new TID value. + */ newval = (curval & ~FUTEX_TID_MASK) | vpid; - ownerdied = 0; + force_take = 0; lock_taken = 1; } @@ -775,7 +773,7 @@ retry: goto retry; /* - * We took the lock due to owner died take over. + * We took the lock due to forced take over. */ if (unlikely(lock_taken)) return 1; @@ -790,20 +788,25 @@ retry: switch (ret) { case -ESRCH: /* - * No owner found for this futex. Check if the - * OWNER_DIED bit is set to figure out whether - * this is a robust futex or not. + * We failed to find an owner for this + * futex. So we have no pi_state to block + * on. This can happen in two cases: + * + * 1) The owner died + * 2) A stale FUTEX_WAITERS bit + * + * Re-read the futex value. */ if (get_futex_value_locked(&curval, uaddr)) return -EFAULT; /* - * We simply start over in case of a robust - * futex. The code above will take the futex - * and return happy. + * If the owner died or we have a stale + * WAITERS bit the owner TID in the user space + * futex is 0. */ - if (curval & FUTEX_OWNER_DIED) { - ownerdied = 1; + if (!(curval & FUTEX_TID_MASK)) { + force_take = 1; goto retry; } default: -- cgit v1.1 From 9f4c3f1cde541d477633479a0203ef8a834ee5f9 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 31 Oct 2012 01:20:05 -0200 Subject: ASoC: mxs-saif: Add MODULE_ALIAS Add MODULE_ALIAS information. Signed-off-by: Fabio Estevam Acked-by: Dong Aisheng Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index aa037b2..93380cc 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -812,3 +812,4 @@ module_platform_driver(mxs_saif_driver); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("MXS ASoC SAIF driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mxs-saif"); -- cgit v1.1 From 213a79656462176b553c6f9cdf96e14313e43bcf Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 2 Nov 2012 13:02:53 +0000 Subject: ASoC: bells: Add missing select of WM0010 Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index e7b8317..fa166bd 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -207,6 +207,7 @@ config SND_SOC_BELLS select SND_SOC_WM5102 select SND_SOC_WM5110 select SND_SOC_WM9081 + select SND_SOC_WM0010 config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" -- cgit v1.1 From 4868ce57bfe1810262231dd8fe83fbba0ab59f13 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 2 Nov 2012 13:02:54 +0000 Subject: ASoC: bells: Select WM1250-EV1 Springbank audio I/O module Ensure we select the WM1250-EV1 as the current software system configuration demands it. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fa166bd..3c7c3a5 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -208,6 +208,7 @@ config SND_SOC_BELLS select SND_SOC_WM5110 select SND_SOC_WM9081 select SND_SOC_WM0010 + select SND_SOC_WM1250_EV1 config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" -- cgit v1.1 From f55f14752ecaccf7d6a52fd13929b73fcb191f19 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 1 Nov 2012 15:57:11 -0200 Subject: ASoC: mxs-saif: Fix channel swap for 24-bit format Playing 24-bit format file leads to channel swap on mx28 and the reason is that the current driver performs one write/read to/from the SAIF_DATA register to trigger the transfer. This approach works fine for S16_LE case because SAIF_DATA is a 32-bit register and thus is capable of storing the 16-bit left and right channels, but for the S24_LE case it can only store one channel, so in order to not lose the FIFO sync an extra read/write is needed. Reported-by: Dan Winner Signed-off-by: Fabio Estevam Tested-by: Dan Winner Acked-by: Dong Aisheng Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 93380cc..c294fbb 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -523,16 +523,24 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* - * write a data to saif data register to trigger - * the transfer + * write data to saif data register to trigger + * the transfer. + * For 24-bit format the 32-bit FIFO register stores + * only one channel, so we need to write twice. + * This is also safe for the other non 24-bit formats. */ __raw_writel(0, saif->base + SAIF_DATA); + __raw_writel(0, saif->base + SAIF_DATA); } else { /* - * read a data from saif data register to trigger - * the receive + * read data from saif data register to trigger + * the receive. + * For 24-bit format the 32-bit FIFO register stores + * only one channel, so we need to read twice. + * This is also safe for the other non 24-bit formats. */ __raw_readl(saif->base + SAIF_DATA); + __raw_readl(saif->base + SAIF_DATA); } master_saif->ongoing = 1; -- cgit v1.1 From 987c285c2ae2e4e32aca3a9b3252d28171c75711 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 5 Nov 2012 10:27:52 +0200 Subject: mac80211: sync acccess to tx_filtered/ps_tx_buf queues These are accessed without a lock when ending STA PSM. If the sta_cleanup timer accesses these lists at the same time, we might crash. This may fix some mysterious crashes we had during ieee80211_sta_ps_deliver_wakeup. Cc: stable@vger.kernel.org Signed-off-by: Arik Nemtsov Signed-off-by: Ido Yariv Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 797dd36..89ccd3e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -961,6 +961,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) struct ieee80211_local *local = sdata->local; struct sk_buff_head pending; int filtered = 0, buffered = 0, ac; + unsigned long flags; clear_sta_flag(sta, WLAN_STA_SP); @@ -976,12 +977,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int count = skb_queue_len(&pending), tmp; + spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); + spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); tmp = skb_queue_len(&pending); filtered += tmp - count; count = tmp; + spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); + spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); tmp = skb_queue_len(&pending); buffered += tmp - count; } -- cgit v1.1 From 7c34158231b2eda8dcbd297be2bb1559e69cb433 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 4 Nov 2012 09:29:17 +0100 Subject: iwlwifi: handle DMA mapping failures The RX replenish code doesn't handle DMA mapping failures, which will cause issues if there actually is a failure. This was reported by Shuah Khan who found a DMA mapping framework warning ("device driver failed to check map error"). Cc: stable@vger.kernel.org Reported-by: Shuah Khan Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/rx.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 17c8e5d..bb69f8f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) dma_map_page(trans->dev, page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); + if (dma_mapping_error(trans->dev, rxb->page_dma)) { + rxb->page = NULL; + spin_lock_irqsave(&rxq->lock, flags); + list_add(&rxb->list, &rxq->rx_used); + spin_unlock_irqrestore(&rxq->lock, flags); + __free_pages(page, trans_pcie->rx_page_order); + return; + } /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; + if (dma_mapping_error(trans->dev, rxb->page_dma)) { + /* + * free the page(s) as well to not break + * the invariant that the items on the used + * list have no page(s) + */ + __free_pages(rxb->page, trans_pcie->rx_page_order); + rxb->page = NULL; + list_add_tail(&rxb->list, &rxq->rx_used); + } else { + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } } else list_add_tail(&rxb->list, &rxq->rx_used); spin_unlock_irqrestore(&rxq->lock, flags); -- cgit v1.1 From 73c503cb981394872db41dd5cde385cb5373b4b9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 5 Nov 2012 15:46:36 -0800 Subject: ARM: OMAP4: PM: fix regulator name for VDD_MPU commit 24d7b40a (ARM: OMAP2+: PM: MPU DVFS: use generic CPU device for MPU-SS) updated the regulator name used for the MPU regulator, but only updated OMAP3, not OMAP4. Fix the OMAP4 name as well, otherwise CPUfreq fails to find the MPU regulator. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/twl-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109..44c4205 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -366,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { }; static struct regulator_consumer_supply omap4_vdd1_supply[] = { - REGULATOR_SUPPLY("vcc", "mpu.0"), + REGULATOR_SUPPLY("vcc", "cpu0"), }; static struct regulator_consumer_supply omap4_vdd2_supply[] = { -- cgit v1.1 From 55c6f4cb6ef49afbb86222c6a3ff85329199c729 Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Fri, 2 Nov 2012 17:05:44 -0400 Subject: ASoC: wm8978: pll incorrectly configured when codec is master When MCLK is supplied externally and BCLK and LRC are configured as outputs (codec is master), the PLL values are only calculated correctly on the first transmission. On subsequent transmissions, at differenct sample rates, the wrong PLL values are used. Test for f_opclk instead of f_pllout to determine if the PLL values are needed. Signed-off-by: Eric Millbrandt Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/wm8978.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 5421fd9..4c0a8e4 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream, wm8978->mclk_idx = -1; f_sel = wm8978->f_mclk; } else { - if (!wm8978->f_pllout) { + if (!wm8978->f_opclk) { /* We only enter here, if OPCLK is not used */ int ret = wm8978_configure_pll(codec); if (ret < 0) -- cgit v1.1 From 4a8dece21eea0ad6aca442272673d48693cd93b4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 5 Nov 2012 13:51:51 +0200 Subject: drm/i915/crt: fix DPMS standby and suspend mode handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCH platforms and VLV should map DPMS standby and suspend modes to off, but due to a buggy reversed comparison this is done on pre-PCH platforms instead. Reported-by: Loïc Yhuel Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56754 Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index b726b47..6345878 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) int old_dpms; /* PCH platforms and VLV only support on/off. */ - if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) + if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) mode = DRM_MODE_DPMS_OFF; if (mode == connector->dpms) -- cgit v1.1 From e32643544d8d9e7776daf0a4e803c57b54ba77f0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 25 Oct 2012 22:20:37 -0500 Subject: ARM: highbank: retry wfi on reset request In some cases, an interrupt can occur and prevent cause failure to enter wfi. This causes reset to hang. Retrying the wfi should be enough to prevent reset from hanging. Signed-off-by: Rob Herring Signed-off-by: Olof Johansson --- arch/arm/mach-highbank/system.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c index 82c27230..86e37cd 100644 --- a/arch/arm/mach-highbank/system.c +++ b/arch/arm/mach-highbank/system.c @@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd) hignbank_set_pwr_soft_reset(); scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); - cpu_do_idle(); + while (1) + cpu_do_idle(); } -- cgit v1.1 From 64e104771351d365e51e588a0e9a656ae6ed2f50 Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Tue, 6 Nov 2012 07:25:04 -0800 Subject: device_cgroup: fix unchecked cgroup parent usage In 4cef7299b478687 ("device_cgroup: add proper checking when changing default behavior") the cgroup parent usage is unchecked. root will not have a parent and trying to use device.{allow,deny} will cause problems. For some reason my stressing scripts didn't test the root directory so I didn't catch it on my regular tests. Signed-off-by: Aristeu Rozanski Cc: Li Zefan Cc: James Morris Cc: Pavel Emelyanov Acked-by: Serge E. Hallyn Cc: Jiri Slaby Cc: Tejun Heo Signed-off-by: Tejun Heo --- security/device_cgroup.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 842c254..96d87ea 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -352,6 +352,8 @@ static int parent_has_perm(struct dev_cgroup *childcg, */ static inline int may_allow_all(struct dev_cgroup *parent) { + if (!parent) + return 1; return parent->behavior == DEVCG_DEFAULT_ALLOW; } @@ -376,11 +378,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, int count, rc; struct dev_exception_item ex; struct cgroup *p = devcgroup->css.cgroup; - struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent); + struct dev_cgroup *parent = NULL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + if (p->parent) + parent = cgroup_to_devcgroup(p->parent); + memset(&ex, 0, sizeof(ex)); b = buffer; @@ -391,11 +396,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, if (!may_allow_all(parent)) return -EPERM; dev_exception_clean(devcgroup); + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; + if (!parent) + break; + rc = dev_exceptions_copy(&devcgroup->exceptions, &parent->exceptions); if (rc) return rc; - devcgroup->behavior = DEVCG_DEFAULT_ALLOW; break; case DEVCG_DENY: dev_exception_clean(devcgroup); -- cgit v1.1 From 36e42a323cf0de26bd819448b024d3851fc0d865 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 1 Nov 2012 22:02:50 -0600 Subject: irqchip: irq-bcm2835: Add terminating entry for of_device_id table The of_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- drivers/irqchip/irq-bcm2835.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index dc670cc..16c78f1 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c @@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node, } static struct of_device_id irq_of_match[] __initconst = { - { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } + { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, + { } }; void __init bcm2835_init_irq(void) -- cgit v1.1 From 201e72acb2d3821e2de9ce6091e98859c316b29a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 6 Nov 2012 09:17:37 -0800 Subject: device_cgroup: fix RCU usage dev_cgroup->exceptions is protected with devcgroup_mutex for writes and RCU for reads; however, RCU usage isn't correct. * dev_exception_clean() doesn't use RCU variant of list_del() and kfree(). The function can race with may_access() and may_access() may end up dereferencing already freed memory. Use list_del_rcu() and kfree_rcu() instead. * may_access() may be called only with RCU read locked but doesn't use RCU safe traversal over ->exceptions. Use list_for_each_entry_rcu(). Signed-off-by: Tejun Heo Acked-by: Serge E. Hallyn Cc: stable@vger.kernel.org Cc: Aristeu Rozanski Cc: Li Zefan --- security/device_cgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 96d87ea..b08d20c 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -164,8 +164,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup) struct dev_exception_item *ex, *tmp; list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { - list_del(&ex->list); - kfree(ex); + list_del_rcu(&ex->list); + kfree_rcu(ex, rcu); } } @@ -298,7 +298,7 @@ static int may_access(struct dev_cgroup *dev_cgroup, struct dev_exception_item *ex; bool match = false; - list_for_each_entry(ex, &dev_cgroup->exceptions, list) { + list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) continue; if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) -- cgit v1.1 From 31df3bb78be614fb9125abe56972dfee79bd3e18 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 31 Oct 2012 22:07:39 +0100 Subject: iwlwifi: use ieee80211_free_txskb To let mac80211 clean up any TX information when a frame is dropped, use ieee80211_free_txskb(). Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/dvm/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index ff8162d..fa4d1b8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwlagn_tx_skb(priv, control->sta, skb)) - dev_kfree_skb_any(skb); + ieee80211_free_txskb(hw, skb); } static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 7ff3f14..408132c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); - dev_kfree_skb_any(skb); + ieee80211_free_txskb(priv->hw, skb); } static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) -- cgit v1.1 From 6268f74990c7fab6727bcb2dc82b3c4d4b302317 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 6 Nov 2012 16:33:18 +0000 Subject: ASoC: bells: Correct type in sub speaker DAI name for WM5102 Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/samsung/bells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index b0d46d6..b56b9a3 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5110-aif3", + .cpu_dai_name = "wm5102-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -- cgit v1.1 From 5c855c8e2be67f2d5a989ef1190098f924f9f820 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 7 Nov 2012 20:38:35 +0800 Subject: ASoC: cs42l52: fix the return value of cs42l52_set_fmt() Fix the return value of cs42l52_set_fmt() when clock inversion is not allowed and also remove the useless variable ret. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) [We had been assigning to ret but then ignoring the value we assgined -- broonie] Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/cs42l52.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 6159929..f91136c 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -773,7 +773,6 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); - int ret = 0; u8 iface = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -822,7 +821,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) case SND_SOC_DAIFMT_NB_IF: break; default: - ret = -EINVAL; + return -EINVAL; } cs42l52->config.format = iface; snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); -- cgit v1.1 From 0133370f93eae5ed3c0f16d9da2b7add7dda6076 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 2 Nov 2012 13:44:46 +0530 Subject: drivers: bus: ocp2scp: add pdata support ocp2scp was not having pdata support which makes *musb* fail for non-dt boot in OMAP platform. The pdata will have information about the devices that is connected to ocp2scp. ocp2scp driver will now make use of this information to create the devices that is attached to ocp2scp. This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I Acked-by: Felipe Balbi [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- drivers/bus/omap-ocp2scp.c | 68 ++++++++++++++++++++++++++++-- include/linux/platform_data/omap_ocp2scp.h | 31 ++++++++++++++ 2 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 include/linux/platform_data/omap_ocp2scp.h diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c index ff63560..0c48b0e 100644 --- a/drivers/bus/omap-ocp2scp.c +++ b/drivers/bus/omap-ocp2scp.c @@ -22,6 +22,26 @@ #include #include #include +#include + +/** + * _count_resources - count for the number of resources + * @res: struct resource * + * + * Count and return the number of resources populated for the device that is + * connected to ocp2scp. + */ +static unsigned _count_resources(struct resource *res) +{ + int cnt = 0; + + while (res->start != res->end) { + cnt++; + res++; + } + + return cnt; +} static int ocp2scp_remove_devices(struct device *dev, void *c) { @@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c) static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) { - int ret; - struct device_node *np = pdev->dev.of_node; + int ret; + unsigned res_cnt, i; + struct device_node *np = pdev->dev.of_node; + struct platform_device *pdev_child; + struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data; + struct omap_ocp2scp_dev *dev; if (np) { ret = of_platform_populate(np, NULL, NULL, &pdev->dev); if (ret) { - dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n"); + dev_err(&pdev->dev, + "failed to add resources for ocp2scp child\n"); goto err0; } + } else if (pdata) { + for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++, + dev++) { + res_cnt = _count_resources(dev->res); + + pdev_child = platform_device_alloc(dev->drv_name, + PLATFORM_DEVID_AUTO); + if (!pdev_child) { + dev_err(&pdev->dev, + "failed to allocate mem for ocp2scp child\n"); + goto err0; + } + + ret = platform_device_add_resources(pdev_child, + dev->res, res_cnt); + if (ret) { + dev_err(&pdev->dev, + "failed to add resources for ocp2scp child\n"); + goto err1; + } + + pdev_child->dev.parent = &pdev->dev; + + ret = platform_device_add(pdev_child); + if (ret) { + dev_err(&pdev->dev, + "failed to register ocp2scp child device\n"); + goto err1; + } + } + } else { + dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n"); + return -EINVAL; } + pm_runtime_enable(&pdev->dev); return 0; +err1: + platform_device_put(pdev_child); + err0: device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); diff --git a/include/linux/platform_data/omap_ocp2scp.h b/include/linux/platform_data/omap_ocp2scp.h new file mode 100644 index 0000000..5c6c393 --- /dev/null +++ b/include/linux/platform_data/omap_ocp2scp.h @@ -0,0 +1,31 @@ +/* + * omap_ocp2scp.h -- ocp2scp header file + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Author: Kishon Vijay Abraham I + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __DRIVERS_OMAP_OCP2SCP_H +#define __DRIVERS_OMAP_OCP2SCP_H + +struct omap_ocp2scp_dev { + const char *drv_name; + struct resource *res; +}; + +struct omap_ocp2scp_platform_data { + int dev_cnt; + struct omap_ocp2scp_dev **devices; +}; +#endif /* __DRIVERS_OMAP_OCP2SCP_H */ -- cgit v1.1 From 637874ddb94a78e07ca8ce76ca500c62c4583535 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Sat, 27 Oct 2012 19:05:55 +0530 Subject: ARM: OMAP4: add _dev_attr_ to ocp2scp for representing usb_phy In order to reflect devices(usb_phy) attached to ocp2scp bus, ocp2scp is assigned a device attribute to represent the attached devices. This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I Cc: Benoit Cousson [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d028..cf579b5 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -2681,6 +2682,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { .sysc = &omap44xx_ocp2scp_sysc, }; +/* ocp2scp dev_attr */ +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { + { + .name = "usb_phy", + .start = 0x4a0ad080, + .end = 0x4a0ae000, + .flags = IORESOURCE_MEM, + }, + { + /* XXX: Remove this once control module driver is in place */ + .name = "ctrl_dev", + .start = 0x4a002300, + .end = 0x4a002303, + .flags = IORESOURCE_MEM, + }, + { } +}; + +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { + { + .drv_name = "omap-usb2", + .res = omap44xx_usb_phy_and_pll_addrs, + }, + { } +}; + /* ocp2scp_usb_phy */ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", @@ -2694,6 +2721,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .modulemode = MODULEMODE_HWCTRL, }, }, + .dev_attr = ocp2scp_dev_attr, }; /* -- cgit v1.1 From 459bc971eba0fe84b3fe857cf0a71c5fd102f06b Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Sat, 27 Oct 2012 19:05:56 +0530 Subject: ARM: OMAP: ocp2scp: create omap device for ocp2scp Platfrom device for ocp2scp is created using omap_device_build in devices file. This is used for both omap4(musb) and omap5(dwc3). This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index cba60e05..c72b5a7 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -613,6 +614,83 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) +{ + int cnt = 0; + + while (ocp2scp_dev->drv_name != NULL) { + cnt++; + ocp2scp_dev++; + } + + return cnt; +} + +static void omap_init_ocp2scp(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + int bus_id = -1, dev_cnt = 0, i; + struct omap_ocp2scp_dev *ocp2scp_dev; + const char *oh_name, *name; + struct omap_ocp2scp_platform_data *pdata; + + if (!cpu_is_omap44xx()) + return; + + oh_name = "ocp2scp_usb_phy"; + name = "omap-ocp2scp"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("%s: could not find omap_hwmod for %s\n", __func__, + oh_name); + return; + } + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for ocp2scp pdata\n", __func__); + return; + } + + ocp2scp_dev = oh->dev_attr; + dev_cnt = count_ocp2scp_devices(ocp2scp_dev); + + if (!dev_cnt) { + pr_err("%s: No devices connected to ocp2scp\n", __func__); + kfree(pdata); + return; + } + + pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) + * dev_cnt, GFP_KERNEL); + if (!pdata->devices) { + pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); + kfree(pdata); + return; + } + + for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) + pdata->devices[i] = ocp2scp_dev; + + pdata->dev_cnt = dev_cnt; + + pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, + 0, false); + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s %s\n", + name, oh_name); + kfree(pdata->devices); + kfree(pdata); + return; + } +} +#else +static inline void omap_init_ocp2scp(void) { } +#endif + /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void) omap_init_sham(); omap_init_aes(); omap_init_vout(); + omap_init_ocp2scp(); return 0; } -- cgit v1.1 From 5e767ab928088ca2a835b94b94dd286c2ca840ea Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 8 Oct 2012 10:47:34 +0200 Subject: ARM: OMAP: Add maintainer entry for IGEP machines Enric and I have been mantained this machine and while we are moving to device trees, it is good that people cc us when reporting bugs or regression on the board file until we have proper DT support. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 59203e7..8a398b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git F: arch/arm/mach-sa1100/jornada720.c F: arch/arm/mach-sa1100/include/mach/jornada720.h +ARM/IGEP MACHINE SUPPORT +M: Enric Balletbo i Serra +M: Javier Martinez Canillas +L: linux-omap@vger.kernel.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-omap2/board-igep0020.c + ARM/INCOME PXA270 SUPPORT M: Marek Vasut L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit v1.1 From cbf6bae1044286a89955d7c4b3a8d6d84a9916b3 Mon Sep 17 00:00:00 2001 From: Anders Hedlund Date: Mon, 29 Oct 2012 20:25:42 +0100 Subject: ARM: OMAP3: igep0020: Set WIFI/BT GPIO pins in correct mux mode Setup the WIFI/BT GPIO pin muxes to enable WIFI/BT functionality. This is needed to fix regression caused by recent versions of u-boot that only mux essential pins. Signed-off-by: Anders Hedlund Cc: Jonas Zetterberg Cc: Enric Balletbo i Serra Cc: Javier Martinez Canillas Cc: Matthias Brugger [tony@atomide.com: updated comments to describe regression] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-igep0020.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 48d5e41..3785906 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void) } else return; + /* Make sure that the GPIO pins are muxed correctly */ + omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); + err = gpio_request_array(igep_wlan_bt_gpios, ARRAY_SIZE(igep_wlan_bt_gpios)); if (err) { -- cgit v1.1 From cfff2f999d9baa561f20d999c8b83b03f078fb8f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Nov 2012 09:47:27 +0100 Subject: mac80211: fix memory leak in device registration error path If the cipher suites need to be allocated, but this allocation fails, this leaks the internal scan request. Fix that by going to the correct error handling label. Signed-off-by: Johannes Berg --- net/mac80211/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c80c449..f57f597 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -871,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); - if (!suites) - return -ENOMEM; + if (!suites) { + result = -ENOMEM; + goto fail_wiphy_register; + } for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || -- cgit v1.1 From f3f09d5a4462929609342460d756fab2e8151421 Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Sat, 31 Mar 2012 08:05:17 -0400 Subject: unicore32/mm/fault.c: Port OOM changes to do_pf Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable) The above commits introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable. These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation. Port these changes to unicore32. Signed-off-by: Kautuk Consul Acked-by: Guan Xuetao --- arch/unicore32/mm/fault.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 2eeb9c0..f9b5c10 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) } static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, - struct task_struct *tsk) + unsigned int flags, struct task_struct *tsk) { struct vm_area_struct *vma; int fault; @@ -194,14 +194,7 @@ good_area: * If for any reason at all we couldn't handle the fault, make * sure we exit gracefully rather than endlessly redo the fault. */ - fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, - (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); - if (unlikely(fault & VM_FAULT_ERROR)) - return fault; - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); return fault; check_stack: @@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); tsk = current; mm = tsk->mm; @@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!user_mode(regs) && !search_exception_tables(regs->UCreg_pc)) goto no_context; +retry: down_read(&mm->mmap_sem); } else { /* @@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) #endif } - fault = __do_pf(mm, addr, fsr, tsk); + fault = __do_pf(mm, addr, fsr, flags, tsk); + + /* If we need to retry but a fatal signal is pending, handle the + * signal first. We do not need to release the mmap_sem because + * it would already be released in __lock_page_or_retry in + * mm/filemap.c. */ + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return 0; + + if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; + if (fault & VM_FAULT_RETRY) { + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk + * of starvation. */ + flags &= ~FAULT_FLAG_ALLOW_RETRY; + goto retry; + } + } + up_read(&mm->mmap_sem); /* -- cgit v1.1 From 446d141e1c84d34c70592b53443b06533703c324 Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 12 Apr 2012 09:18:46 +0800 Subject: UniCore32 bugfix: add missed CONFIG_ZONE_DMA Because our PCI-bus handler confines dma zone into 128M, we should add CONFIG_ZONE_DMA for all boards. Otherwise, all memory bigger than 128M will be pushed into ZONE_MOVABLE. Cc: Arnd Bergmann Signed-off-by: Liu Guoli Signed-off-by: Guan Xuetao --- arch/unicore32/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index e5c5473..5b95ba4 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -64,6 +64,9 @@ config GENERIC_CALIBRATE_DELAY config ARCH_MAY_HAVE_PC_FDC bool +config ZONE_DMA + def_bool y + config NEED_DMA_MAP_STATE def_bool y -- cgit v1.1 From 195d4577d1d7ab1f0398b3190547c116b56f435f Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 14 Jun 2012 15:39:48 +0800 Subject: UniCore32-bugfix: fix mismatch return value of __xchg_bad_pointer When disintegrate system.h, I left an error in asm/cmpxchg.h, which will result in following error: arch/unicore32/include/asm/cmpxchg.h: In function '__xchg': arch/unicore32/include/asm/cmpxchg.h:38: error: void value not ignored as it ought to be Signed-off-by: Guan Xuetao --- arch/unicore32/include/asm/cmpxchg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h index df4d5ac..8e797ad 100644 --- a/arch/unicore32/include/asm/cmpxchg.h +++ b/arch/unicore32/include/asm/cmpxchg.h @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, : "memory", "cc"); break; default: - ret = __xchg_bad_pointer(); + __xchg_bad_pointer(); } return ret; -- cgit v1.1 From 10e1e99e55378a65529c48753703c069aebce7af Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 14 Jun 2012 11:38:25 +0800 Subject: UniCore32-bugfix: Remove definitions in asm/bug.h to solve difference between native and cross compiler For kernel/bound.c being compiled by native compiler, it will generate following errors in gcc 4.4.3: CC kernel/bounds.s In file included from include/linux/bug.h:4, from include/linux/page-flags.h:9, from kernel/bounds.c:9: arch/unicore32/include/asm/bug.h:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void' arch/unicore32/include/asm/bug.h:23: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void' So, we moved definitions in asm/bug.h to arch/unicore32/kernel/setup.h to solve the problem. Signed-off-by: Guan Xuetao --- arch/unicore32/include/asm/bug.h | 5 ----- arch/unicore32/kernel/setup.h | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index b1ff8ca..93a56f3 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h @@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); extern void uc32_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap); -extern asmlinkage void __backtrace(void); -extern asmlinkage void c_backtrace(unsigned long fp, int pmode); - -extern void __show_regs(struct pt_regs *); - #endif /* __UNICORE_BUG_H__ */ diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index f239550..30f749d 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; extern void kernel_thread_helper(void); extern void __init early_signal_init(void); + +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +extern void __show_regs(struct pt_regs *); + #endif -- cgit v1.1 From e8ce15a6d7ecdbabd8d04d78e065a2706459194f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 9 Oct 2012 09:47:48 +0100 Subject: UAPI: (Scripted) Disintegrate arch/unicore32/include/asm Signed-off-by: David Howells Acked-by: Arnd Bergmann Acked-by: Thomas Gleixner Acked-by: Michael Kerrisk Acked-by: Paul E. McKenney Acked-by: Dave Jones --- arch/unicore32/include/asm/Kbuild | 1 - arch/unicore32/include/asm/byteorder.h | 24 -------- arch/unicore32/include/asm/kvm_para.h | 1 - arch/unicore32/include/asm/ptrace.h | 76 +---------------------- arch/unicore32/include/asm/sigcontext.h | 29 --------- arch/unicore32/include/asm/unistd.h | 14 ----- arch/unicore32/include/uapi/asm/Kbuild | 5 ++ arch/unicore32/include/uapi/asm/byteorder.h | 24 ++++++++ arch/unicore32/include/uapi/asm/kvm_para.h | 1 + arch/unicore32/include/uapi/asm/ptrace.h | 90 ++++++++++++++++++++++++++++ arch/unicore32/include/uapi/asm/sigcontext.h | 29 +++++++++ arch/unicore32/include/uapi/asm/unistd.h | 14 +++++ 12 files changed, 164 insertions(+), 144 deletions(-) delete mode 100644 arch/unicore32/include/asm/byteorder.h delete mode 100644 arch/unicore32/include/asm/kvm_para.h delete mode 100644 arch/unicore32/include/asm/sigcontext.h delete mode 100644 arch/unicore32/include/asm/unistd.h create mode 100644 arch/unicore32/include/uapi/asm/byteorder.h create mode 100644 arch/unicore32/include/uapi/asm/kvm_para.h create mode 100644 arch/unicore32/include/uapi/asm/ptrace.h create mode 100644 arch/unicore32/include/uapi/asm/sigcontext.h create mode 100644 arch/unicore32/include/uapi/asm/unistd.h diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index c910c98..601e92f 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -1,4 +1,3 @@ -include include/asm-generic/Kbuild.asm generic-y += atomic.h generic-y += auxvec.h diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/asm/byteorder.h deleted file mode 100644 index ebe1b3f..0000000 --- a/arch/unicore32/include/asm/byteorder.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/byteorder.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * UniCore ONLY support Little Endian mode, the data bus is connected such - * that byte accesses appear as: - * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 - * and word accesses (data or instruction) appear as: - * d0...d31 - */ -#ifndef __UNICORE_BYTEORDER_H__ -#define __UNICORE_BYTEORDER_H__ - -#include - -#endif - diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h deleted file mode 100644 index 14fab8f..0000000 --- a/arch/unicore32/include/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h index b9caf9b..726749d 100644 --- a/arch/unicore32/include/asm/ptrace.h +++ b/arch/unicore32/include/asm/ptrace.h @@ -12,80 +12,10 @@ #ifndef __UNICORE_PTRACE_H__ #define __UNICORE_PTRACE_H__ -#define PTRACE_GET_THREAD_AREA 22 - -/* - * PSR bits - */ -#define USER_MODE 0x00000010 -#define REAL_MODE 0x00000011 -#define INTR_MODE 0x00000012 -#define PRIV_MODE 0x00000013 -#define ABRT_MODE 0x00000017 -#define EXTN_MODE 0x0000001b -#define SUSR_MODE 0x0000001f -#define MODE_MASK 0x0000001f -#define PSR_R_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_V_BIT 0x10000000 -#define PSR_C_BIT 0x20000000 -#define PSR_Z_BIT 0x40000000 -#define PSR_S_BIT 0x80000000 - -/* - * Groups of PSR bits - */ -#define PSR_f 0xff000000 /* Flags */ -#define PSR_c 0x000000ff /* Control */ +#include #ifndef __ASSEMBLY__ -/* - * This struct defines the way the registers are stored on the - * stack during a system call. Note that sizeof(struct pt_regs) - * has to be a multiple of 8. - */ -struct pt_regs { - unsigned long uregs[34]; -}; - -#define UCreg_asr uregs[32] -#define UCreg_pc uregs[31] -#define UCreg_lr uregs[30] -#define UCreg_sp uregs[29] -#define UCreg_ip uregs[28] -#define UCreg_fp uregs[27] -#define UCreg_26 uregs[26] -#define UCreg_25 uregs[25] -#define UCreg_24 uregs[24] -#define UCreg_23 uregs[23] -#define UCreg_22 uregs[22] -#define UCreg_21 uregs[21] -#define UCreg_20 uregs[20] -#define UCreg_19 uregs[19] -#define UCreg_18 uregs[18] -#define UCreg_17 uregs[17] -#define UCreg_16 uregs[16] -#define UCreg_15 uregs[15] -#define UCreg_14 uregs[14] -#define UCreg_13 uregs[13] -#define UCreg_12 uregs[12] -#define UCreg_11 uregs[11] -#define UCreg_10 uregs[10] -#define UCreg_09 uregs[9] -#define UCreg_08 uregs[8] -#define UCreg_07 uregs[7] -#define UCreg_06 uregs[6] -#define UCreg_05 uregs[5] -#define UCreg_04 uregs[4] -#define UCreg_03 uregs[3] -#define UCreg_02 uregs[2] -#define UCreg_01 uregs[1] -#define UCreg_00 uregs[0] -#define UCreg_ORIG_00 uregs[33] - -#ifdef __KERNEL__ - #define user_mode(regs) \ (processor_mode(regs) == USER_MODE) @@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->UCreg_pc) -#endif /* __KERNEL__ */ - #endif /* __ASSEMBLY__ */ - #endif - diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/asm/sigcontext.h deleted file mode 100644 index 6a2d767..0000000 --- a/arch/unicore32/include/asm/sigcontext.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/sigcontext.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __UNICORE_SIGCONTEXT_H__ -#define __UNICORE_SIGCONTEXT_H__ - -#include -/* - * Signal context structure - contains all info to do with the state - * before the signal handler was invoked. Note: only add new entries - * to the end of the structure. - */ -struct sigcontext { - unsigned long trap_no; - unsigned long error_code; - unsigned long oldmask; - unsigned long fault_address; - struct pt_regs regs; -}; - -#endif diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/asm/unistd.h deleted file mode 100644 index 2abcf61..0000000 --- a/arch/unicore32/include/asm/unistd.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/unistd.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Use the standard ABI for syscalls. */ -#include diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index baebb3d..a44b1c4 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -1,3 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +header-y += byteorder.h +header-y += kvm_para.h +header-y += ptrace.h +header-y += sigcontext.h +header-y += unistd.h diff --git a/arch/unicore32/include/uapi/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h new file mode 100644 index 0000000..ebe1b3f --- /dev/null +++ b/arch/unicore32/include/uapi/asm/byteorder.h @@ -0,0 +1,24 @@ +/* + * linux/arch/unicore32/include/asm/byteorder.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * UniCore ONLY support Little Endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __UNICORE_BYTEORDER_H__ +#define __UNICORE_BYTEORDER_H__ + +#include + +#endif + diff --git a/arch/unicore32/include/uapi/asm/kvm_para.h b/arch/unicore32/include/uapi/asm/kvm_para.h new file mode 100644 index 0000000..14fab8f --- /dev/null +++ b/arch/unicore32/include/uapi/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h new file mode 100644 index 0000000..187aa2e --- /dev/null +++ b/arch/unicore32/include/uapi/asm/ptrace.h @@ -0,0 +1,90 @@ +/* + * linux/arch/unicore32/include/asm/ptrace.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _UAPI__UNICORE_PTRACE_H__ +#define _UAPI__UNICORE_PTRACE_H__ + +#define PTRACE_GET_THREAD_AREA 22 + +/* + * PSR bits + */ +#define USER_MODE 0x00000010 +#define REAL_MODE 0x00000011 +#define INTR_MODE 0x00000012 +#define PRIV_MODE 0x00000013 +#define ABRT_MODE 0x00000017 +#define EXTN_MODE 0x0000001b +#define SUSR_MODE 0x0000001f +#define MODE_MASK 0x0000001f +#define PSR_R_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_S_BIT 0x80000000 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_c 0x000000ff /* Control */ + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the + * stack during a system call. Note that sizeof(struct pt_regs) + * has to be a multiple of 8. + */ +struct pt_regs { + unsigned long uregs[34]; +}; + +#define UCreg_asr uregs[32] +#define UCreg_pc uregs[31] +#define UCreg_lr uregs[30] +#define UCreg_sp uregs[29] +#define UCreg_ip uregs[28] +#define UCreg_fp uregs[27] +#define UCreg_26 uregs[26] +#define UCreg_25 uregs[25] +#define UCreg_24 uregs[24] +#define UCreg_23 uregs[23] +#define UCreg_22 uregs[22] +#define UCreg_21 uregs[21] +#define UCreg_20 uregs[20] +#define UCreg_19 uregs[19] +#define UCreg_18 uregs[18] +#define UCreg_17 uregs[17] +#define UCreg_16 uregs[16] +#define UCreg_15 uregs[15] +#define UCreg_14 uregs[14] +#define UCreg_13 uregs[13] +#define UCreg_12 uregs[12] +#define UCreg_11 uregs[11] +#define UCreg_10 uregs[10] +#define UCreg_09 uregs[9] +#define UCreg_08 uregs[8] +#define UCreg_07 uregs[7] +#define UCreg_06 uregs[6] +#define UCreg_05 uregs[5] +#define UCreg_04 uregs[4] +#define UCreg_03 uregs[3] +#define UCreg_02 uregs[2] +#define UCreg_01 uregs[1] +#define UCreg_00 uregs[0] +#define UCreg_ORIG_00 uregs[33] + + +#endif /* __ASSEMBLY__ */ + +#endif /* _UAPI__UNICORE_PTRACE_H__ */ diff --git a/arch/unicore32/include/uapi/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h new file mode 100644 index 0000000..6a2d767 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/sigcontext.h @@ -0,0 +1,29 @@ +/* + * linux/arch/unicore32/include/asm/sigcontext.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE_SIGCONTEXT_H__ +#define __UNICORE_SIGCONTEXT_H__ + +#include +/* + * Signal context structure - contains all info to do with the state + * before the signal handler was invoked. Note: only add new entries + * to the end of the structure. + */ +struct sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + unsigned long fault_address; + struct pt_regs regs; +}; + +#endif diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h new file mode 100644 index 0000000..2abcf61 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -0,0 +1,14 @@ +/* + * linux/arch/unicore32/include/asm/unistd.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Use the standard ABI for syscalls. */ +#include -- cgit v1.1 From ddd2d384b019d1733335c0fca7eccae3c29d2a14 Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Mon, 15 Oct 2012 14:41:36 +0800 Subject: unicore32: Use Kbuild infrastructure for kvm_para.h All the headers but kvm_para.h use the Kbuild infrastructure to get to the asm-generic headers. Cc: linux-kbuild@vger.kernel.org Signed-off-by: Steven Rostedt Signed-off-by: Guan Xuetao --- arch/unicore32/include/uapi/asm/Kbuild | 2 ++ arch/unicore32/include/uapi/asm/kvm_para.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 arch/unicore32/include/uapi/asm/kvm_para.h diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index a44b1c4..0514d7a 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -6,3 +6,5 @@ header-y += kvm_para.h header-y += ptrace.h header-y += sigcontext.h header-y += unistd.h + +generic-y += kvm_para.h diff --git a/arch/unicore32/include/uapi/asm/kvm_para.h b/arch/unicore32/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f..0000000 --- a/arch/unicore32/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include -- cgit v1.1 From 38e993535edda089a6956bf12a1dde2602649de9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Oct 2012 17:35:21 -0400 Subject: unicore32: switch to generic kernel_thread()/kernel_execve() Signed-off-by: Al Viro Acked-and-Tested-by: Guan Xuetao --- arch/unicore32/Kconfig | 2 ++ arch/unicore32/include/asm/processor.h | 5 --- arch/unicore32/kernel/entry.S | 15 ++++----- arch/unicore32/kernel/process.c | 58 ++++++++-------------------------- arch/unicore32/kernel/sys.c | 42 ------------------------ 5 files changed, 23 insertions(+), 99 deletions(-) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 5b95ba4..fda37c9 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -16,6 +16,8 @@ config UNICORE32 select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP select MODULES_USE_ELF_REL + select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h index 14382cb..4eaa421 100644 --- a/arch/unicore32/include/asm/processor.h +++ b/arch/unicore32/include/asm/processor.h @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() -/* - * Create a new kernel thread - */ -extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); - #define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index dcb87ab..32648c9 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail - get_thread_info tsk - ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing - mov why, #1 - cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? - beq ret_slow_syscall - mov r1, sp - mov r0, #1 @ trace exit [IP = 1] - b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) +ENTRY(ret_from_kernel_thread) + b.l schedule_tail + mov r0, r5 + adr lr, ret_slow_syscall + mov pc, r4 +ENDPROC(ret_from_kernel_thread) + /*============================================================================= * SWI handler *----------------------------------------------------------------------------- diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008586..a8fe265 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); - *childregs = *regs; - childregs->UCreg_00 = 0; - childregs->UCreg_sp = stack_start; - memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; - thread->cpu_context.pc = (unsigned long)ret_from_fork; - - if (clone_flags & CLONE_SETTLS) - childregs->UCreg_16 = regs->UCreg_03; + if (unlikely(!regs)) { + thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; + thread->cpu_context.r4 = stack_start; + thread->cpu_context.r5 = stk_sz; + memset(childregs, 0, sizeof(struct pt_regs)); + } else { + thread->cpu_context.pc = (unsigned long)ret_from_fork; + *childregs = *regs; + childregs->UCreg_00 = 0; + childregs->UCreg_sp = stack_start; + if (clone_flags & CLONE_SETTLS) + childregs->UCreg_16 = regs->UCreg_03; + } return 0; } @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); -/* - * Shuffle the argument into the correct register before calling the - * thread function. r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. - */ -asm(".pushsection .text\n" -" .align\n" -" .type kernel_thread_helper, #function\n" -"kernel_thread_helper:\n" -" mov.a asr, r7\n" -" mov r0, r4\n" -" mov lr, r6\n" -" mov pc, r5\n" -" .size kernel_thread_helper, . - kernel_thread_helper\n" -" .popsection"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.UCreg_04 = (unsigned long)arg; - regs.UCreg_05 = (unsigned long)fn; - regs.UCreg_06 = (unsigned long)do_exit; - regs.UCreg_07 = PRIV_MODE; - regs.UCreg_pc = (unsigned long)kernel_thread_helper; - regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; - - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index fabdee9..8b6e4cc 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -63,48 +63,6 @@ out: return error; } -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - struct pt_regs regs; - int ret; - - memset(®s, 0, sizeof(struct pt_regs)); - ret = do_execve(filename, - (const char __user *const __user *)argv, - (const char __user *const __user *)envp, ®s); - if (ret < 0) - goto out; - - /* - * Save argc to the register structure for userspace. - */ - regs.UCreg_00 = ret; - - /* - * We were successful. We won't be returning to our caller, but - * instead to user space by manipulating the kernel stack. - */ - asm("add r0, %0, %1\n\t" - "mov r1, %2\n\t" - "mov r2, %3\n\t" - "mov r22, #0\n\t" /* not a syscall */ - "mov r23, %0\n\t" /* thread structure */ - "b.l memmove\n\t" /* copy regs to top of stack */ - "mov sp, r0\n\t" /* reposition stack pointer */ - "b ret_to_user" - : - : "r" (current_thread_info()), - "Ir" (THREAD_START_SP - sizeof(regs)), - "r" (®s), - "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); - - out: - return ret; -} - /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, -- cgit v1.1 From 60541d778e536455970281de25b2476e01c03aef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Oct 2012 17:36:40 -0400 Subject: unicore32: switch to generic sys_execve() Signed-off-by: Al Viro Acked-and-Tested-by: Guan Xuetao --- arch/unicore32/include/uapi/asm/unistd.h | 1 + arch/unicore32/kernel/entry.S | 5 ----- arch/unicore32/kernel/sys.c | 21 --------------------- 3 files changed, 1 insertion(+), 26 deletions(-) diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 2abcf61..d18a3be8 100644 --- a/arch/unicore32/include/uapi/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -12,3 +12,4 @@ /* Use the standard ABI for syscalls. */ #include +#define __ARCH_WANT_SYS_EXECVE diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index 32648c9..7049350 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -668,11 +668,6 @@ __cr_alignment: #endif .ltorg -ENTRY(sys_execve) - add r3, sp, #S_OFF - b __sys_execve -ENDPROC(sys_execve) - ENTRY(sys_clone) add ip, sp, #S_OFF stw ip, [sp+], #4 diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index 8b6e4cc..9680134 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -42,27 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, parent_tid, child_tid); } -/* sys_execve() executes a new program. - * This is called indirectly via a small wrapper - */ -asmlinkage long __sys_execve(const char __user *filename, - const char __user *const __user *argv, - const char __user *const __user *envp, - struct pt_regs *regs) -{ - int error; - struct filename *fn; - - fn = getname(filename); - error = PTR_ERR(fn); - if (IS_ERR(fn)) - goto out; - error = do_execve(fn->name, argv, envp, regs); - putname(fn); -out: - return error; -} - /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, -- cgit v1.1 From c284464658acab50c67ff65ff3dc9215a0231ad2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:01:43 -0700 Subject: arch/unicore32: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Guan Xuetao Signed-off-by: Kees Cook Acked-by: Guan Xuetao --- arch/unicore32/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index fda37c9..c4fbb21 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -221,7 +221,7 @@ config PUV3_GPIO bool depends on !ARCH_FPGA select GENERIC_GPIO - select GPIO_SYSFS if EXPERIMENTAL + select GPIO_SYSFS default y if PUV3_NB0916 -- cgit v1.1 From 4870639a754991a52fc8f4ba82f0d9c247c33659 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 7 Nov 2012 12:54:21 +0100 Subject: MIPS: compat: Fix use of TIF_32BIT_ADDR vs _TIF_32BIT_ADDR Signed-off-by: Ralf Baechle --- arch/mips/include/asm/thread_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 8debe9e..d8323ea 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -115,7 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #ifdef CONFIG_MIPS32_O32 #define TIF_32BIT TIF_32BIT_REGS #elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT _TIF_32BIT_ADDR +#define TIF_32BIT TIF_32BIT_ADDR #endif /* CONFIG_MIPS32_O32 */ #define _TIF_SYSCALL_TRACE (1< Date: Thu, 8 Nov 2012 23:59:31 +0100 Subject: MIPS: compat: Implement is_compat_task() by testing for 32-bit address space. So far is_compat_task() was testing for 32-bit registers if O32 support was enabled and if O32 support was disabled but N32 enabled it was testing for 32-bit address space. So if both O32 and N32 were enabled a N32 task was not considered a compat task, whops. This still leaves potential cases where O32 and N32 need different treatment unsolved. But that's another commit. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 58277e0..3c5d146 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -290,7 +290,7 @@ struct compat_shmid64_ds { static inline int is_compat_task(void) { - return test_thread_flag(TIF_32BIT); + return test_thread_flag(TIF_32BIT_ADDR); } #endif /* _ASM_COMPAT_H */ -- cgit v1.1 From 34d875d7b579baab2f2f6dfd8e8533602d9dbf33 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 9 Nov 2012 00:28:59 +0100 Subject: MIPS: compat: Delete now unused TIF_32BIT. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/thread_info.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index d8323ea..18806a5 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ -#ifdef CONFIG_MIPS32_O32 -#define TIF_32BIT TIF_32BIT_REGS -#elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT TIF_32BIT_ADDR -#endif /* CONFIG_MIPS32_O32 */ - #define _TIF_SYSCALL_TRACE (1< Date: Thu, 6 Sep 2012 11:36:54 -0400 Subject: MIPS: bitops.h: Change use of 'unsigned short' to 'int' [ralf@linux-mips.org: No functional change but it's consistent with how use types elsewhere in the code.] Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4319/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bitops.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 82ad35c..455664c 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -57,7 +57,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -118,7 +118,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -191,7 +191,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad */ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); @@ -244,7 +244,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -310,7 +310,7 @@ static inline int test_and_set_bit(unsigned long nr, static inline int test_and_set_bit_lock(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -373,7 +373,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -457,7 +457,7 @@ static inline int test_and_clear_bit(unsigned long nr, static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); -- cgit v1.1 From 92d11594f688c8b55b51e80f2eac4417396237a4 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 6 Sep 2012 11:36:55 -0400 Subject: MIPS: Remove irqflags.h dependency from bitops.h The "else clause" of most functions in bitops.h invoked raw_local_irq_{save,restore}() and in doing so had a dependency on irqflags.h. This fix moves said code to bitops.c, removing the dependency. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4320/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/executive/cvmx-l2c.c | 1 + arch/mips/include/asm/bitops.h | 114 +++++------------ arch/mips/include/asm/io.h | 1 + arch/mips/lib/Makefile | 2 +- arch/mips/lib/bitops.c | 179 +++++++++++++++++++++++++++ 5 files changed, 214 insertions(+), 83 deletions(-) create mode 100644 arch/mips/lib/bitops.c diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index d38246e..9f883bf 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -30,6 +30,7 @@ * measurement, and debugging facilities. */ +#include #include #include #include diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 455664c..46ac73a 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -14,7 +14,6 @@ #endif #include -#include #include #include #include /* sigh ... */ @@ -44,6 +43,24 @@ #define smp_mb__before_clear_bit() smp_mb__before_llsc() #define smp_mb__after_clear_bit() smp_llsc_mb() + +/* + * These are the "slower" versions of the functions and are in bitops.c. + * These functions call raw_local_irq_{save,restore}(). + */ +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); +int __mips_test_and_set_bit(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_set_bit_lock(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_clear_bit(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_change_bit(unsigned long nr, + volatile unsigned long *addr); + + /* * set_bit - Atomically set a bit in memory * @nr: the bit to set @@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + __mips_set_bit(nr, addr); } /* @@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (~(1UL << bit))); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a &= ~mask; - raw_local_irq_restore(flags); - } + } else + __mips_clear_bit(nr, addr); } /* @@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a ^= mask; - raw_local_irq_restore(flags); - } + } else + __mips_change_bit(nr, addr); } /* @@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_set_bit(nr, addr); smp_llsc_mb(); @@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_set_bit_lock(nr, addr); smp_llsc_mb(); @@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a &= ~mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_clear_bit(nr, addr); smp_llsc_mb(); @@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a ^= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_change_bit(nr, addr); smp_llsc_mb(); diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 29d9c23..ff2e034 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index c4a82e8..a7b89371 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o delay.o memcpy.o memset.o \ +lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ strlen_user.o strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c new file mode 100644 index 0000000..239a9c9 --- /dev/null +++ b/arch/mips/lib/bitops.c @@ -0,0 +1,179 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (c) 1999, 2000 Silicon Graphics, Inc. + */ +#include +#include +#include + + +/** + * __mips_set_bit - Atomically set a bit in memory. This is called by + * set_bit() if it cannot find a faster solution. + * @nr: the bit to set + * @addr: the address to start counting from + */ +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a |= mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_set_bit); + + +/** + * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if + * it cannot find a faster solution. + * @nr: Bit to clear + * @addr: Address to start counting from + */ +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a &= ~mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_clear_bit); + + +/** + * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() + * if it cannot find a faster solution. + * @nr: Bit to change + * @addr: Address to start counting from + */ +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a ^= mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_change_bit); + + +/** + * __mips_test_and_set_bit - Set a bit and return its old value. This is + * called by test_and_set_bit() if it cannot find a faster solution. + * @nr: Bit to set + * @addr: Address to count from + */ +int __mips_test_and_set_bit(unsigned long nr, + volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_set_bit); + + +/** + * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is + * called by test_and_set_bit_lock() if it cannot find a faster solution. + * @nr: Bit to set + * @addr: Address to count from + */ +int __mips_test_and_set_bit_lock(unsigned long nr, + volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_set_bit_lock); + + +/** + * __mips_test_and_clear_bit - Clear a bit and return its old value. This is + * called by test_and_clear_bit() if it cannot find a faster solution. + * @nr: Bit to clear + * @addr: Address to count from + */ +int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a &= ~mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_clear_bit); + + +/** + * __mips_test_and_change_bit - Change a bit and return its old value. This is + * called by test_and_change_bit() if it cannot find a faster solution. + * @nr: Bit to change + * @addr: Address to count from + */ +int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a ^= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_change_bit); -- cgit v1.1 From e97c5b609880d97313b13eb71830fca62cee50c2 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 6 Sep 2012 11:36:56 -0400 Subject: MIPS: Make irqflags.h functions preempt-safe for non-mipsr2 cpus For non MIPSr2 processors, such as the BMIPS 5000, calls to arch_local_irq_disable() and others may be preempted, and in doing so a stale value may be restored to c0_status. This fix disables preemption for such processors prior to the call and enables it after the call. Those functions that needed this fix have been "outlined" to mips-atomic.c, as they are no longer good candidates for inlining. This bug was observed in a BMIPS 5000, occuring once every few hours in a continuous reboot test. It was traced to the write_lock_irq() function which was being invoked in release_task() in exit.c. By placing a number of "nops" inbetween the mfc0/mtc0 pair in arch_local_irq_disable(), which is called by write_lock_irq(), we were able to greatly increase the occurance of this bug. Similarly, the application of this commit silenced the bug. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4321/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/irqflags.h | 207 ++++++++++++++------------------------- arch/mips/lib/Makefile | 3 +- arch/mips/lib/mips-atomic.c | 176 +++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 133 deletions(-) create mode 100644 arch/mips/lib/mips-atomic.c diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 309cbcd..9f3384c 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -16,83 +16,13 @@ #include #include -__asm__( - " .macro arch_local_irq_enable \n" - " .set push \n" - " .set reorder \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" - " ori $1, 0x400 \n" - " xori $1, 0x400 \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) - " ei \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1e \n" - " mtc0 $1,$12 \n" -#endif - " irq_enable_hazard \n" - " .set pop \n" - " .endm"); +#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) -extern void smtc_ipi_replay(void); - -static inline void arch_local_irq_enable(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of call overhead on each local_irq_enable() - */ - smtc_ipi_replay(); -#endif - __asm__ __volatile__( - "arch_local_irq_enable" - : /* no outputs */ - : /* no inputs */ - : "memory"); -} - - -/* - * For cli() we have to insert nops to make sure that the new value - * has actually arrived in the status register before the end of this - * macro. - * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs - * no nops at all. - */ -/* - * For TX49, operating only IE bit is not enough. - * - * If mfc0 $12 follows store and the mfc0 is last instruction of a - * page and fetching the next instruction causes TLB miss, the result - * of the mfc0 might wrongly contain EXL bit. - * - * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 - * - * Workaround: mask EXL bit of the result or place a nop before mfc0. - */ __asm__( " .macro arch_local_irq_disable\n" " .set push \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 \n" - " ori $1, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) " di \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1f \n" - " .set noreorder \n" - " mtc0 $1,$12 \n" -#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) : "memory"); } -__asm__( - " .macro arch_local_save_flags flags \n" - " .set push \n" - " .set reorder \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\flags, $2, 1 \n" -#else - " mfc0 \\flags, $12 \n" -#endif - " .set pop \n" - " .endm \n"); - -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - asm volatile("arch_local_save_flags %0" : "=r" (flags)); - return flags; -} __asm__( " .macro arch_local_irq_save result \n" " .set push \n" " .set reorder \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\result, $2, 1 \n" - " ori $1, \\result, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" - " andi \\result, \\result, 0x400 \n" -#elif defined(CONFIG_CPU_MIPSR2) " di \\result \n" " andi \\result, 1 \n" -#else - " mfc0 \\result, $12 \n" - " ori $1, \\result, 0x1f \n" - " xori $1, 0x1f \n" - " .set noreorder \n" - " mtc0 $1, $12 \n" -#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) return flags; } + __asm__( " .macro arch_local_irq_restore flags \n" " .set push \n" " .set noreorder \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - "mfc0 $1, $2, 1 \n" - "andi \\flags, 0x400 \n" - "ori $1, 0x400 \n" - "xori $1, 0x400 \n" - "or \\flags, $1 \n" - "mtc0 \\flags, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_CPU) /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. */ " beqz \\flags, 1f \n" - " di \n" + " di \n" " ei \n" "1: \n" -#elif defined(CONFIG_CPU_MIPSR2) +#else /* * Fast, dangerous. Life is fun, life is good. */ " mfc0 $1, $12 \n" " ins $1, \\flags, 0, 1 \n" " mtc0 $1, $12 \n" -#else - " mfc0 $1, $12 \n" - " andi \\flags, 1 \n" - " ori $1, 0x1f \n" - " xori $1, 0x1f \n" - " or \\flags, $1 \n" - " mtc0 \\flags, $12 \n" #endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); - static inline void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of branch and call overhead on each - * local_irq_restore() - */ - if (unlikely(!(flags & 0x0400))) - smtc_ipi_replay(); -#endif - __asm__ __volatile__( "arch_local_irq_restore\t%0" : "=r" (__tmp1) @@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); } +#else +/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ +void arch_local_irq_disable(void); +unsigned long arch_local_irq_save(void); +void arch_local_irq_restore(unsigned long flags); +void __arch_local_irq_restore(unsigned long flags); +#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ + + +__asm__( + " .macro arch_local_irq_enable \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" + " ori $1, 0x400 \n" + " xori $1, 0x400 \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + " ei \n" +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1e \n" + " mtc0 $1,$12 \n" +#endif + " irq_enable_hazard \n" + " .set pop \n" + " .endm"); + +extern void smtc_ipi_replay(void); + +static inline void arch_local_irq_enable(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of call overhead on each local_irq_enable() + */ + smtc_ipi_replay(); +#endif + __asm__ __volatile__( + "arch_local_irq_enable" + : /* no outputs */ + : /* no inputs */ + : "memory"); +} + + +__asm__( + " .macro arch_local_save_flags flags \n" + " .set push \n" + " .set reorder \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\flags, $2, 1 \n" +#else + " mfc0 \\flags, $12 \n" +#endif + " .set pop \n" + " .endm \n"); + +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + asm volatile("arch_local_save_flags %0" : "=r" (flags)); + return flags; +} + static inline int arch_irqs_disabled_flags(unsigned long flags) { @@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) #endif } -#endif +#endif /* #ifndef __ASSEMBLY__ */ /* * Do the CPU's IRQ-state tracing from assembly code. diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index a7b89371..eeddc58 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -3,7 +3,8 @@ # lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ - strlen_user.o strncpy_user.o strnlen_user.o uncached.o + mips-atomic.o strlen_user.o strncpy_user.o \ + strnlen_user.o uncached.o obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c new file mode 100644 index 0000000..e091430 --- /dev/null +++ b/arch/mips/lib/mips-atomic.c @@ -0,0 +1,176 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle + * Copyright (C) 1996 by Paul M. Antoine + * Copyright (C) 1999 Silicon Graphics + * Copyright (C) 2000 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include + +#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) + +/* + * For cli() we have to insert nops to make sure that the new value + * has actually arrived in the status register before the end of this + * macro. + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs + * no nops at all. + */ +/* + * For TX49, operating only IE bit is not enough. + * + * If mfc0 $12 follows store and the mfc0 is last instruction of a + * page and fetching the next instruction causes TLB miss, the result + * of the mfc0 might wrongly contain EXL bit. + * + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 + * + * Workaround: mask EXL bit of the result or place a nop before mfc0. + */ +__asm__( + " .macro arch_local_irq_disable\n" + " .set push \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 \n" + " ori $1, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1f \n" + " .set noreorder \n" + " mtc0 $1,$12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +void arch_local_irq_disable(void) +{ + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_disable" + : /* no outputs */ + : /* no inputs */ + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(arch_local_irq_disable); + + +__asm__( + " .macro arch_local_irq_save result \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\result, $2, 1 \n" + " ori $1, \\result, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" + " andi \\result, \\result, 0x400 \n" +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 \\result, $12 \n" + " ori $1, \\result, 0x1f \n" + " xori $1, 0x1f \n" + " .set noreorder \n" + " mtc0 $1, $12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + preempt_disable(); + asm volatile("arch_local_irq_save\t%0" + : "=r" (flags) + : /* no inputs */ + : "memory"); + preempt_enable(); + return flags; +} +EXPORT_SYMBOL(arch_local_irq_save); + + +__asm__( + " .macro arch_local_irq_restore flags \n" + " .set push \n" + " .set noreorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + "mfc0 $1, $2, 1 \n" + "andi \\flags, 0x400 \n" + "ori $1, 0x400 \n" + "xori $1, 0x400 \n" + "or \\flags, $1 \n" + "mtc0 \\flags, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) + /* see irqflags.h for inline function */ +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 $1, $12 \n" + " andi \\flags, 1 \n" + " ori $1, 0x1f \n" + " xori $1, 0x1f \n" + " or \\flags, $1 \n" + " mtc0 \\flags, $12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +void arch_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of branch and call overhead on each + * local_irq_restore() + */ + if (unlikely(!(flags & 0x0400))) + smtc_ipi_replay(); +#endif + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(arch_local_irq_restore); + + +void __arch_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(__arch_local_irq_restore); + +#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ -- cgit v1.1 From c36a7ff4578ab6294885aef5ef241aeec4cdb1f0 Mon Sep 17 00:00:00 2001 From: Jiri Engelthaler Date: Thu, 20 Sep 2012 16:49:50 +0200 Subject: mtd: slram: invalid checking of absolute end address Fixed parsing end absolute address. Signed-off-by: Jiri Engelthaler Cc: stable@vger.kernel.org Signed-off-by: Artem Bityutskiy --- drivers/mtd/devices/slram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 8f52fc8..5a5cd2a 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) if (*(szlength) != '+') { devlength = simple_strtoul(szlength, &buffer, 0); - devlength = handle_unit(devlength, buffer) - devstart; + devlength = handle_unit(devlength, buffer); if (devlength < devstart) goto err_out; -- cgit v1.1 From 0131950ebd146b5e31508233352d6f4625af25b1 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 22 Sep 2012 11:42:31 +0530 Subject: mtd: onenand: Make flexonenand_set_boundary static Fixes the following sparse warning: drivers/mtd/onenand/onenand_base.c:3697:5: warning: symbol 'flexonenand_set_boundary' was not declared. Should it be static? Signed-off-by: Sachin Kamat Acked-by: Kyungmin Park Signed-off-by: Artem Bityutskiy --- drivers/mtd/onenand/onenand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 7153e0d2..b3f41f2 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int * flexonenand_set_boundary - Writes the SLC boundary * @param mtd - mtd info structure */ -int flexonenand_set_boundary(struct mtd_info *mtd, int die, +static int flexonenand_set_boundary(struct mtd_info *mtd, int die, int boundary, int lock) { struct onenand_chip *this = mtd->priv; -- cgit v1.1 From 5ffd3412ae5536a4c57469cb8ea31887121dcb2e Mon Sep 17 00:00:00 2001 From: Thomas Betker Date: Wed, 17 Oct 2012 22:59:30 +0200 Subject: jffs2: Fix lock acquisition order bug in jffs2_write_begin jffs2_write_begin() first acquires the page lock, then f->sem. This causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first acquires f->sem, then the page lock: jffs2_garbage_collect_live mutex_lock(&f->sem) (A) jffs2_garbage_collect_dnode jffs2_gc_fetch_page read_cache_page_async do_read_cache_page lock_page(page) (B) jffs2_write_begin grab_cache_page_write_begin find_lock_page lock_page(page) (B) mutex_lock(&f->sem) (A) We fix this by restructuring jffs2_write_begin() to take f->sem before the page lock. However, we make sure that f->sem is not held when calling jffs2_reserve_space(), as this is not permitted by the locking rules. The deadlock above was observed multiple times on an SoC with a dual ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred when using scp to copy files from a host system to the ARM target system. The fix was heavily tested on the same target system. Cc: stable@vger.kernel.org Signed-off-by: Thomas Betker Acked-by: Joakim Tjernlund Signed-off-by: Artem Bityutskiy --- fs/jffs2/file.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 60ef3fb..1506673 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -138,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct page *pg; struct inode *inode = mapping->host; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); + struct jffs2_raw_inode ri; + uint32_t alloc_len = 0; pgoff_t index = pos >> PAGE_CACHE_SHIFT; uint32_t pageofs = index << PAGE_CACHE_SHIFT; int ret = 0; + jffs2_dbg(1, "%s()\n", __func__); + + if (pageofs > inode->i_size) { + ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + if (ret) + return ret; + } + + mutex_lock(&f->sem); pg = grab_cache_page_write_begin(mapping, index, flags); - if (!pg) + if (!pg) { + if (alloc_len) + jffs2_complete_reservation(c); + mutex_unlock(&f->sem); return -ENOMEM; + } *pagep = pg; - jffs2_dbg(1, "%s()\n", __func__); - - if (pageofs > inode->i_size) { + if (alloc_len) { /* Make new hole frag from old EOF to new page */ - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; - uint32_t alloc_len; jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", (unsigned int)inode->i_size, pageofs); - ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, - ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); - if (ret) - goto out_page; - - mutex_lock(&f->sem); memset(&ri, 0, sizeof(ri)); ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -191,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, if (IS_ERR(fn)) { ret = PTR_ERR(fn); jffs2_complete_reservation(c); - mutex_unlock(&f->sem); goto out_page; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); @@ -206,12 +211,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); jffs2_complete_reservation(c); - mutex_unlock(&f->sem); goto out_page; } jffs2_complete_reservation(c); inode->i_size = pageofs; - mutex_unlock(&f->sem); } /* @@ -220,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, * case of a short-copy. */ if (!PageUptodate(pg)) { - mutex_lock(&f->sem); ret = jffs2_do_readpage_nolock(inode, pg); - mutex_unlock(&f->sem); if (ret) goto out_page; } + mutex_unlock(&f->sem); jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); return ret; out_page: unlock_page(pg); page_cache_release(pg); + mutex_unlock(&f->sem); return ret; } -- cgit v1.1 From 476e44cb19f1fbf2d5883dddcc0ce31b33b45915 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 19 Oct 2012 20:10:46 +0300 Subject: Bluetooth: Fix having bogus entries in mgmt_read_index_list reply The mgmt_read_index_list uses one loop to calculate the max needed size of its response with the help of an upper-bound of the controller count. The second loop is more strict as it checks for HCI_SETUP (which might have gotten set after the first loop) and could result in some indexes being skipped. Because of this the function needs to readjust the event length and index count after filling in the response array. Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index aa2ea0a..2cfabe2 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_dev *d; size_t rp_len; u16 count; - int i, err; + int err; BT_DBG("sock %p", sk); @@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, return -ENOMEM; } - rp->num_controllers = cpu_to_le16(count); - - i = 0; + count = 0; list_for_each_entry(d, &hci_dev_list, list) { if (test_bit(HCI_SETUP, &d->dev_flags)) continue; @@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (!mgmt_valid_hdev(d)) continue; - rp->index[i++] = cpu_to_le16(d->id); + rp->index[count++] = cpu_to_le16(d->id); BT_DBG("Added hci%u", d->id); } + rp->num_controllers = cpu_to_le16(count); + rp_len = sizeof(*rp) + (2 * count); + read_unlock(&hci_dev_list_lock); err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, -- cgit v1.1 From 896ea28ea824d49671fc7e9315d9c5be491a644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20S=C3=A9rgio?= Date: Thu, 25 Oct 2012 16:55:51 -0300 Subject: Bluetooth: Fix error status when pairing fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pairing fails due to wrong confirm value, the management layer doesn't report a proper error status. It sends MGMT_STATUS_CONNECT_FAILED instead of MGMT_STATUS_AUTH_FAILED. Most of management functions that receive a status as a parameter expects for it to be encoded as a HCI status. But when a SMP pairing fails, the SMP layer sends the SMP reason as the error status to the management layer. This commit maps all SMP reasons to HCI_ERROR_AUTH_FAILURE, which will be converted to MGMT_STATUS_AUTH_FAILED in the management layer. Reported-by: Claudio Takahasi Reviewed-by: João Paulo Rechi Vita Signed-off-by: Paulo Sérgio Signed-off-by: Gustavo Padovan --- net/bluetooth/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2ac8d50..a592337 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, - hcon->dst_type, reason); + hcon->dst_type, HCI_ERROR_AUTH_FAILURE); cancel_delayed_work_sync(&conn->security_timer); -- cgit v1.1 From fbe96d6ff9f4e361e1b2ec0a30140e17af7e3854 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 Oct 2012 01:35:40 -0700 Subject: Bluetooth: Notify about device registration before power on It is important that the monitor interface gets notified about a new device before its power on procedure has been started. For some reason that is no longer working as expected and the power on procedure runs first. It is safe to just notify about device registration and trigger the power on procedure afterwards. Signed-off-by: Marcel Holtmann Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8a0ce70..a0a2f97 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) if (hdev->dev_type != HCI_AMP) set_bit(HCI_AUTO_OFF, &hdev->dev_flags); - schedule_work(&hdev->power_on); - hci_notify(hdev, HCI_DEV_REG); hci_dev_hold(hdev); + schedule_work(&hdev->power_on); + return id; err_wqueue: -- cgit v1.1 From acd9454433e28c1a365d8b069813c35c1c3a8ac3 Mon Sep 17 00:00:00 2001 From: Marcos Chaparro Date: Tue, 6 Nov 2012 16:19:11 -0300 Subject: Bluetooth: ath3k: Add support for VAIO VPCEH [0489:e027] Added Atheros AR3011 internal bluetooth device found in Sony VAIO VPCEH to the devices list. Before this, the bluetooth module was identified as an Foxconn / Hai bluetooth device [0489:e027], now it claims to be an AtherosAR3011 Bluetooth [0cf3:3005]. T: Bus=01 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e027 Rev= 0.01 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Marcos Chaparro Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 1 + drivers/bluetooth/btusb.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fc2de55..b00000e 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, + { USB_DEVICE(0x0489, 0xE027) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index debda27..ee82f2f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, -- cgit v1.1 From 482049f75750d73358e65236b933417b69f9cc25 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 8 Nov 2012 10:25:26 +0100 Subject: Bluetooth: Fix memory leak when removing a UUID When removing a UUID from the list in the remove_uuid() function we must also kfree the entry in addition to removing it from the list. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2cfabe2..91de423 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1367,6 +1367,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, continue; list_del(&match->list); + kfree(match); found++; } -- cgit v1.1 From 20f544eea03db4b498942558b882d463ce575c3e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Nov 2012 14:06:28 +0100 Subject: mac80211: don't send null data packet when not associated On resume or firmware recovery, mac80211 sends a null data packet to see if the AP is still around and hasn't disconnected us. However, it always does this even if it wasn't even connected before, leading to a warning in the new channel context code. Fix this by checking that it's associated. Cc: stable@vger.kernel.org Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e6e4bda..fa1d343 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1491,6 +1491,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; + if (!sdata->u.mgd.associated) + continue; ieee80211_send_nullfunc(local, sdata, 0); } -- cgit v1.1 From 445632ad6dda42f4d3f9df2569a852ca0d4ea608 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Thu, 8 Nov 2012 12:03:12 -0600 Subject: ASoC: dapm: Use card_list during DAPM shutdown DAPM shutdown incorrectly uses "list" field of codec struct while iterating over probed components (codec_dev_list). "list" field refers to codecs registered in the system, "card_list" field is used for probed components. Signed-off-by: Misael Lopez Cruz Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d0a4be3..6e35bca 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3745,7 +3745,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) { struct snd_soc_codec *codec; - list_for_each_entry(codec, &card->codec_dev_list, list) { + list_for_each_entry(codec, &card->codec_dev_list, card_list) { soc_dapm_shutdown_codec(&codec->dapm); if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) snd_soc_dapm_set_bias_level(&codec->dapm, -- cgit v1.1 From d055852ee86703d48b0c571e94bd2eb33aa9b91d Mon Sep 17 00:00:00 2001 From: Mukund Navada Date: Fri, 9 Nov 2012 11:53:40 +0530 Subject: ASoC: core: Double control update err for snd_soc_put_volsw_sx snd_soc_put_volsw_sx function fails to update second control if first control is updated by snd_soc_update_bits_locked. Signed-off-by: Mukund Navada Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d119862..10d21be 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2786,8 +2786,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, val = (ucontrol->value.integer.value[0] + min) & mask; val = val << shift; - if (snd_soc_update_bits_locked(codec, reg, val_mask, val)) - return err; + err = snd_soc_update_bits_locked(codec, reg, val_mask, val); + if (err < 0) + return err; if (snd_soc_volsw_is_stereo(mc)) { val_mask = mask << rshift; -- cgit v1.1 From 40a812044a11a8fd32202cd22bb76329dd188094 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 8 Nov 2012 09:03:47 -0800 Subject: Input: MT - document new 'flags' argument of input_mt_init_slots() Fixes new kernel-doc warning in input-mt.c: Warning(drivers/input/input-mt.c:38): No description found for parameter 'flags' Reported-by: Randy Dunlap Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/input-mt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index c0ec7d4..1abbc17 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) * input_mt_init_slots() - initialize MT input slots * @dev: input device supporting MT events and finger tracking * @num_slots: number of slots used by the device + * @flags: mt tasks to handle in core * * This function allocates all necessary memory for MT slot handling * in the input device, prepares the ABS_MT_SLOT and * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. + * Depending on the flags set, it also performs pointer emulation and + * frame synchronization. + * * May be called repeatedly. Returns -EINVAL if attempting to * reinitialize with a different number of slots. */ -- cgit v1.1 From 1f98ab7fef48a2968f37f422c256c9fbd978c3f0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 10 Nov 2012 03:44:14 +0100 Subject: mac80211: call skb_dequeue/ieee80211_free_txskb instead of __skb_queue_purge Fixes more wifi status skb leaks, leading to hostapd/wpa_supplicant hangs. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/sta_info.c | 6 +++--- net/mac80211/status.c | 9 +++++++++ net/mac80211/tx.c | 9 ++++++--- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c80455..156e583 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1314,6 +1314,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + struct sk_buff_head *skbs); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 89ccd3e..3b5911e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); - __skb_queue_purge(&sta->ps_tx_buf[ac]); - __skb_queue_purge(&sta->tx_filtered[ac]); + ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); + ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); } #ifdef CONFIG_MAC80211_MESH @@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk) tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); if (!tid_tx) continue; - __skb_queue_purge(&tid_tx->pending); + ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); kfree(tid_tx); } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3af0cc4..101eb88 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -668,3 +668,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ieee80211_free_txskb); + +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + struct sk_buff_head *skbs) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(skbs))) + ieee80211_free_txskb(hw, skb); +} diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9bf83f..b858ebe 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (tx->skb) ieee80211_free_txskb(&tx->local->hw, tx->skb); else - __skb_queue_purge(&tx->skbs); + ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); return -1; } else if (unlikely(res == TX_QUEUED)) { I802_DEBUG_INC(tx->local->tx_handlers_queued); @@ -2120,10 +2120,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ void ieee80211_clear_tx_pending(struct ieee80211_local *local) { + struct sk_buff *skb; int i; - for (i = 0; i < local->hw.queues; i++) - skb_queue_purge(&local->pending[i]); + for (i = 0; i < local->hw.queues; i++) { + while ((skb = skb_dequeue(&local->pending[i])) != NULL) + ieee80211_free_txskb(&local->hw, skb); + } } /* -- cgit v1.1 From 0b8728d6f140dc20690384286ade47c956edc999 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Mon, 5 Nov 2012 06:20:31 -0800 Subject: ledtrig-cpu: kill useless mutex to fix sleep in atomic context Seeing the following every time the CPU enters or leaves idle on a Beagleboard: BUG: sleeping function called from invalid context at kernel/mutex.c:269 in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0 no locks held by swapper/0/0. [] (unwind_backtrace+0x0/0xf8) from [] (mutex_lock_nested+0x24/0x380) [] (mutex_lock_nested+0x24/0x380) from [] (ledtrig_cpu+0x38/0x88) [] (ledtrig_cpu+0x38/0x88) from [] (cpu_idle+0xf4/0x120) [] (cpu_idle+0xf4/0x120) from [] (start_kernel+0x2bc/0x30c) Miles Lane has reported seeing similar splats during system suspend. The mutex in struct led_trigger_cpu appears to have no function: it resides in a per-cpu data structure which never changes after the trigger is registered. So just remove it. Reported-by: Miles Lane Signed-off-by: Nathan Lynch Signed-off-by: Bryan Wu --- drivers/leds/ledtrig-cpu.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c index b312056..4239b39 100644 --- a/drivers/leds/ledtrig-cpu.c +++ b/drivers/leds/ledtrig-cpu.c @@ -33,8 +33,6 @@ struct led_trigger_cpu { char name[MAX_NAME_LEN]; struct led_trigger *_trig; - struct mutex lock; - int lock_is_inited; }; static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) { struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); - /* mutex lock should be initialized before calling mutex_call() */ - if (!trig->lock_is_inited) - return; - - mutex_lock(&trig->lock); - /* Locate the correct CPU LED */ switch (ledevt) { case CPU_LED_IDLE_END: @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) /* Will leave the LED as it is */ break; } - - mutex_unlock(&trig->lock); } EXPORT_SYMBOL(ledtrig_cpu); @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); - mutex_init(&trig->lock); - snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); - mutex_lock(&trig->lock); led_trigger_register_simple(trig->name, &trig->_trig); - trig->lock_is_inited = 1; - mutex_unlock(&trig->lock); } register_syscore_ops(&ledtrig_cpu_syscore_ops); @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); - mutex_lock(&trig->lock); - led_trigger_unregister_simple(trig->_trig); trig->_trig = NULL; memset(trig->name, 0, MAX_NAME_LEN); - trig->lock_is_inited = 0; - - mutex_unlock(&trig->lock); - mutex_destroy(&trig->lock); } unregister_syscore_ops(&ledtrig_cpu_syscore_ops); -- cgit v1.1 From 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sun, 11 Nov 2012 11:20:01 +0000 Subject: ipv4: avoid undefined behavior in do_ip_setsockopt() (1< Signed-off-by: David S. Miller --- net/ipv4/ip_sockglue.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5eea4a8..14bbfcf 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level, struct inet_sock *inet = inet_sk(sk); int val = 0, err; - if (((1<= sizeof(int)) { if (get_user(val, (int __user *) optval)) return -EFAULT; -- cgit v1.1 From 5a8477660d9ddc090203736d7271137265cb25bb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 12 Nov 2012 01:19:02 -0500 Subject: kill bogus BUG_ON() in do_close_on_exec() It can be legitimately triggered via procfs access. Now, at least 2 of 3 of get_files_struct() callers in procfs are useless, but when and if we get rid of those we can always add WARN_ON() here. BUG_ON() at that spot is simply wrong. Signed-off-by: Al Viro --- fs/file.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/file.c b/fs/file.c index d3b5fa8..331e7d2 100644 --- a/fs/file.c +++ b/fs/file.c @@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files) struct fdtable *fdt; /* exec unshares first */ - BUG_ON(atomic_read(&files->count) != 1); spin_lock(&files->file_lock); for (i = 0; ; i++) { unsigned long set; -- cgit v1.1 From 05193639ca977cc889668718adb38db6d585045b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Nov 2012 10:07:36 +0100 Subject: ALSA: hda - Add a missing quirk entry for iMac 9,1 This is another variant of iMac 9,1 with a different codec SSID. Reported-and-tested-by: Everaldo Canuto Cc: [v3.3+] Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c0ce3b1..68fd492 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5407,6 +5407,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), + SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), -- cgit v1.1 From 6b90466cfec2a2fe027187d675d8d14217c12d82 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 12 Nov 2012 10:16:09 +0100 Subject: HID: microsoft: do not use compound literal - fix build In patch "HID: microsoft: fix invalid rdesc for 3k kbd" I fixed support for MS 3k keyboards. However the added check using memcmp and a compound statement breaks build on architectures where memcmp is a macro with parameters. hid-microsoft.c:51:18: error: macro "memcmp" passed 6 arguments, but takes just 3 On x86_64, memcmp is a function, so I did not see the error. Signed-off-by: Jiri Slaby Reported-by: Geert Uytterhoeven Signed-off-by: Jiri Kosina --- drivers/hid/hid-microsoft.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index f676c01..6fcd466d0 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -46,9 +46,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[559] = 0x45; } /* the same as above (s/usage/physical/) */ - if ((quirks & MS_RDESC_3K) && *rsize == 106 && - !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, - &rdesc[94], 4)) { + if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && + rdesc[95] == 0x00 && rdesc[96] == 0x29 && + rdesc[97] == 0xff) { rdesc[94] = 0x35; rdesc[96] = 0x45; } -- cgit v1.1 From fa968ee215c0ca91e4a9c3a69ac2405aae6e5d2f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 7 Nov 2012 10:44:08 +0100 Subject: s390/signal: set correct address space control If user space is running in primary mode it can switch to secondary or access register mode, this is used e.g. in the clock_gettime code of the vdso. If a signal is delivered to the user space process while it has been running in access register mode the signal handler is executed in access register mode as well which will result in a crash most of the time. Set the address space control bits in the PSW to the default for the execution of the signal handler and make sure that the previous address space control is restored on signal return. Take care that user space can not switch to the kernel address space by modifying the registers in the signal frame. Cc: stable@vger.kernel.org Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/compat.h | 2 +- arch/s390/include/uapi/asm/ptrace.h | 4 ++-- arch/s390/kernel/compat_signal.c | 14 ++++++++++++-- arch/s390/kernel/signal.c | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a34a9d6..18cd6b5 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -20,7 +20,7 @@ #define PSW32_MASK_CC 0x00003000UL #define PSW32_MASK_PM 0x00000f00UL -#define PSW32_MASK_USER 0x00003F00UL +#define PSW32_MASK_USER 0x0000FF00UL #define PSW32_ADDR_AMODE 0x80000000UL #define PSW32_ADDR_INSN 0x7FFFFFFFUL diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 705588a..a5ca214 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h @@ -239,7 +239,7 @@ typedef struct #define PSW_MASK_EA 0x00000000UL #define PSW_MASK_BA 0x00000000UL -#define PSW_MASK_USER 0x00003F00UL +#define PSW_MASK_USER 0x0000FF00UL #define PSW_ADDR_AMODE 0x80000000UL #define PSW_ADDR_INSN 0x7FFFFFFFUL @@ -269,7 +269,7 @@ typedef struct #define PSW_MASK_EA 0x0000000100000000UL #define PSW_MASK_BA 0x0000000080000000UL -#define PSW_MASK_USER 0x00003F8180000000UL +#define PSW_MASK_USER 0x0000FF8180000000UL #define PSW_ADDR_AMODE 0x0000000000000000UL #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a1e8a86..593fcc9 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); + /* Check for invalid user address space control. */ + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); for (i = 0; i < NUM_GPRS; i++) regs->gprs[i] = (__u64) regs32.gprs[i]; @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ + /* Force 31 bit amode and default user address space control. */ + regs->psw.mask = PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__force __u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ + /* Force 31 bit amode and default user address space control. */ + regs->psw.mask = PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c13a2a3..d1259d8 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (user_sregs.regs.psw.mask & PSW_MASK_USER); + /* Check for invalid user address space control. */ + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); /* Check for invalid amode */ if (regs->psw.mask & PSW_MASK_EA) regs->psw.mask |= PSW_MASK_BA; @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ + /* Force default amode and default user address space control. */ + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ + /* Force default amode and default user address space control. */ + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); -- cgit v1.1 From 658e5ce705f2a09ab681eb61ca7c8619bb7a783d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 10 Nov 2012 11:04:27 +0100 Subject: s390/topology: fix core id vs physical package id mix-up The current topology code confuses core id vs physical package id. In other words /sys/devices/system/cpu/cpuX/topology/core_id displays the physical_package_id (aka socket id) instead of the core id. The physical_package_id sysfs attribute always displays "-1" instead of the socket id. Fix this mix-up with a small patch which defines and initializes topology_physical_package_id correctly and fixes the broken core id handling. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/topology.h | 3 +++ arch/s390/kernel/topology.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 9ca3053..9935cbd 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -8,6 +8,9 @@ struct cpu; #ifdef CONFIG_SCHED_BOOK +extern unsigned char cpu_socket_id[NR_CPUS]; +#define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) + extern unsigned char cpu_core_id[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 54d93f4..dd55f7c 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); static struct mask_info core_info; cpumask_t cpu_core_map[NR_CPUS]; unsigned char cpu_core_id[NR_CPUS]; +unsigned char cpu_socket_id[NR_CPUS]; static struct mask_info book_info; cpumask_t cpu_book_map[NR_CPUS]; @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, cpumask_set_cpu(lcpu, &book->mask); cpu_book_id[lcpu] = book->id; cpumask_set_cpu(lcpu, &core->mask); + cpu_core_id[lcpu] = rcpu; if (one_core_per_cpu) { - cpu_core_id[lcpu] = rcpu; + cpu_socket_id[lcpu] = rcpu; core = core->next; } else { - cpu_core_id[lcpu] = core->id; + cpu_socket_id[lcpu] = core->id; } smp_cpu_set_polarization(lcpu, tl_cpu->pp); } -- cgit v1.1 From 43c771a1963ab461a2f194e3c97fded1d5fe262f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Nov 2012 10:51:34 +0100 Subject: wireless: allow 40 MHz on world roaming channels 12/13 When in world roaming mode, allow 40 MHz to be used on channels 12 and 13 so that an AP that is, e.g., using HT40+ on channel 9 (in the UK) can be used. Cc: stable@vger.kernel.org Reported-by: Eddie Chapman Tested-by: Eddie Chapman Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index bcc7d7e..b75756b 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. No HT40 - * channel fits here. */ - REG_RULE(2467-10, 2472+10, 20, 6, 20, + /* IEEE 802.11b/g, channels 12..13. */ + REG_RULE(2467-10, 2472+10, 40, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), /* IEEE 802.11 channel 14 - Only JP enables -- cgit v1.1 From 4cf2d3b1b6ff9b7b6af1d2dbf1b63aa465250bc2 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:57 +0200 Subject: clk: ux500: Register i2c clock lookups for u8500 Cc: Ben Dooks Cc: Wolfram Sang Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Ulf Hansson Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index ca4a25e..7ad01aa 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -228,6 +228,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); + clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, @@ -239,6 +241,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, BIT(6), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, BIT(7), 0); @@ -255,11 +258,14 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, BIT(10), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); + clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, BIT(1), 0); @@ -284,7 +290,6 @@ void u8500_clk_init(void) BIT(6), 0); clk_register_clkdev(clk, "apb_pclk", "sdi1"); - clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, BIT(7), 0); clk_register_clkdev(clk, "apb_pclk", "sdi3"); @@ -318,8 +323,10 @@ void u8500_clk_init(void) BIT(1), 0); clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, BIT(4), 0); @@ -401,6 +408,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); + clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", @@ -412,17 +421,23 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.2"); + clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); /* FIXME: Redefinition of BIT(3). */ + clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.4"); + clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.3"); clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); @@ -452,8 +467,10 @@ void u8500_clk_init(void) U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); -- cgit v1.1 From 08b1f1c7b9bf0f6fe9e2ce3369928955554a958b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:58 +0200 Subject: clk: ux500: Register ssp clock lookups for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 7ad01aa..36ef41d 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -321,8 +321,11 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); + clk_register_clkdev(clk, "apb_pclk", "ssp0"); + clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "ssp1"); clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); @@ -465,8 +468,11 @@ void u8500_clk_init(void) /* Periph3 */ clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ssp0"); + clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ssp1"); clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); -- cgit v1.1 From 15e66cd8d029de8055822a98c5a72a4414ffc0a6 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:59 +0200 Subject: clk: ux500: Register msp clock lookups for u8500 Cc: Mark Brown Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 36ef41d..be843ba 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -232,8 +232,13 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "msp0"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); + clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, BIT(4), 0); + clk_register_clkdev(clk, "apb_pclk", "msp1"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, BIT(5), 0); @@ -262,6 +267,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); + clk_register_clkdev(clk, "apb_pclk", "msp3"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); @@ -285,6 +292,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, BIT(5), 0); + clk_register_clkdev(clk, "apb_pclk", "msp2"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, BIT(6), 0); @@ -415,8 +424,13 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp0"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); + clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp1"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); @@ -436,6 +450,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp3"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", @@ -448,6 +464,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp2"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); -- cgit v1.1 From d4915cf5f6190b94411c3102078ac4b86149fe59 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:58:00 +0200 Subject: clk: ux500: Update rtc clock lookup for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index be843ba..0aae929 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -40,7 +40,7 @@ void u8500_clk_init(void) CLK_IS_ROOT|CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); - clk_register_clkdev(clk, NULL, "rtc-pl031"); + clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); /* PRCMU clocks */ fw_version = prcmu_get_fw_version(); -- cgit v1.1 From 3d930678034e756d0960d214412d344772b21109 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:58:01 +0200 Subject: clk: ux500: Register slimbus clock lookups for u8500 At the same time the prcc bit for the kclk is corrected to bit 8 instead of 3. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 0aae929..e2c17d1 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -254,6 +254,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, BIT(8), 0); + clk_register_clkdev(clk, "apb_pclk", "slimbus0"); clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, BIT(9), 0); @@ -441,8 +442,8 @@ void u8500_clk_init(void) clk_register_clkdev(clk, NULL, "nmk-i2c.2"); clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", - U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); - /* FIXME: Redefinition of BIT(3). */ + U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "slimbus0"); clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); -- cgit v1.1 From d0ddfbd3d1346c1f481ec2289eef350cdba64b42 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 12 Nov 2012 18:31:35 +0200 Subject: drm/i915/sdvo: clean up connectors on intel_sdvo_init() failures Any failures in intel_sdvo_init() after the intel_sdvo_setup_output() call left behind ghost connectors, attached (with a dangling pointer) to the sdvo that has been cleaned up and freed. Properly destroy any connectors attached to the encoder. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=46381 CC: Chris Wilson Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org Tested-by: bjo@nord-west.org [danvet: added a comment to explain why we need to clean up connectors even when sdvo_output_setup fails.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 79d308d..c600fb0 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2382,6 +2382,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) return true; } +static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) +{ + struct drm_device *dev = intel_sdvo->base.base.dev; + struct drm_connector *connector, *tmp; + + list_for_each_entry_safe(connector, tmp, + &dev->mode_config.connector_list, head) { + if (intel_attached_encoder(connector) == &intel_sdvo->base) + intel_sdvo_destroy(connector); + } +} + static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, int type) @@ -2705,7 +2717,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) intel_sdvo->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", SDVO_NAME(intel_sdvo)); - goto err; + /* Output_setup can leave behind connectors! */ + goto err_output; } /* Only enable the hotplug irq if we need it, to work around noisy @@ -2718,12 +2731,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) - goto err; + goto err_output; if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, &intel_sdvo->pixel_clock_min, &intel_sdvo->pixel_clock_max)) - goto err; + goto err_output; DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " "clock range %dMHz - %dMHz, " @@ -2743,6 +2756,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); return true; +err_output: + intel_sdvo_output_cleanup(intel_sdvo); + err: drm_encoder_cleanup(&intel_encoder->base); i2c_del_adapter(&intel_sdvo->ddc); -- cgit v1.1 From 1ef43369c681bf30a980a4ba42df20514b15fdda Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Nov 2012 11:08:50 -0800 Subject: ARM: OMAP4: TWL: mux sys_drm_msecure as output for PMIC On OMAP4 boards using the TWL6030 PMIC, the sys_drm_msecure is connected to the MSECURE input of the TWL6030 PMIC. This signal controls the secure-mode operation of the PMIC. If its not mux'd correctly, some functionality of the PMIC will not be accessible since the PMIC will be in secure mode. For example, if the TWL RTC is in secure mode, most of its registers are read-only, meaning (re)programming the RTC (e.g. for wakeup from suspend) will fail. To fix, ensure the signal is properly mux'd as output when TWL is intialized. This fix is required when using recent versions of u-boot (>= v2012.04.01) since u-boot is no longer setting the default mux for this pin. Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/twl-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109..96cae8b 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type, { /* PMIC part*/ omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); + omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); /* Register additional devices on i2c1 bus if needed */ -- cgit v1.1 From 2d4d07b97c0b774ea9ce2a2105818208d3df7241 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 24 Oct 2012 16:37:28 -0200 Subject: ARM: boot: Fix usage of kecho Since commit edc88ceb0 (ARM: be really quiet when building with 'make -s') the following output is generated when building a kernel for ARM: echo ' Kernel: arch/arm/boot/Image is ready' Kernel: arch/arm/boot/Image is ready Building modules, stage 2. echo ' Kernel: arch/arm/boot/zImage is ready' Kernel: arch/arm/boot/zImage is ready As per Documentation/kbuild/makefiles.txt the correct way of using kecho is '@$(kecho)'. Make this change so no more unwanted 'echo' messages are displayed. Signed-off-by: Fabio Estevam Signed-off-by: Arnd Bergmann --- arch/arm/boot/Makefile | 10 +++++----- arch/arm/tools/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f2aa09e..9137df5 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' endif @@ -90,7 +90,7 @@ fi $(obj)/uImage: $(obj)/zImage FORCE @$(check_for_multiple_loadaddr) $(call if_changed,uimage) - $(kecho) ' Image $@ is ready' + @$(kecho) ' Image $@ is ready' $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' PHONY += initrd FORCE initrd: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index cd60a81..32d05c8 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -5,6 +5,6 @@ # include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types - $(kecho) ' Generating $@' + @$(kecho) ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } -- cgit v1.1 From 6d1068b3a98519247d8ba4ec85cd40ac136dbdf9 Mon Sep 17 00:00:00 2001 From: Petr Matousek Date: Tue, 6 Nov 2012 19:24:07 +0100 Subject: KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit set (CVE-2012-4461) On hosts without the XSAVE support unprivileged local user can trigger oops similar to the one below by setting X86_CR4_OSXSAVE bit in guest cr4 register using KVM_SET_SREGS ioctl and later issuing KVM_RUN ioctl. invalid opcode: 0000 [#2] SMP Modules linked in: tun ip6table_filter ip6_tables ebtable_nat ebtables ... Pid: 24935, comm: zoog_kvm_monito Tainted: G D 3.2.0-3-686-pae EIP: 0060:[] EFLAGS: 00210246 CPU: 0 EIP is at kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] EAX: 00000001 EBX: 000f387e ECX: 00000000 EDX: 00000000 ESI: 00000000 EDI: 00000000 EBP: ef5a0060 ESP: d7c63e70 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process zoog_kvm_monito (pid: 24935, ti=d7c62000 task=ed84a0c0 task.ti=d7c62000) Stack: 00000001 f70a1200 f8b940a9 ef5a0060 00000000 00200202 f8769009 00000000 ef5a0060 000f387e eda5c020 8722f9c8 00015bae 00000000 ed84a0c0 ed84a0c0 c12bf02d 0000ae80 ef7f8740 fffffffb f359b740 ef5a0060 f8b85dc1 0000ae80 Call Trace: [] ? kvm_arch_vcpu_ioctl_set_sregs+0x2fe/0x308 [kvm] ... [] ? syscall_call+0x7/0xb Code: 89 e8 e8 14 ee ff ff ba 00 00 04 00 89 e8 e8 98 48 ff ff 85 c0 74 1e 83 7d 48 00 75 18 8b 85 08 07 00 00 31 c9 8b 95 0c 07 00 00 <0f> 01 d1 c7 45 48 01 00 00 00 c7 45 1c 01 00 00 00 0f ae f0 89 EIP: [] kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] SS:ESP 0068:d7c63e70 QEMU first retrieves the supported features via KVM_GET_SUPPORTED_CPUID and then sets them later. So guest's X86_FEATURE_XSAVE should be masked out on hosts without X86_FEATURE_XSAVE, making kvm_set_cr4 with X86_CR4_OSXSAVE fail. Userspaces that allow specifying guest cpuid with X86_FEATURE_XSAVE even on hosts that do not support it, might be susceptible to this attack from inside the guest as well. Allow setting X86_CR4_OSXSAVE bit only if host has XSAVE support. Signed-off-by: Petr Matousek Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/cpuid.h | 3 +++ arch/x86/kvm/x86.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a10e460..58fc514 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; + if (!static_cpu_has(X86_FEATURE_XSAVE)) + return 0; + best = kvm_find_cpuid_entry(vcpu, 1, 0); return best && (best->ecx & bit(X86_FEATURE_XSAVE)); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 224a7e7..4f76417 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, int pending_vec, max_bits, idx; struct desc_ptr dt; + if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) + return -EINVAL; + dt.size = sregs->idt.limit; dt.address = sregs->idt.base; kvm_x86_ops->set_idt(vcpu, &dt); -- cgit v1.1 From 5574f7745436d2014fcba1163f820d132e816c85 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 10 Nov 2012 19:52:50 +0100 Subject: ASoC: cs4271: free allocated GPIO In case of probe deferral, the allocated GPIO line is not freed, which prevents it from being claimed and properly asserted in later attempts. Fix this by using devm_gpio_request(). Signed-off-by: Daniel Mack Reported-by: Michael Hirsch Cc: Alexander Sverdlin Signed-off-by: Mark Brown --- sound/soc/codecs/cs4271.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index f994af3..e3f0a7f 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -485,7 +485,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) gpio_nreset = cs4271plat->gpio_nreset; if (gpio_nreset >= 0) - if (gpio_request(gpio_nreset, "CS4271 Reset")) + if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) gpio_nreset = -EINVAL; if (gpio_nreset >= 0) { /* Reset codec */ @@ -535,15 +535,10 @@ static int cs4271_probe(struct snd_soc_codec *codec) static int cs4271_remove(struct snd_soc_codec *codec) { struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); - int gpio_nreset; - gpio_nreset = cs4271->gpio_nreset; - - if (gpio_is_valid(gpio_nreset)) { + if (gpio_is_valid(cs4271->gpio_nreset)) /* Set codec to the reset state */ - gpio_set_value(gpio_nreset, 0); - gpio_free(gpio_nreset); - } + gpio_set_value(cs4271->gpio_nreset, 0); return 0; }; -- cgit v1.1 From d2153a1595ee8235ecf9f9e2d1ac18eee373cbb5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 13 Nov 2012 10:44:54 +0300 Subject: ALSA: es1968: precedence bug in snd_es1968_tea575x_get_pins() I don't think this works as intended. '|' higher precedence than ?: so the bitwize OR "0 | (val & STR_MOST)" is a no-op. I have re-written it to be more clear. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/pci/es1968.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 50169bc..7266020 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -2581,9 +2581,14 @@ static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) struct es1968 *chip = tea->private_data; unsigned long io = chip->io_port + GPIO_DATA; u16 val = inw(io); - - return (val & STR_DATA) ? TEA575X_DATA : 0 | - (val & STR_MOST) ? TEA575X_MOST : 0; + u8 ret; + + ret = 0; + if (val & STR_DATA) + ret |= TEA575X_DATA; + if (val & STR_MOST) + ret |= TEA575X_MOST; + return ret; } static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) -- cgit v1.1 From 703fb94ec58e0e8769380c2877a8a34aeb5b6c97 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Tue, 13 Nov 2012 08:52:24 +0100 Subject: xfrm: Fix the gc threshold value for ipv4 The xfrm gc threshold value depends on ip_rt_max_size. This value was set to INT_MAX with the routing cache removal patch, so we start doing garbage collecting when we have INT_MAX/2 IPsec routes cached. Fix this by going back to the static threshold of 1024 routes. Signed-off-by: Steffen Klassert --- include/net/xfrm.h | 2 +- net/ipv4/route.c | 2 +- net/ipv4/xfrm4_policy.c | 13 +------------ 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6f0ba01..63445ed 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1351,7 +1351,7 @@ struct xfrm6_tunnel { }; extern void xfrm_init(void); -extern void xfrm4_init(int rt_hash_size); +extern void xfrm4_init(void); extern int xfrm_state_init(struct net *net); extern void xfrm_state_fini(struct net *net); extern void xfrm4_state_init(void); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a8c65121..200d287 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2597,7 +2597,7 @@ int __init ip_rt_init(void) pr_err("Unable to create route proc files\n"); #ifdef CONFIG_XFRM xfrm_init(); - xfrm4_init(ip_rt_max_size); + xfrm4_init(); #endif rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 05c5ab8..3be0ac2 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -279,19 +279,8 @@ static void __exit xfrm4_policy_fini(void) xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); } -void __init xfrm4_init(int rt_max_size) +void __init xfrm4_init(void) { - /* - * Select a default value for the gc_thresh based on the main route - * table hash size. It seems to me the worst case scenario is when - * we have ipsec operating in transport mode, in which we create a - * dst_entry per socket. The xfrm gc algorithm starts trying to remove - * entries at gc_thresh, and prevents new allocations as 2*gc_thresh - * so lets set an initial xfrm gc_thresh value at the rt_max_size/2. - * That will let us store an ipsec connection per route table entry, - * and start cleaning when were 1/2 full - */ - xfrm4_dst_ops.gc_thresh = rt_max_size/2; dst_entries_init(&xfrm4_dst_ops); xfrm4_state_init(); -- cgit v1.1 From d55c4c613fc4d4ad2ba0fc6fa2b57176d420f7e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 22 Oct 2012 15:49:02 +0200 Subject: s390/gup: add missing TASK_SIZE check to get_user_pages_fast() When walking page tables we need to make sure that everything is within bounds of the ASCE limit of the task's address space. Otherwise we might calculate e.g. a pud pointer which is not within a pud and dereference it. So check against TASK_SIZE (which is the ASCE limit) before walking page tables. Reviewed-by: Gerald Schaefer Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 8b82853..16fb3c1 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -229,7 +229,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (end < start) + if ((end < start) || (end > TASK_SIZE)) goto slow_irqon; /* -- cgit v1.1 From 516bad44b9f3bdcb0be6be0252b7557bf7a149e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 22 Oct 2012 15:58:26 +0200 Subject: s390/gup: fix access_ok() usage in __get_user_pages_fast() access_ok() returns always "true" on s390. Therefore all access_ok() invocations are rather pointless. However when walking page tables we need to make sure that everything is within bounds of the ASCE limit of the task's address space. So remove the access_ok() call and add the same check we have in get_user_pages_fast(). Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 16fb3c1..1f5315d1 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, - (void __user *)start, len))) + if ((end < start) || (end > TASK_SIZE)) return 0; local_irq_save(flags); -- cgit v1.1 From 4bffbb3455372a26816e364fb4448810f7014452 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 8 Nov 2012 14:18:47 +0100 Subject: s390/mm: have 16 byte aligned struct pages Select HAVE_ALIGNED_STRUCT_PAGE on s390, so that the slub allocator can make use of compare and swap double for lockless updates. This increases the size of struct page to 64 bytes (instead of 56 bytes), however the performance gain justifies the increased size: - now excactly four struct pages fit into a single cache line; the case that accessing a struct page causes two cache line loads does not exist anymore. - calculating the offset of a struct page within the memmap array is only a simple shift instead of a more expensive multiplication. A "hackbench 200 process 200" run on a 32 cpu system did show an 8% runtime improvement. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dba755..d385f39 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -96,6 +96,7 @@ config S390 select HAVE_MEMBLOCK_NODE_MAP select HAVE_CMPXCHG_LOCAL select HAVE_CMPXCHG_DOUBLE + select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_VIRT_CPU_ACCOUNTING select VIRT_CPU_ACCOUNTING select ARCH_DISCARD_MEMBLOCK -- cgit v1.1 From 2f4f649a69a9eb51f6e98130e19dd90a260a4145 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 12 Nov 2012 14:33:44 +0200 Subject: drm/i915: do not ignore eDP bpc settings from vbt There are laptops out there that need the eDP bpc from VBT. This is effectively a revert of commit 4344b813f105a19f793f1fd93ad775b784648b95 Author: Daniel Vetter Date: Fri Aug 10 11:10:20 2012 +0200 drm/i915: ignore eDP bpc settings from vbt but putting the VBT check after the EDID check to see them both in dmesg if this clamps more than the EDID. We have enough history with bpc clamping to warrant the extra debug info. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=47641 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56401 Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 461a637..4154bcd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, } } + if (intel_encoder->type == INTEL_OUTPUT_EDP) { + /* Use VBT settings if we have an eDP panel */ + unsigned int edp_bpc = dev_priv->edp.bpp / 3; + + if (edp_bpc < display_bpc) { + DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); + display_bpc = edp_bpc; + } + continue; + } + /* * HDMI is either 12 or 8, so if the display lets 10bpc sneak * through, clamp it down. (Note: >12bpc will be caught below.) -- cgit v1.1 From 49bd665c5407a453736d3232ee58f2906b42e83c Mon Sep 17 00:00:00 2001 From: Maciej Patelczyk Date: Mon, 15 Oct 2012 14:29:03 +0200 Subject: [SCSI] isci: copy fis 0x34 response into proper buffer SATA MICROCODE DOWNALOAD fails on isci driver. After receiving Register Device to Host (FIS 0x34) frame Initiator resets phy. In the frame handler routine response (FIS 0x34) was copied into wrong buffer and upper layer did not receive any answer which resulted in timeout and reset. This patch corrects this bug. Signed-off-by: Maciej Patelczyk Signed-off-by: Lukasz Dorau Cc: Signed-off-by: James Bottomley --- drivers/scsi/isci/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index c1bafc3..9594ab6 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, frame_index, (void **)&frame_buffer); - sci_controller_copy_sata_response(&ireq->stp.req, + sci_controller_copy_sata_response(&ireq->stp.rsp, frame_header, frame_buffer); -- cgit v1.1 From 225ae5fd9a320e22841410049c3bdb6cf14a5841 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Nov 2012 10:41:50 +0100 Subject: MIPS: Malta: Fix interupt number of CBUS UART. The CBUS UART's interrupt number was wrong conflicting with the interrupt being tied to the Intel PIIX4. Since the PIIX4's interrupt is registered before the CBUS UART which is not being used on most systems this would not be noticed. Attempts to open the ttyS2 CBUS UART would result in: genirq: Flags mismatch irq 18. 00000000 (serial) vs. 00010000 (XT-PIC cascade) serial_link_irq_chain: request failed: -16 for irq: 18 Qemu was written to match the kernel so will need to be fixed also. Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 80562b8..7473217 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define SMC_PORT(base, int) \ @@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { SMC_PORT(0x2F8, 3), { .mapbase = 0x1f000900, /* The CBUS UART */ - .irq = MIPS_CPU_IRQ_BASE + 2, + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, .uartclk = 3686400, /* Twice the usual clk! */ .iotype = UPIO_MEM32, .flags = CBUS_UART_FLAGS, -- cgit v1.1 From f0e3e35c9049087172c65302b42da8fe7ebb63a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Sat, 10 Nov 2012 10:13:42 +0100 Subject: USB: keyspan: fix typo causing GPF on open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit f79b2d0f (USB: keyspan: fix NULL-pointer dereferences and memory leaks) had a small typo which made the driver use wrong offsets when mapping serial port private data. This results in in a GPF when the port is opened. Reported-by: Richard Cc: stable Signed-off-by: Bjørn Mork Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7179b0c..cff8dd5 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2430,7 +2430,7 @@ static void keyspan_release(struct usb_serial *serial) static int keyspan_port_probe(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - struct keyspan_port_private *s_priv; + struct keyspan_serial_private *s_priv; struct keyspan_port_private *p_priv; const struct keyspan_device_details *d_details; struct callbacks *cback; @@ -2445,7 +2445,6 @@ static int keyspan_port_probe(struct usb_serial_port *port) if (!p_priv) return -ENOMEM; - s_priv = usb_get_serial_data(port->serial); p_priv->device_details = d_details; /* Setup values for the various callback routines */ -- cgit v1.1 From fcb21645f1bd86d2be29baf48aa1b298de52ccc7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 8 Nov 2012 11:56:42 -0600 Subject: USB: option: add Novatel E362 and Dell Wireless 5800 USB IDs The Dell 5800 appears to be a simple rebrand of the Novatel E362. Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5dee7d6..c25d3fd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 +#define NOVATELWIRELESS_PRODUCT_E362 0x9010 #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 @@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 +#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ +#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ + #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a @@ -706,6 +710,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, @@ -728,6 +733,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, -- cgit v1.1 From c0bc3098871dd9b964f6b45ec1e4d70d87811744 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 8 Nov 2012 11:56:53 -0600 Subject: USB: option: add Alcatel X220/X500D USB IDs Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c25d3fd..edc64bb 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -287,6 +287,7 @@ static void option_instat_callback(struct urb *urb); /* ALCATEL PRODUCTS */ #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S_X200 0x0000 +#define ALCATEL_PRODUCT_X220_X500D 0x0017 #define PIRELLI_VENDOR_ID 0x1266 #define PIRELLI_PRODUCT_C100_1 0x1002 @@ -1164,6 +1165,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), -- cgit v1.1 From e592c5d0b7db94b485b4a2342db041a1882b7f75 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Nov 2012 10:52:52 -0800 Subject: Revert "USB/host: Cleanup unneccessary irq disable code" This reverts commit 73d4066055e0e2830533041f4b91df8e6e5976ff. Martin Steigerwald reported that this change caused a hard lockup when using USB if threadirqs are enabled. Thomas pointed out that this patch is incorrect, and can cause problems. So revert it to get the previously working functionality back. Reported-by: Martin Steigerwald Cc: Thomas Gleixner Cc: Chuansheng Liu Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 16 ++++++++++++++++ drivers/usb/host/ehci-ls1x.c | 2 +- drivers/usb/host/ohci-xls.c | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1e741bc..f034716 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); irqreturn_t usb_hcd_irq (int irq, void *__hcd) { struct usb_hcd *hcd = __hcd; + unsigned long flags; irqreturn_t rc; + /* IRQF_DISABLED doesn't work correctly with shared IRQs + * when the first handler doesn't use it. So let's just + * assume it's never used. + */ + local_irq_save(flags); + if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) rc = IRQ_NONE; else if (hcd->driver->irq(hcd) == IRQ_NONE) @@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) else rc = IRQ_HANDLED; + local_irq_restore(flags); return rc; } EXPORT_SYMBOL_GPL(usb_hcd_irq); @@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, int retval; if (hcd->driver->irq) { + + /* IRQF_DISABLED doesn't work as advertised when used together + * with IRQF_SHARED. As usb_hcd_irq() will always disable + * interrupts we can remove it here. + */ + if (irqflags & IRQF_SHARED) + irqflags &= ~IRQF_DISABLED; + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); retval = request_irq(irqnum, &usb_hcd_irq, irqflags, diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c index ca75965..aa0f328 100644 --- a/drivers/usb/host/ehci-ls1x.c +++ b/drivers/usb/host/ehci-ls1x.c @@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) goto err_put_hcd; } - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (ret) goto err_put_hcd; diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index 84201cd..41e378f 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c @@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, goto err3; } - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err4; return retval; -- cgit v1.1 From 80928805babfd97b6f1721dd942a55dd2e7813ea Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Tue, 6 Nov 2012 00:08:53 +0000 Subject: smsc95xx: set MII_BUSY bit to read/write PHY regs The device datasheet specifies the BUSY bit must be set when reading or writing phy registers. This patch ensures we do that. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 3286166..362cb8c 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -184,7 +184,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) /* set the address, index & direction (read from PHY) */ phy_id &= dev->mii.phy_id_mask; idx &= dev->mii.reg_num_mask; - addr = (phy_id << 11) | (idx << 6) | MII_READ_; + addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_; ret = smsc95xx_write_reg(dev, MII_ADDR, addr); check_warn_goto_done(ret, "Error writing MII_ADDR"); @@ -221,7 +221,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, /* set the address, index & direction (write to PHY) */ phy_id &= dev->mii.phy_id_mask; idx &= dev->mii.reg_num_mask; - addr = (phy_id << 11) | (idx << 6) | MII_WRITE_; + addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_; ret = smsc95xx_write_reg(dev, MII_ADDR, addr); check_warn_goto_done(ret, "Error writing MII_ADDR"); -- cgit v1.1 From a134884ac0e9fa48786560d49ed49c5f5f686410 Mon Sep 17 00:00:00 2001 From: Stefan Raspl Date: Mon, 12 Nov 2012 23:05:16 +0000 Subject: qeth: Fix IPA_CMD_QIPASSIST return code handling Return codes of IPA_CMD_QIPASSIST are not checked, especially the ones which indicate that the command is not supported. As a result, the device driver would not enable all available features on older card generations. This patch adds proper checking and sets the bare minimum in the supported functions flags to avoid follow-on errors. Signed-off-by: Stefan Raspl Signed-off-by: Frank Blaschka Reviewed-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 24 ++++++++++++++++++++++-- drivers/s390/net/qeth_l2_main.c | 11 +++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3e25d315..4d6ba00 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2942,13 +2942,33 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, QETH_DBF_TEXT(SETUP, 2, "qipasscb"); cmd = (struct qeth_ipa_cmd *) data; + + switch (cmd->hdr.return_code) { + case IPA_RC_NOTSUPP: + case IPA_RC_L2_UNSUPPORTED_CMD: + QETH_DBF_TEXT(SETUP, 2, "ipaunsup"); + card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS; + card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS; + return -0; + default: + if (cmd->hdr.return_code) { + QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled " + "rc=%d\n", + dev_name(&card->gdev->dev), + cmd->hdr.return_code); + return 0; + } + } + if (cmd->hdr.prot_version == QETH_PROT_IPV4) { card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; - } else { + } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) { card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; - } + } else + QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected" + "\n", dev_name(&card->gdev->dev)); QETH_DBF_TEXT(SETUP, 2, "suppenbl"); QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index e67e025..84e8f1d 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -626,10 +626,13 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "doL2init"); QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); - rc = qeth_query_setadapterparms(card); - if (rc) { - QETH_DBF_MESSAGE(2, "could not query adapter parameters on " - "device %s: x%x\n", CARD_BUS_ID(card), rc); + if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { + rc = qeth_query_setadapterparms(card); + if (rc) { + QETH_DBF_MESSAGE(2, "could not query adapter " + "parameters on device %s: x%x\n", + CARD_BUS_ID(card), rc); + } } if (card->info.type == QETH_CARD_TYPE_IQD || -- cgit v1.1 From 7702745b15128e5f0659693736a864e35be1c807 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 12 Nov 2012 23:05:17 +0000 Subject: qeth: set new mac even if old mac is gone If the set_mac_address() function of qeth is invoked, qeth deletes the old mac address first on OSA. Only if deletion returns successfully the new mac address is set on OSA. Deletion may return with a return value "MAC not found on OSA". In this case qeth should continue setting the new mac address. When the OSA cable is pulled, OSA forgets any set mac address. If the OSA network interface acts as a slave to a bonding master interface, bonding can invoke the set_mac_address function for failover purposes and depends on successful setting of the new mac address even though the old mac address could no longer be deleted. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 84e8f1d..fddb626 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -679,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) return -ERESTARTSYS; } rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); - if (!rc) + if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) rc = qeth_l2_send_setmac(card, addr->sa_data); return rc ? -EINVAL : 0; } -- cgit v1.1 From bbc8d9228ea8e37ce29fa96150d10b85a2c7be60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 13 Nov 2012 03:19:43 +0000 Subject: net: cdc_ncm: add Huawei devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A number of Huawei 3G and LTE modems implement a CDC NCM function, including the necessary functional descriptors, but using a non standard interface layout and class/subclass/protocol codes. These devices can be handled by this driver with only a minor change to the probing logic, allowing a single combined control and data interface. This works because the devices - include a CDC Union descriptor labelling the combined interface as both master and slave, and - have an alternate setting #1 for the bulk endpoints on the combined interface. The 3G/LTE network connection is managed by vendor specific AT commands on a serial function in the same composite device. Handling the managment function is out of the scope of this driver. It will be handled by an appropriate USB serial driver. Reported-and-Tested-by: Olof Ermis Reported-and-Tested-by: Tommy Cheng Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ncm.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4cd582a..74fab1a 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -540,10 +540,12 @@ advance: (ctx->ether_desc == NULL) || (ctx->control != intf)) goto error; - /* claim interfaces, if any */ - temp = usb_driver_claim_interface(driver, ctx->data, dev); - if (temp) - goto error; + /* claim data interface, if different from control */ + if (ctx->data != ctx->control) { + temp = usb_driver_claim_interface(driver, ctx->data, dev); + if (temp) + goto error; + } iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; @@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) tasklet_kill(&ctx->bh); + /* handle devices with combined control and data interface */ + if (ctx->control == ctx->data) + ctx->data = NULL; + /* disconnect master --> disconnect slave */ if (intf == ctx->control && ctx->data) { usb_set_intfdata(ctx->data, NULL); @@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, + /* Huawei NCM devices disguised as vendor specific */ + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), + .driver_info = (unsigned long)&wwan_info, + }, + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), + .driver_info = (unsigned long)&wwan_info, + }, + /* Generic CDC-NCM devices */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), -- cgit v1.1 From bd090dfc634ddd711a5fbd0cadc6e0ab4977bcaf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 13 Nov 2012 05:37:18 +0000 Subject: tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming() We added support for RFC 5961 in latest kernels but TCP fails to perform exhaustive check of ACK sequence. We can update our view of peer tsval from a frame that is later discarded by tcp_ack() This makes timestamps enabled sessions vulnerable to injection of a high tsval : peers start an ACK storm, since the victim sends a dupack each time it receives an ACK from the other peer. As tcp_validate_incoming() is called before tcp_ack(), we should not peform tcp_replace_ts_recent() from it, and let callers do it at the right time. Signed-off-by: Eric Dumazet Cc: Neal Cardwell Cc: Yuchung Cheng Cc: Nandita Dukkipati Cc: H.K. Jerry Chu Cc: Romain Francoise Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2c2b13a..609ff98 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5313,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, goto discard; } - /* ts_recent update must be made after we are sure that the packet - * is in window. - */ - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); - /* step 3: check security and precedence [ignored] */ /* step 4: Check for a SYN @@ -5552,6 +5547,11 @@ step5: if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ @@ -6130,6 +6130,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } else goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + /* step 6: check the URG bit */ tcp_urg(sk, skb, th); -- cgit v1.1 From 52b702ffa509595c5d04a1a1d0f63acf92b4789b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 9 Nov 2012 13:35:24 +0000 Subject: vxlan: Fix error that was resulting in VXLAN MTU size being 10 bytes too large This change fixes an issue I found where VXLAN frames were fragmented when they were up to the VXLAN MTU size. I root caused the issue to the fact that the headroom was 4 + 20 + 8 + 8. This math doesn't appear to be correct because we are not inserting a VLAN header, but instead a 2nd Ethernet header. As such the math for the overhead should be 20 + 8 + 8 + 14 to account for the extra headers that are inserted for VXLAN. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 7b4adde..0c4d0f4 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -50,8 +50,8 @@ #define VXLAN_N_VID (1u << 24) #define VXLAN_VID_MASK (VXLAN_N_VID - 1) -/* VLAN + IP header + UDP + VXLAN */ -#define VXLAN_HEADROOM (4 + 20 + 8 + 8) +/* IP header + UDP + VXLAN + Ethernet header */ +#define VXLAN_HEADROOM (20 + 8 + 8 + 14) #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ -- cgit v1.1 From 73e212fc48890b552e4ae65b65c0e709f478879b Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sat, 10 Nov 2012 07:12:36 +0000 Subject: doc/net: Fix typo in netdev-features.txt Signed-off-by: Kirill Smelkov Signed-off-by: David S. Miller --- Documentation/networking/netdev-features.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/networking/netdev-features.txt b/Documentation/networking/netdev-features.txt index 4164f5c..f310ede 100644 --- a/Documentation/networking/netdev-features.txt +++ b/Documentation/networking/netdev-features.txt @@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet. This requests that the NIC receive all possible frames, including errored frames (such as bad FCS, etc). This can be helpful when sniffing a link with bad packets on it. Some NICs may receive more packets if also put into normal -PROMISC mdoe. +PROMISC mode. -- cgit v1.1 From d4596bad2a713fcd0def492b1960e6d899d5baa8 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Sat, 10 Nov 2012 19:52:34 +0000 Subject: ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT) forgot to set return value Cc: Stephen Hemminger Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- net/ipv6/ipv6_sockglue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d..e02faed 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -827,6 +827,7 @@ pref_skip_coa: if (val < 0 || val > 255) goto e_inval; np->min_hopcount = val; + retv = 0; break; case IPV6_DONTFRAG: np->dontfrag = valbool; -- cgit v1.1 From b78a4932f5fb11fadf41e69c606a33fa6787574c Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Tue, 13 Nov 2012 18:43:03 +0100 Subject: mac80211: deinitialize ibss-internals after emptiness check The check whether the IBSS is active and can be removed should be performed before deinitializing the fields used for the check/search. Otherwise, the configured BSS will not be found and removed properly. To make it more clear for the future, rename sdata->u.ibss to the local pointer ifibss which is used within the checks. This behaviour was introduced by f3209bea110cade12e2b133da8b8499689cb0e2e ("mac80211: fix IBSS teardown race") Cc: stable@vger.kernel.org Cc: Ignacy Gawedzki Signed-off-by: Simon Wunderlich Signed-off-by: Johannes Berg --- net/mac80211/ibss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index bf87c70..c21e33d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1151,10 +1151,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); - sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; - memset(sdata->u.ibss.bssid, 0, ETH_ALEN); - sdata->u.ibss.ssid_len = 0; - active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1175,6 +1171,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } + ifibss->state = IEEE80211_IBSS_MLME_SEARCH; + memset(ifibss->bssid, 0, ETH_ALEN); + ifibss->ssid_len = 0; + sta_info_flush(sdata->local, sdata); spin_lock_bh(&ifibss->incomplete_lock); -- cgit v1.1 From d38e0e3fed4f58bcddef4dc93a591dfe2f651cb0 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 7 Nov 2012 18:21:51 -0800 Subject: Revert "Staging: Android alarm: IOCTL command encoding fix" Commit 6bd4a5d96c08dc2380f8053b1bd4f879f55cd3c9 changed the ANDROID_ALARM_GET_TIME ioctls from IOW to IOR. While technically correct, the _IOC_DIR bits are ignored by alarm_ioctl, so the commit breaks a userspace ABI used by all existing Android devices for a purely cosmetic reason. Revert it. Cc: stable Cc: Dae S. Kim Signed-off-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/android_alarm.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index f2ffd96..d0cafd6 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -51,12 +51,10 @@ enum android_alarm_return_flags { #define ANDROID_ALARM_WAIT _IO('a', 1) #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) -#define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) - /* Set alarm */ #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) -#define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) -- cgit v1.1 From d85c8a6ab2bb0ba067a2a72c63c3bd20e6788996 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 13 Nov 2012 22:27:19 +0100 Subject: MAINTAINERS: i2c: 7 years, this is it I have been maintaining the i2c subsystem for 7 years now, it's about time to let someone else take over. Just before I leave, I would like to thank several individuals who made this possible at all: * Greg Kroah-Hartman, for his faith in my potential subsystem maintainer skills. Greg, I hope I met your expectations. * Late David Brownell, for helping me convert the i2c subsystem to the standard device driver model. Rest in peace David, we're missing you. * Ben Dooks, for stepping in when I asked for someone to take care of the huge flow of new i2c adapter drivers for embedded systems. * Wolfram Sang, for joining the crew when it became clear that there was more review work than Ben and myself could deal with. I hope I did not forget anyone, please forgive me if I did. Another big thank is due to Wolfram again, who quickly proposed to take over as the main i2c subsystem maintainer. This will allow for a smooth and fast transition. Note that I will keep maintaining all I2C/SMBus controller drivers for PC systems as well as a few others. I am hereby updating MAINTAINERS accordingly. I'll also keep maintaining user-space i2c-tools. Signed-off-by: Jean Delvare Cc: Greg Kroah-Hartman Cc: Ben Dooks Acked-by: Wolfram Sang --- MAINTAINERS | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 59203e7..ff8e763 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3598,6 +3598,49 @@ F: drivers/hid/hid-hyperv.c F: drivers/net/hyperv/ F: drivers/staging/hv/ +I2C OVER PARALLEL PORT +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-parport +F: Documentation/i2c/busses/i2c-parport-light +F: drivers/i2c/busses/i2c-parport.c +F: drivers/i2c/busses/i2c-parport-light.c + +I2C/SMBUS CONTROLLER DRIVERS FOR PC +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-ali1535 +F: Documentation/i2c/busses/i2c-ali1563 +F: Documentation/i2c/busses/i2c-ali15x3 +F: Documentation/i2c/busses/i2c-amd756 +F: Documentation/i2c/busses/i2c-amd8111 +F: Documentation/i2c/busses/i2c-i801 +F: Documentation/i2c/busses/i2c-nforce2 +F: Documentation/i2c/busses/i2c-piix4 +F: Documentation/i2c/busses/i2c-sis5595 +F: Documentation/i2c/busses/i2c-sis630 +F: Documentation/i2c/busses/i2c-sis96x +F: Documentation/i2c/busses/i2c-via +F: Documentation/i2c/busses/i2c-viapro +F: drivers/i2c/busses/i2c-ali1535.c +F: drivers/i2c/busses/i2c-ali1563.c +F: drivers/i2c/busses/i2c-ali15x3.c +F: drivers/i2c/busses/i2c-amd756.c +F: drivers/i2c/busses/i2c-amd756-s4882.c +F: drivers/i2c/busses/i2c-amd8111.c +F: drivers/i2c/busses/i2c-i801.c +F: drivers/i2c/busses/i2c-isch.c +F: drivers/i2c/busses/i2c-nforce2.c +F: drivers/i2c/busses/i2c-nforce2-s4985.c +F: drivers/i2c/busses/i2c-piix4.c +F: drivers/i2c/busses/i2c-sis5595.c +F: drivers/i2c/busses/i2c-sis630.c +F: drivers/i2c/busses/i2c-sis96x.c +F: drivers/i2c/busses/i2c-via.c +F: drivers/i2c/busses/i2c-viapro.c + I2C/SMBUS STUB DRIVER M: "Mark M. Hoffman" L: linux-i2c@vger.kernel.org @@ -3605,9 +3648,8 @@ S: Maintained F: drivers/i2c/busses/i2c-stub.c I2C SUBSYSTEM -M: "Jean Delvare (PC drivers, core)" +M: Wolfram Sang M: "Ben Dooks (embedded platforms)" -M: "Wolfram Sang (embedded platforms)" L: linux-i2c@vger.kernel.org W: http://i2c.wiki.kernel.org/ T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ @@ -3618,6 +3660,13 @@ F: drivers/i2c/ F: include/linux/i2c.h F: include/linux/i2c-*.h +I2C-TAOS-EVM DRIVER +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-taos-evm +F: drivers/i2c/busses/i2c-taos-evm.c + I2C-TINY-USB DRIVER M: Till Harbaum L: linux-i2c@vger.kernel.org @@ -7887,13 +7936,6 @@ M: Roger Luethi S: Maintained F: drivers/net/ethernet/via/via-rhine.c -VIAPRO SMBUS DRIVER -M: Jean Delvare -L: linux-i2c@vger.kernel.org -S: Maintained -F: Documentation/i2c/busses/i2c-viapro -F: drivers/i2c/busses/i2c-viapro.c - VIA SD/MMC CARD CONTROLLER DRIVER M: Bruce Chang M: Harald Welte -- cgit v1.1 From aa1e3e81e75ceb3d977c3292cefafcd5179eb8b8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 13 Nov 2012 22:27:19 +0100 Subject: i2c-mux-pinctrl: Fix probe error path When allocating the memory for i2c busses, the code checked the wrong variable and thus never detected if there was a memory error. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org Signed-off-by: Jean Delvare --- drivers/i2c/muxes/i2c-mux-pinctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 5f097f3..7fa5b24 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) mux->busses = devm_kzalloc(&pdev->dev, sizeof(mux->busses) * mux->pdata->bus_count, GFP_KERNEL); - if (!mux->states) { + if (!mux->busses) { dev_err(&pdev->dev, "Cannot allocate busses\n"); ret = -ENOMEM; goto err; -- cgit v1.1 From eb5ce43997b10dd07a63befeb26778d996c5a356 Mon Sep 17 00:00:00 2001 From: Rami Rosen Date: Tue, 13 Nov 2012 13:29:15 +0000 Subject: vxlan: fix a typo. Use eXtensible and not eXtensiable in the comment on top. Signed-off-by: Rami Rosen Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 0c4d0f4..3d0bf66 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1,5 +1,5 @@ /* - * VXLAN: Virtual eXtensiable Local Area Network + * VXLAN: Virtual eXtensible Local Area Network * * Copyright (c) 2012 Vyatta Inc. * -- cgit v1.1 From 1ba56fb45a927d083f655302e75a1911a75b5da6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 13 Nov 2012 13:10:59 +0000 Subject: vxlan: Update hard_header_len based on lowerdev when instantiating VXLAN In the event of a VXLAN device being linked to a device that has a hard_header_len greater than that of standard ethernet we could end up with the hard_header_len not being large enough for outgoing frames. In order to prevent this we should update the length when a lowerdev is provided. Signed-off-by: Alexander Duyck Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 3d0bf66..8b5c619 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1102,6 +1102,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, if (!tb[IFLA_MTU]) dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; + + /* update header length based on lower device */ + dev->hard_header_len = lowerdev->hard_header_len + + VXLAN_HEADROOM; } if (data[IFLA_VXLAN_TOS]) -- cgit v1.1 From 3c6bdaeab4fda6c9fdd5f3f5c610dea97bddf7d6 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 18 Sep 2012 12:19:30 -0400 Subject: [SCSI] Add a report opcode helper The REPORT SUPPORTED OPERATION CODES command can be used to query whether a given opcode is supported by a device. Add a helper function that allows us to look up commands. We only issue RSOC if the device reports compliance with SPC-3 or later. But to err on the side of caution we disable the command for ATA, FireWire and USB. Signed-off-by: Martin K. Petersen Acked-by: Mike Snitzer Signed-off-by: James Bottomley --- drivers/ata/libata-scsi.c | 1 + drivers/firewire/sbp2.c | 1 + drivers/scsi/scsi.c | 45 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/storage/scsiglue.c | 3 +++ include/scsi/scsi_device.h | 3 +++ 5 files changed, 53 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e3bda074..7c2dead 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1052,6 +1052,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) { sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; + sdev->no_report_opcodes = 1; /* Schedule policy is determined by ->qc_defer() callback and * it needs to see every deferred qc. Set dev_blocked to 1 to diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 1162d6b..f82e9d4 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1546,6 +1546,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) struct sbp2_logical_unit *lu = sdev->hostdata; sdev->use_10_for_rw = 1; + sdev->no_report_opcodes = 1; if (sbp2_param_exclusive_login) sdev->manage_start_stop = 1; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2936b44..2c0d0ec 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -1062,6 +1063,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, EXPORT_SYMBOL_GPL(scsi_get_vpd_page); /** + * scsi_report_opcode - Find out if a given command opcode is supported + * @sdev: scsi device to query + * @buffer: scratch buffer (must be at least 20 bytes long) + * @len: length of buffer + * @opcode: opcode for command to look up + * + * Uses the REPORT SUPPORTED OPERATION CODES to look up the given + * opcode. Returns 0 if RSOC fails or if the command opcode is + * unsupported. Returns 1 if the device claims to support the command. + */ +int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, + unsigned int len, unsigned char opcode) +{ + unsigned char cmd[16]; + struct scsi_sense_hdr sshdr; + int result; + + if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) + return 0; + + memset(cmd, 0, 16); + cmd[0] = MAINTENANCE_IN; + cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; + cmd[2] = 1; /* One command format */ + cmd[3] = opcode; + put_unaligned_be32(len, &cmd[6]); + memset(buffer, 0, len); + + result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, + &sshdr, 30 * HZ, 3, NULL); + + if (result && scsi_sense_valid(&sshdr) && + sshdr.sense_key == ILLEGAL_REQUEST && + (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) + return 0; + + if ((buffer[1] & 3) == 3) /* Command supported */ + return 1; + + return 0; +} +EXPORT_SYMBOL(scsi_report_opcode); + +/** * scsi_device_get - get an additional reference to a scsi_device * @sdev: device to get a reference to * diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a3d5436..6ab376a 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -186,6 +186,9 @@ static int slave_configure(struct scsi_device *sdev) /* Some devices don't handle VPD pages correctly */ sdev->skip_vpd_pages = 1; + /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ + sdev->no_report_opcodes = 1; + /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 88fae8d..379d465 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -135,6 +135,7 @@ struct scsi_device { * because we did a bus reset. */ unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ @@ -362,6 +363,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, struct scsi_sense_hdr *sshdr); extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, int buf_len); +extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, + unsigned int len, unsigned char opcode); extern int scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state); extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, -- cgit v1.1 From 26e85fcd15f68b57d9ba645cd3591117a8ac0e05 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 18 Sep 2012 12:19:31 -0400 Subject: [SCSI] sd: Permit merged discard requests Support requests with more than one bio payload for discards. The total number of bytes to be discarded is stored in req->__data_len and used in sd_done() to complete the I/O. Signed-off-by: Martin K. Petersen Reviewed-by: Mike Snitzer Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12f6fdf..c6af4c1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -583,29 +583,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) } /** - * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device + * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device * @sdp: scsi device to operate one * @rq: Request to prepare * * Will issue either UNMAP or WRITE SAME(16) depending on preference * indicated by target device. **/ -static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) +static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) { struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); - struct bio *bio = rq->bio; - sector_t sector = bio->bi_sector; - unsigned int nr_sectors = bio_sectors(bio); + sector_t sector = blk_rq_pos(rq); + unsigned int nr_sectors = blk_rq_sectors(rq); + unsigned int nr_bytes = blk_rq_bytes(rq); unsigned int len; int ret; char *buf; struct page *page; - if (sdkp->device->sector_size == 4096) { - sector >>= 3; - nr_sectors >>= 3; - } - + sector >>= ilog2(sdp->sector_size) - 9; + nr_sectors >>= ilog2(sdp->sector_size) - 9; rq->timeout = SD_TIMEOUT; memset(rq->cmd, 0, rq->cmd_len); @@ -660,6 +657,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) blk_add_request_payload(rq, page, len); ret = scsi_setup_blk_pc_cmnd(sdp, rq); rq->buffer = page_address(page); + rq->__data_len = nr_bytes; out: if (ret != BLKPREP_OK) { @@ -712,7 +710,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) * block PC requests to make life easier. */ if (rq->cmd_flags & REQ_DISCARD) { - ret = scsi_setup_discard_cmnd(sdp, rq); + ret = sd_setup_discard_cmnd(sdp, rq); goto out; } else if (rq->cmd_flags & REQ_FLUSH) { ret = scsi_setup_flush_cmnd(sdp, rq); @@ -1482,12 +1480,20 @@ static int sd_done(struct scsi_cmnd *SCpnt) unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); struct scsi_sense_hdr sshdr; struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); + struct request *req = SCpnt->request; int sense_valid = 0; int sense_deferred = 0; unsigned char op = SCpnt->cmnd[0]; - if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) - scsi_set_resid(SCpnt, 0); + if (req->cmd_flags & REQ_DISCARD) { + if (!result) { + good_bytes = blk_rq_bytes(req); + scsi_set_resid(SCpnt, 0); + } else { + good_bytes = 0; + scsi_set_resid(SCpnt, blk_rq_bytes(req)); + } + } if (result) { sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); -- cgit v1.1 From 5db44863b6ebbb400c5e61d56ebe8f21ef48b1bd Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 18 Sep 2012 12:19:32 -0400 Subject: [SCSI] sd: Implement support for WRITE SAME Implement support for WRITE SAME(10) and WRITE SAME(16) in the SCSI disk driver. - We set the default maximum to 0xFFFF because there are several devices out there that only support two-byte block counts even with WRITE SAME(16). We only enable transfers bigger than 0xFFFF if the device explicitly reports MAXIMUM WRITE SAME LENGTH in the BLOCK LIMITS VPD. - max_write_same_blocks can be overriden per-device basis in sysfs. - The UNMAP discovery heuristics remain unchanged but the discard limits are tweaked to match the "real" WRITE SAME commands. - In the error handling logic we now distinguish between WRITE SAME with and without UNMAP set. The discovery process heuristics are: - If the device reports a SCSI level of SPC-3 or greater we'll issue READ SUPPORTED OPERATION CODES to find out whether WRITE SAME(16) is supported. If that's the case we will use it. - If the device supports the block limits VPD and reports a MAXIMUM WRITE SAME LENGTH bigger than 0xFFFF we will use WRITE SAME(16). - Otherwise we will use WRITE SAME(10) unless the target LBA is beyond 0xFFFFFFFF or the block count exceeds 0xFFFF. - no_write_same is set for ATA, FireWire and USB. Signed-off-by: Martin K. Petersen Reviewed-by: Mike Snitzer Reviewed-by: Jeff Garzik Signed-off-by: James Bottomley --- drivers/ata/libata-scsi.c | 1 + drivers/firewire/sbp2.c | 1 + drivers/scsi/scsi_lib.c | 22 ++++-- drivers/scsi/sd.c | 172 ++++++++++++++++++++++++++++++++++++++--- drivers/scsi/sd.h | 7 ++ drivers/usb/storage/scsiglue.c | 3 + include/scsi/scsi_device.h | 1 + 7 files changed, 191 insertions(+), 16 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7c2dead..a6df6a3 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1053,6 +1053,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; sdev->no_report_opcodes = 1; + sdev->no_write_same = 1; /* Schedule policy is determined by ->qc_defer() callback and * it needs to see every deferred qc. Set dev_blocked to 1 to diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index f82e9d4..bb1b392 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1547,6 +1547,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) sdev->use_10_for_rw = 1; sdev->no_report_opcodes = 1; + sdev->no_write_same = 1; if (sbp2_param_exclusive_login) sdev->manage_start_stop = 1; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index da36a3a..9032e91 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) action = ACTION_FAIL; error = -EILSEQ; /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && - (cmd->cmnd[0] == UNMAP || - cmd->cmnd[0] == WRITE_SAME_16 || - cmd->cmnd[0] == WRITE_SAME)) { - description = "Discard failure"; + } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { + switch (cmd->cmnd[0]) { + case UNMAP: + description = "Discard failure"; + break; + case WRITE_SAME: + case WRITE_SAME_16: + if (cmd->cmnd[1] & 0x8) + description = "Discard failure"; + else + description = + "Write same failure"; + break; + default: + description = "Invalid command failure"; + break; + } action = ACTION_FAIL; error = -EREMOTEIO; } else diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c6af4c1..352bc77 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); #endif static void sd_config_discard(struct scsi_disk *, unsigned int); +static void sd_config_write_same(struct scsi_disk *); static int sd_revalidate_disk(struct gendisk *); static void sd_unlock_native_capacity(struct gendisk *disk); static int sd_probe(struct device *); @@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev, return err ? err : count; } +static ssize_t +sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); +} + +static ssize_t +sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + unsigned long max; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (sdp->type != TYPE_DISK) + return -EINVAL; + + err = kstrtoul(buf, 10, &max); + + if (err) + return err; + + if (max == 0) + sdp->no_write_same = 1; + else if (max <= SD_MAX_WS16_BLOCKS) + sdkp->max_ws_blocks = max; + + sd_config_write_same(sdkp); + + return count; +} + static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = { __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, sd_store_provisioning_mode), + __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, + sd_show_write_same_blocks, sd_store_write_same_blocks), __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, sd_show_max_medium_access_timeouts, sd_store_max_medium_access_timeouts), @@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) return; case SD_LBP_UNMAP: - max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); + max_blocks = min_not_zero(sdkp->max_unmap_blocks, + (u32)SD_MAX_WS16_BLOCKS); break; case SD_LBP_WS16: - max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); + max_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS16_BLOCKS); break; case SD_LBP_WS10: - max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); + max_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); break; case SD_LBP_ZERO: - max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); + max_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); q->limits.discard_zeroes_data = 1; break; } @@ -667,6 +713,83 @@ out: return ret; } +static void sd_config_write_same(struct scsi_disk *sdkp) +{ + struct request_queue *q = sdkp->disk->queue; + unsigned int logical_block_size = sdkp->device->sector_size; + unsigned int blocks = 0; + + if (sdkp->device->no_write_same) { + sdkp->max_ws_blocks = 0; + goto out; + } + + /* Some devices can not handle block counts above 0xffff despite + * supporting WRITE SAME(16). Consequently we default to 64k + * blocks per I/O unless the device explicitly advertises a + * bigger limit. + */ + if (sdkp->max_ws_blocks == 0) + sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; + + if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) + blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS16_BLOCKS); + else + blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); + +out: + blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); +} + +/** + * sd_setup_write_same_cmnd - write the same data to multiple blocks + * @sdp: scsi device to operate one + * @rq: Request to prepare + * + * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on + * preference indicated by target device. + **/ +static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) +{ + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); + struct bio *bio = rq->bio; + sector_t sector = blk_rq_pos(rq); + unsigned int nr_sectors = blk_rq_sectors(rq); + unsigned int nr_bytes = blk_rq_bytes(rq); + int ret; + + if (sdkp->device->no_write_same) + return BLKPREP_KILL; + + BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); + + sector >>= ilog2(sdp->sector_size) - 9; + nr_sectors >>= ilog2(sdp->sector_size) - 9; + + rq->__data_len = sdp->sector_size; + rq->timeout = SD_WRITE_SAME_TIMEOUT; + memset(rq->cmd, 0, rq->cmd_len); + + if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { + rq->cmd_len = 16; + rq->cmd[0] = WRITE_SAME_16; + put_unaligned_be64(sector, &rq->cmd[2]); + put_unaligned_be32(nr_sectors, &rq->cmd[10]); + } else { + rq->cmd_len = 10; + rq->cmd[0] = WRITE_SAME; + put_unaligned_be32(sector, &rq->cmd[2]); + put_unaligned_be16(nr_sectors, &rq->cmd[7]); + } + + ret = scsi_setup_blk_pc_cmnd(sdp, rq); + rq->__data_len = nr_bytes; + + return ret; +} + static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) { rq->timeout = SD_FLUSH_TIMEOUT; @@ -712,6 +835,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) if (rq->cmd_flags & REQ_DISCARD) { ret = sd_setup_discard_cmnd(sdp, rq); goto out; + } else if (rq->cmd_flags & REQ_WRITE_SAME) { + ret = sd_setup_write_same_cmnd(sdp, rq); + goto out; } else if (rq->cmd_flags & REQ_FLUSH) { ret = scsi_setup_flush_cmnd(sdp, rq); goto out; @@ -1484,8 +1610,9 @@ static int sd_done(struct scsi_cmnd *SCpnt) int sense_valid = 0; int sense_deferred = 0; unsigned char op = SCpnt->cmnd[0]; + unsigned char unmap = SCpnt->cmnd[1] & 8; - if (req->cmd_flags & REQ_DISCARD) { + if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { if (!result) { good_bytes = blk_rq_bytes(req); scsi_set_resid(SCpnt, 0); @@ -1542,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ good_bytes = sd_completed_bytes(SCpnt); /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && - (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) - sd_config_discard(sdkp, SD_LBP_DISABLE); + if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { + switch (op) { + case UNMAP: + sd_config_discard(sdkp, SD_LBP_DISABLE); + break; + case WRITE_SAME_16: + case WRITE_SAME: + if (unmap) + sd_config_discard(sdkp, SD_LBP_DISABLE); + else { + sdkp->device->no_write_same = 1; + sd_config_write_same(sdkp); + + good_bytes = 0; + req->__data_len = blk_rq_bytes(req); + req->cmd_flags |= REQ_QUIET; + } + } + } break; default: break; @@ -2380,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) if (buffer[3] == 0x3c) { unsigned int lba_count, desc_count; - sdkp->max_ws_blocks = - (u32) min_not_zero(get_unaligned_be64(&buffer[36]), - (u64)0xffffffff); + sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); if (!sdkp->lbpme) goto out; @@ -2475,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) kfree(buffer); } +static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) +{ + if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, + WRITE_SAME_16)) + sdkp->ws16 = 1; +} + static int sd_try_extended_inquiry(struct scsi_device *sdp) { /* @@ -2534,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_write_protect_flag(sdkp, buffer); sd_read_cache_type(sdkp, buffer); sd_read_app_tag_own(sdkp, buffer); + sd_read_write_same(sdkp, buffer); } sdkp->first_scan = 0; @@ -2551,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) blk_queue_flush(sdkp->disk->queue, flush); set_capacity(disk, sdkp->capacity); + sd_config_write_same(sdkp); kfree(buffer); out: diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 47c52a6..74a1e4c 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -14,6 +14,7 @@ #define SD_TIMEOUT (30 * HZ) #define SD_MOD_TIMEOUT (75 * HZ) #define SD_FLUSH_TIMEOUT (60 * HZ) +#define SD_WRITE_SAME_TIMEOUT (120 * HZ) /* * Number of allowed retries @@ -39,6 +40,11 @@ enum { }; enum { + SD_MAX_WS10_BLOCKS = 0xffff, + SD_MAX_WS16_BLOCKS = 0x7fffff, +}; + +enum { SD_LBP_FULL = 0, /* Full logical block provisioning */ SD_LBP_UNMAP, /* Use UNMAP command */ SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ @@ -77,6 +83,7 @@ struct scsi_disk { unsigned lbpws : 1; unsigned lbpws10 : 1; unsigned lbpvpd : 1; + unsigned ws16 : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 6ab376a..92f35ab 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -189,6 +189,9 @@ static int slave_configure(struct scsi_device *sdev) /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ sdev->no_report_opcodes = 1; + /* Do not attempt to use WRITE SAME */ + sdev->no_write_same = 1; + /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 379d465..55367b0 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -136,6 +136,7 @@ struct scsi_device { unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ + unsigned no_write_same:1; /* no WRITE SAME command */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ -- cgit v1.1 From effded75e24c7941961d473e4f4babed4c52af3c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 14 Nov 2012 11:23:54 +0300 Subject: ALSA: fm801: precedence bug in snd_fm801_tea575x_get_pins() There is a precedence bug because | has higher precedence than ?:. This code was cut and pasted and I fixed a similar bug a few days ago. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index cc2e91d..c5806f8 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -767,9 +767,14 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) struct fm801 *chip = tea->private_data; unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); - - return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | - (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; + u8 ret; + + ret = 0; + if (reg & FM801_GPIO_GP(gpio.data)) + ret |= TEA575X_DATA; + if (reg & FM801_GPIO_GP(gpio.most)) + ret |= TEA575X_MOST; + return ret; } static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) -- cgit v1.1 From 0d852fe4d27fa82de9fdcbda9a5ac634800b1fd1 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Tue, 13 Nov 2012 16:43:21 +0100 Subject: i2c: at91: fix SMBus quick command The driver claims to support SMBus quick command but it was not the case. This patch fixes this issue. Without it, i2cdetect finds imaginary devices. And with some IP versions, trying to send 0 byte can cause issue when writing data to an EEPROM. Signed-off-by: Ludovic Desroches Acked-by: Jean-Christophe PLAGNIOL-VILLARD [wsa: improved the commit message] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index aa59a25..c02bf20 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -39,6 +39,7 @@ #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ +#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */ #define AT91_TWI_SWRST 0x0080 /* Software Reset */ #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ @@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) INIT_COMPLETION(dev->cmd_complete); dev->transfer_status = 0; - if (dev->msg->flags & I2C_M_RD) { + + if (!dev->buf_len) { + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); + } else if (dev->msg->flags & I2C_M_RD) { unsigned start_flags = AT91_TWI_START; if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { -- cgit v1.1 From 23ff2f0f6128b4c310fbb274dbb91cc2f9b6ab06 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 14 Nov 2012 09:39:31 +0000 Subject: regulator: core: Avoid deadlock when regulator_register fails When regulator_register fails and exits through the scrub path the regulator_put function was called whilst holding the regulator_list_mutex, causing deadlock. This patch adds a private version of the regulator_put function which can be safely called whilst holding the mutex, replacing the aforementioned call. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/regulator/core.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829c..3ebc06b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_exclusive); -/** - * regulator_put - "free" the regulator source - * @regulator: regulator source - * - * Note: drivers must ensure that all regulator_enable calls made on this - * regulator source are balanced by regulator_disable calls prior to calling - * this function. - */ -void regulator_put(struct regulator *regulator) +/* Locks held by regulator_put() */ +static void _regulator_put(struct regulator *regulator) { struct regulator_dev *rdev; if (regulator == NULL || IS_ERR(regulator)) return; - mutex_lock(®ulator_list_mutex); rdev = regulator->rdev; debugfs_remove_recursive(regulator->debugfs); @@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) rdev->exclusive = 0; module_put(rdev->owner); +} + +/** + * regulator_put - "free" the regulator source + * @regulator: regulator source + * + * Note: drivers must ensure that all regulator_enable calls made on this + * regulator source are balanced by regulator_disable calls prior to calling + * this function. + */ +void regulator_put(struct regulator *regulator) +{ + mutex_lock(®ulator_list_mutex); + _regulator_put(regulator); mutex_unlock(®ulator_list_mutex); } EXPORT_SYMBOL_GPL(regulator_put); @@ -3445,7 +3451,7 @@ unset_supplies: scrub: if (rdev->supply) - regulator_put(rdev->supply); + _regulator_put(rdev->supply); if (rdev->ena_gpio) gpio_free(rdev->ena_gpio); kfree(rdev->constraints); -- cgit v1.1 From 04baaa27b43d389879237b32f8bd194a94cf1ca7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 13 Nov 2012 21:28:44 +0100 Subject: iwlwifi: fix monitor mode FCS flag When the firmware is in SNIFFER mode, it leaves the FCS at the end of frame. Not telling mac80211 means it won't add the right flag to the radiotap header and that confuses wireshark. Since mac80211 doesn't have a per-packet flag, set the HW flag dynamically. This works as the monitor vif can only be present in the driver by itself. This fixes a regression introduced by my commit 578977264199de9815ace51ade87cec4894cf010 Author: Johannes Berg Date: Fri May 11 10:53:18 2012 +0200 iwlwifi: support explicit monitor interface Cc: stable@vger.kernel.org [3.5+] Reported-by: MARK PHILLIPS Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index fa4d1b8..2d9eee9 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, vif_priv->ctx = ctx; ctx->vif = vif; + /* + * In SNIFFER device type, the firmware reports the FCS to + * the host, rather than snipping it off. Unfortunately, + * mac80211 doesn't (yet) provide a per-packet flag for + * this, so that we have to set the hardware flag based + * on the interfaces added. As the monitor interface can + * only be present by itself, and will be removed before + * other interfaces are added, this is safe. + */ + if (vif->type == NL80211_IFTYPE_MONITOR) + priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; + else + priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; + err = iwl_setup_interface(priv, ctx); if (!err || reset) goto out; -- cgit v1.1 From 9aadd70aed60b47e367e7a1a6b9068daba04fe05 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 6 Nov 2012 16:31:32 +0000 Subject: Revert "ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints" This reverts commit 3db11feffc1ad2ab9dea27789e6b5b3032827adc (ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints). This commit causes I2C timeouts to appear on several OMAP3430/3530-based boards: http://marc.info/?l=linux-arm-kernel&m=135071372426971&w=2 http://marc.info/?l=linux-arm-kernel&m=135067558415214&w=2 http://marc.info/?l=linux-arm-kernel&m=135216013608196&w=2 and appears to have been sent for merging before one of its prerequisites was merged: http://marc.info/?l=linux-arm-kernel&m=135219411617621&w=2 Signed-off-by: Paul Walmsley Acked-by: Jean Pihet Signed-off-by: Wolfram Sang --- arch/arm/plat-omap/i2c.c | 21 +++++++++++++++++++++ drivers/i2c/busses/i2c-omap.c | 32 ++++++++++++++------------------ include/linux/i2c-omap.h | 1 + 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a5683a8..6013831 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -26,12 +26,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #define OMAP_I2C_SIZE 0x3f @@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id) #ifdef CONFIG_ARCH_OMAP2PLUS +/* + * XXX This function is a temporary compatibility wrapper - only + * needed until the I2C driver can be converted to call + * omap_pm_set_max_dev_wakeup_lat() and handle a return code. + */ +static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) +{ + omap_pm_set_max_mpu_wakeup_lat(dev, t); +} + static inline int omap2_i2c_add_bus(int bus_id) { int l; @@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id) dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; pdata->flags = dev_attr->flags; + /* + * When waiting for completion of a i2c transfer, we need to + * set a wake up latency constraint for the MPU. This is to + * ensure quick enough wakeup from idle, when transfer + * completes. + * Only omap3 has support for constraints + */ + if (cpu_is_omap34xx()) + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data), NULL, 0, 0); diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eae..0b02543 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -43,7 +43,6 @@ #include #include #include -#include /* I2C controller revisions */ #define OMAP_I2C_OMAP1_REV_2 0x20 @@ -187,8 +186,9 @@ struct omap_i2c_dev { int reg_shift; /* bit shift for I2C register addresses */ struct completion cmd_complete; struct resource *ioarea; - u32 latency; /* maximum MPU wkup latency */ - struct pm_qos_request pm_qos_request; + u32 latency; /* maximum mpu wkup latency */ + void (*set_mpu_wkup_lat)(struct device *dev, + long latency); u32 speed; /* Speed of bus in kHz */ u32 dtrev; /* extra revision from DT */ u32 flags; @@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) dev->b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ - dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); + if (dev->set_mpu_wkup_lat != NULL) + dev->latency = (1000000 * dev->threshold) / + (1000 * dev->speed / 8); } /* @@ -629,16 +631,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (r < 0) goto out; - /* - * When waiting for completion of a i2c transfer, we need to - * set a wake up latency constraint for the MPU. This is to - * ensure quick enough wakeup from idle, when transfer - * completes. - */ - if (dev->latency) - pm_qos_add_request(&dev->pm_qos_request, - PM_QOS_CPU_DMA_LATENCY, - dev->latency); + if (dev->set_mpu_wkup_lat != NULL) + dev->set_mpu_wkup_lat(dev->dev, dev->latency); for (i = 0; i < num; i++) { r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); @@ -646,8 +640,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) break; } - if (dev->latency) - pm_qos_remove_request(&dev->pm_qos_request); + if (dev->set_mpu_wkup_lat != NULL) + dev->set_mpu_wkup_lat(dev->dev, -1); if (r == 0) r = num; @@ -1104,6 +1098,7 @@ omap_i2c_probe(struct platform_device *pdev) } else if (pdata != NULL) { dev->speed = pdata->clkrate; dev->flags = pdata->flags; + dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; dev->dtrev = pdata->rev; } @@ -1159,8 +1154,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ - dev->latency = (1000000 * dev->fifo_size) / - (1000 * dev->speed / 8); + if (dev->set_mpu_wkup_lat != NULL) + dev->latency = (1000000 * dev->fifo_size) / + (1000 * dev->speed / 8); } /* reset ASAP, clearing any IRQs */ diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index df804ba..92a0dc7 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -34,6 +34,7 @@ struct omap_i2c_bus_platform_data { u32 clkrate; u32 rev; u32 flags; + void (*set_mpu_wkup_lat)(struct device *dev, long set); }; #endif -- cgit v1.1 From 10e44239f67d0b6fb74006e61a7e883b8075247a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Nov 2012 11:22:48 +0100 Subject: ALSA: usb-audio: Fix mutex deadlock at disconnection The recent change for USB-audio disconnection race fixes introduced a mutex deadlock again. There is a circular dependency between chip->shutdown_rwsem and pcm->open_mutex, depicted like below, when a device is opened during the disconnection operation: A. snd_usb_audio_disconnect() -> card.c::register_mutex -> chip->shutdown_rwsem (write) -> snd_card_disconnect() -> pcm.c::register_mutex -> pcm->open_mutex B. snd_pcm_open() -> pcm->open_mutex -> snd_usb_pcm_open() -> chip->shutdown_rwsem (read) Since the chip->shutdown_rwsem protection in the case A is required only for turning on the chip->shutdown flag and it doesn't have to be taken for the whole operation, we can reduce its window in snd_usb_audio_disconnect(). Reported-by: Jiri Slaby Cc: Signed-off-by: Takashi Iwai --- sound/usb/card.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 282f0fc..dbf7999 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, return; card = chip->card; - mutex_lock(®ister_mutex); down_write(&chip->shutdown_rwsem); chip->shutdown = 1; + up_write(&chip->shutdown_rwsem); + + mutex_lock(®ister_mutex); chip->num_interfaces--; if (chip->num_interfaces <= 0) { snd_card_disconnect(card); @@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; - up_write(&chip->shutdown_rwsem); mutex_unlock(®ister_mutex); snd_card_free_when_closed(card); } else { - up_write(&chip->shutdown_rwsem); mutex_unlock(®ister_mutex); } } -- cgit v1.1 From aedc256dd032fe9b0691fdd0f67b5e65e3e7bc0d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 14 Nov 2012 16:22:45 +0200 Subject: i2c: omap: ensure writes to dev->buf_len are ordered if we allow compiler reorder our writes, we could fall into a situation where dev->buf_len is reset for no apparent reason. This bug was found with a simple script which would transfer data to an i2c client from 1 to 1024 bytes (a simple for loop), when we got to transfer sizes bigger than the fifo size, dev->buf_len was reset to zero before we had an oportunity to handle XDR Interrupt. Because dev->buf_len was zero, we entered omap_i2c_transmit_data() to transfer zero bytes, which would mean we would just silently exit omap_i2c_transmit_data() without actually writing anything to DATA register. That would cause XDR IRQ to trigger forever and we would never transfer the remaining bytes. After adding the memory barrier, we also drop resetting dev->buf_len to zero in omap_i2c_xfer_msg() because both omap_i2c_transmit_data() and omap_i2c_receive_data() will act until dev->buf_len reaches zero, rendering the other write in omap_i2c_xfer_msg() redundant. This patch has been tested with pandaboard for a few iterations of the script mentioned above. Signed-off-by: Felipe Balbi Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0b02543..3525c9e 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -524,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, dev->buf = msg->buf; dev->buf_len = msg->len; + /* make sure writes to dev->buf_len are ordered */ + barrier(); + omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); /* Clear the FIFO Buffers */ @@ -581,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, */ timeout = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); - dev->buf_len = 0; if (timeout == 0) { dev_err(dev->dev, "controller timed out\n"); omap_i2c_init(dev); -- cgit v1.1 From d61f978b8f26d2392c88249f877e46e2c2b5561d Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 4 Nov 2012 23:13:09 +0100 Subject: brcmfmac: fix typo in CONFIG_BRCMISCAN The old ifdef CONFIG_BRCMFISCAN looks wrong to me and it makes more sense when CONFIG_BRCMISCAN is used. This patch was just compile tested by me, but not runtime tested. Signed-off-by: Hauke Mehrtens Acked-by: Franky Lin Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index a6f1e81..481345c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4401,7 +4401,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) static void brcmf_wiphy_pno_params(struct wiphy *wiphy) { -#ifndef CONFIG_BRCMFISCAN +#ifndef CONFIG_BRCMISCAN /* scheduled scan settings */ wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; -- cgit v1.1 From c019bc119a97aa20372c5a2cf210d209380d397d Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 14 Nov 2012 19:15:47 +1100 Subject: TTY: hvc_console, fix port reference count going to zero prematurely Commit bdb498c20040 "TTY: hvc_console, add tty install" took the port refcounting out of hvc_open()/hvc_close(), but failed to remove the kref_put() and tty_kref_put() calls in hvc_hangup() that were there to remove the extra references that hvc_open() had taken. The result was that doing a vhangup() when the current terminal was a hvc_console, then closing the current terminal, would end up calling destroy_hvc_struct() and making the port disappear entirely. This meant that Fedora 17 systems would boot up but then not display the login prompt on the console, and attempts to open /dev/hvc0 would give a "No such device" error. This fixes it by removing the extra kref_put() and tty_kref_put() calls. Signed-off-by: Paul Mackerras Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index a5dec1c..13ee53b 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty) { struct hvc_struct *hp = tty->driver_data; unsigned long flags; - int temp_open_count; if (!hp) return; @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty) return; } - temp_open_count = hp->port.count; hp->port.count = 0; spin_unlock_irqrestore(&hp->port.lock, flags); tty_port_tty_set(&hp->port, NULL); @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty) if (hp->ops->notifier_hangup) hp->ops->notifier_hangup(hp, hp->data); - - while(temp_open_count) { - --temp_open_count; - tty_port_put(&hp->port); - } } /* -- cgit v1.1 From 1838b8c487378c6c576029d9e0e07b5a73036bac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 4 Nov 2012 23:34:18 +0800 Subject: tty: serial: max310x: Add terminating entry for spi_device_id table The spi_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 2bc28a5..1ab1d2c 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1239,6 +1239,7 @@ static int __devexit max310x_remove(struct spi_device *spi) static const struct spi_device_id max310x_id_table[] = { { "max3107", MAX310X_TYPE_MAX3107 }, { "max3108", MAX310X_TYPE_MAX3108 }, + { } }; MODULE_DEVICE_TABLE(spi, max310x_id_table); -- cgit v1.1 From ddd32b4289a6feda9ad9e68b0d85641c389a72ba Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Tue, 13 Nov 2012 02:17:36 +0900 Subject: x86, mm: Correct vmflag test for checking VM_HUGETLB commit 611ae8e3f5204f7480b3b405993b3352cfa16662('enable tlb flush range support for x86') change flush_tlb_mm_range() considerably. After this, we test whether vmflag equal to VM_HUGETLB and it may be always failed, because vmflag usually has other flags simultaneously. Our intention is to check whether this vma is for hughtlb, so correct it according to this purpose. Signed-off-by: Joonsoo Kim Acked-by: Alex Shi Link: http://lkml.kernel.org/r/1352740656-19417-1-git-send-email-js1304@gmail.com Signed-off-by: H. Peter Anvin --- arch/x86/mm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 0777f04..60f926c 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, } if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 - || vmflag == VM_HUGETLB) { + || vmflag & VM_HUGETLB) { local_flush_tlb(); goto flush_all; } -- cgit v1.1 From f0f98b19e23d4426ca185e3d4ca80e6aff5ef51b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 13 Nov 2012 09:48:51 +0100 Subject: regulator: fix voltage check in regulator_is_supported_voltage() regulator_is_supported_voltage() should return true only if the voltage of fixed/constant regulator is between min_uV and max_uV. Signed-off-by: Marek Szyprowski Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829c..27eb9d6 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1974,7 +1974,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { ret = regulator_get_voltage(regulator); if (ret >= 0) - return (min_uV >= ret && ret <= max_uV); + return (min_uV <= ret && ret <= max_uV); else return ret; } -- cgit v1.1 From 70a6f46d7b0ec03653b9ab3f8063a9717a4a53ef Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 14 Nov 2012 11:49:53 +0000 Subject: pstore: Fix NULL pointer dereference in console writes Passing a NULL id causes a NULL pointer deference in writers such as erst_writer and efi_pstore_write because they expect to update this id. Pass a dummy id instead. This avoids a cascade of oopses caused when the initial pstore_console_write passes a null which in turn causes writes to the console causing further oopses in subsequent pstore_console_write calls. Signed-off-by: Colin Ian King Acked-by: Kees Cook Cc: stable@vger.kernel.org Signed-off-by: Anton Vorontsov --- fs/pstore/platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index a40da07..947fbe0 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -161,6 +161,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) while (s < e) { unsigned long flags; + u64 id; if (c > psinfo->bufsize) c = psinfo->bufsize; @@ -172,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) spin_lock_irqsave(&psinfo->buf_lock, flags); } memcpy(psinfo->buf, s, c); - psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); + psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); spin_unlock_irqrestore(&psinfo->buf_lock, flags); s += c; c = e - s; -- cgit v1.1 From b2942004fb5c9f3304b77e187b8a1977b3626c9b Mon Sep 17 00:00:00 2001 From: Saurabh Mohan Date: Wed, 14 Nov 2012 18:08:15 -0800 Subject: ipv4/ip_vti.c: VTI fix post-decryption forwarding With the latest kernel there are two things that must be done post decryption so that the packet are forwarded. 1. Remove the mark from the packet. This will cause the packet to not match the ipsec-policy again. However doing this causes the post-decryption check to fail also and the packet will get dropped. (cat /proc/net/xfrm_stat). 2. Remove the sp association in the skbuff so that no policy check is done on the packet for VTI tunnels. Due to #2 above we must now do a security-policy check in the vti rcv path prior to resetting the mark in the skbuff. Signed-off-by: Saurabh Mohan Reported-by: Ruben Herold Signed-off-by: David S. Miller --- net/ipv4/ip_vti.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 1831092..858fddf 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb) if (tunnel != NULL) { struct pcpu_tstats *tstats; + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) + return -1; + tstats = this_cpu_ptr(tunnel->dev->tstats); u64_stats_update_begin(&tstats->syncp); tstats->rx_packets++; tstats->rx_bytes += skb->len; u64_stats_update_end(&tstats->syncp); + skb->mark = 0; + secpath_reset(skb); skb->dev = tunnel->dev; return 1; } -- cgit v1.1 From 71c6c837a0fe9d291e0764503f09dac0fec59ce1 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Tue, 13 Nov 2012 19:47:36 +0000 Subject: drivers/net: fix tasklet misuse issue In commit 175c0dff, drivers uses tasklet_kill to avoid put disabled tasklet on the tasklet vec. But some of the drivers uses tasklet_init & tasklet_disable in the driver init code, then tasklet_enable when it is opened. This makes tasklet_enable on a killed tasklet and make ksoftirqd crazy then. Normally, drivers should use tasklet_init/tasklet_kill on device open/remove, and use tasklet_disable/tasklet_enable on device suspend/resume. Reported-by: Peter Wu Tested-by: Peter Wu Signed-off-by: Xiaotian Feng Cc: "David S. Miller" Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/ethernet/jme.c | 28 +++++++---------------- drivers/net/ethernet/micrel/ksz884x.c | 16 ++++--------- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 12 +++++----- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 92317e9..60ac46f 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev) jme_clear_pm(jme); JME_NAPI_ENABLE(jme); - tasklet_enable(&jme->linkch_task); - tasklet_enable(&jme->txclean_task); - tasklet_hi_enable(&jme->rxclean_task); - tasklet_hi_enable(&jme->rxempty_task); + tasklet_init(&jme->linkch_task, jme_link_change_tasklet, + (unsigned long) jme); + tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet, + (unsigned long) jme); + tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet, + (unsigned long) jme); + tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet, + (unsigned long) jme); rc = jme_request_irq(jme); if (rc) @@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev, tasklet_init(&jme->pcc_task, jme_pcc_tasklet, (unsigned long) jme); - tasklet_init(&jme->linkch_task, - jme_link_change_tasklet, - (unsigned long) jme); - tasklet_init(&jme->txclean_task, - jme_tx_clean_tasklet, - (unsigned long) jme); - tasklet_init(&jme->rxclean_task, - jme_rx_clean_tasklet, - (unsigned long) jme); - tasklet_init(&jme->rxempty_task, - jme_rx_empty_tasklet, - (unsigned long) jme); - tasklet_disable_nosync(&jme->linkch_task); - tasklet_disable_nosync(&jme->txclean_task); - tasklet_disable_nosync(&jme->rxclean_task); - tasklet_disable_nosync(&jme->rxempty_task); jme->dpi.cur = PCC_P1; jme->reg_ghc = 0; diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e558edd..69e0197 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev) rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); if (rc) return rc; - tasklet_enable(&hw_priv->rx_tasklet); - tasklet_enable(&hw_priv->tx_tasklet); + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, + (unsigned long) hw_priv); + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, + (unsigned long) hw_priv); hw->promiscuous = 0; hw->all_multi = 0; @@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, spin_lock_init(&hw_priv->hwlock); mutex_init(&hw_priv->lock); - /* tasklet is enabled. */ - tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, - (unsigned long) hw_priv); - tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, - (unsigned long) hw_priv); - - /* tasklet_enable will decrement the atomic counter. */ - tasklet_disable(&hw_priv->rx_tasklet); - tasklet_disable(&hw_priv->tx_tasklet); - for (i = 0; i < TOTAL_PORT_NUM; i++) init_waitqueue_head(&hw_priv->counter[i].counter); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1d04754..77e6db9 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -942,6 +942,10 @@ static int axienet_open(struct net_device *ndev) phy_start(lp->phy_dev); } + /* Enable tasklets for Axi DMA error handling */ + tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, + (unsigned long) lp); + /* Enable interrupts for Axi DMA Tx */ ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); if (ret) @@ -950,8 +954,7 @@ static int axienet_open(struct net_device *ndev) ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); if (ret) goto err_rx_irq; - /* Enable tasklets for Axi DMA error handling */ - tasklet_enable(&lp->dma_err_tasklet); + return 0; err_rx_irq: @@ -960,6 +963,7 @@ err_tx_irq: if (lp->phy_dev) phy_disconnect(lp->phy_dev); lp->phy_dev = NULL; + tasklet_kill(&lp->dma_err_tasklet); dev_err(lp->dev, "request_irq() failed\n"); return ret; } @@ -1613,10 +1617,6 @@ static int __devinit axienet_of_probe(struct platform_device *op) goto err_iounmap_2; } - tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, - (unsigned long) lp); - tasklet_disable(&lp->dma_err_tasklet); - return 0; err_iounmap_2: -- cgit v1.1 From 769ce4c95e8f77c1d5df82194e54df49d28830c5 Mon Sep 17 00:00:00 2001 From: Kamlakant Patel Date: Wed, 14 Nov 2012 01:41:38 +0000 Subject: net/smsc911x: Fix ready check in cases where WORD_SWAP is needed The chip ready check added by the commit 3ac3546e [Always wait for the chip to be ready] does not work when the register read/write is word swapped. This check has been added before the WORD_SWAP register is programmed, so we need to check for swapped register value as well. Bit 16 is marked as RESERVED in SMSC datasheet, Steve Glendinning checked with SMSC and wrote: The chip architects have concluded we should be reading PMT_CTRL until we see any of bits 0, 8, 16 or 24 set. Then we should read BYTE_TEST to check the byte order is correct (as we already do). The rationale behind this is that some of the chip variants have word order swapping features too, so the READY bit could actually be in any of the 4 possible locations. The architects have confirmed that if any of these 4 positions is set the chip is ready. The other 3 locations will either never be set or can only go high after READY does (so also indicate the device is ready). This change will check for the READY bit at the 16th position. We do not check the other two cases (bit 8 and 24) since the driver does not support byte-swapped register read/write. Signed-off-by: Kamlakant Patel Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 62d1baf..c53c0f4 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev) static int __devinit smsc911x_init(struct net_device *dev) { struct smsc911x_data *pdata = netdev_priv(dev); - unsigned int byte_test; + unsigned int byte_test, mask; unsigned int to = 100; SMSC_TRACE(pdata, probe, "Driver Parameters:"); @@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev) /* * poll the READY bit in PMT_CTRL. Any other access to the device is * forbidden while this bit isn't set. Try for 100ms + * + * Note that this test is done before the WORD_SWAP register is + * programmed. So in some configurations the READY bit is at 16 before + * WORD_SWAP is written to. This issue is worked around by waiting + * until either bit 0 or bit 16 gets set in PMT_CTRL. + * + * SMSC has confirmed that checking bit 16 (marked as reserved in + * the datasheet) is fine since these bits "will either never be set + * or can only go high after READY does (so also indicate the device + * is ready)". */ - while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) + + mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_); + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to) udelay(1000); + if (to == 0) { pr_err("Device not READY in 100ms aborting\n"); return -ENODEV; -- cgit v1.1 From 80d11788fb8f4d9fcfae5ad508c7f1b65e8b28a3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Nov 2012 22:32:15 -0500 Subject: Revert "drivers/net/phy/mdio-bitbang.c: Call mdiobus_unregister before mdiobus_free" This reverts commit aa731872f7d33dcb8b54dad0cfb82d4e4d195d7e. As pointed out by Ben Hutchings, this change is not correct. mdiobus_unregister() can't be called if the bus isn't registered yet, however this change can result in situations which cause that to happen. Part of the confusion here revolves around the fact that the callers of this module control registration/unregistration, rather than the module itself. Signed-off-by: David S. Miller --- drivers/net/phy/mdio-bitbang.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c index 6428fcb..daec9b0 100644 --- a/drivers/net/phy/mdio-bitbang.c +++ b/drivers/net/phy/mdio-bitbang.c @@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus) struct mdiobb_ctrl *ctrl = bus->priv; module_put(ctrl->ops->owner); - mdiobus_unregister(bus); mdiobus_free(bus); } EXPORT_SYMBOL(free_mdio_bitbang); -- cgit v1.1 From cbc351abe3c9bcec11c712dd41bb212748fd46d3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 15 Nov 2012 11:58:24 +0100 Subject: pinctrl/samsung: don't allow enabling pinctrl-samsung standalone The main samsung pinctrl module references the specific exynos4210 pinctrl driver, which selects the main driver in Kconfig. Making the main driver a silent "bool" option avoid this potential build error if CONFIG_PINCTRL_SAMSUNG=y && CONFIG_PINCTRL_EXYNOS4=n: drivers/built-in.o:(.rodata+0x4e4): undefined reference to `exynos4210_pin_ctrl' Signed-off-by: Arnd Bergmann Cc: Tomasz Figa Cc: Kyungmin Park Cc: Linus Walleij Acked-by: Kukjin Kim Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d96caefd..aeecf0f 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -178,7 +178,7 @@ config PINCTRL_COH901 ports of 8 GPIO pins each. config PINCTRL_SAMSUNG - bool "Samsung pinctrl driver" + bool depends on OF && GPIOLIB select PINMUX select PINCONF -- cgit v1.1 From af451af4e0a3a4cd7536843f585c96a9b095a4e8 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 9 Oct 2012 23:26:06 -0700 Subject: mtd: nand: fix Samsung SLC NAND identification regression A combination of the following two commits caused a regression in 3.7-rc1 when identifying some Samsung NAND, so that some previously working NAND were no longer detected properly: commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a mtd: nand: add generic READ ID length calculation functions commit e2d3a35ee427aaba99b6c68a56609ce276c51270 mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID Particularly, a regression was seen on Samsung K9F2G08U0B, with the following full 8-byte READ ID string: ec da 10 95 44 00 ec da The basic problem is that Samsung manufactures both SLC and MLC NAND that use a non-standard decoding table for deriving information from their IDs. I have heuristically determined that all the chips that use the new table have ID strings which wrap around after the 6th byte. Unfortunately, I overlooked the fact that some older Samsung SLC (which use a different decoding table) have "5 byte ID strings" which also wrap around after the 6th byte. This patch re-introduces a distinction between these old and new Samsung NAND by checking that the 6th byte is non-zero, allowing both old and new Samsung NAND to be detected properly. Signed-off-by: Brian Norris Tested-by: Brian Norris Reported-by: Marek Vasut Tested-by: Marek Vasut Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ec6841d..d5ece6e 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2983,13 +2983,14 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) - * New style (6 byte ID): Samsung K9GAG08U0F (p.44) + * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * - * Check for ID length, cell type, and Hynix/Samsung ID to decide what - * to do. + * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung + * ID to decide what to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { + if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && + id_data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; -- cgit v1.1 From 6924d99fcdf1a688538a3cdebd1f135c22eec191 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 14 Nov 2012 21:46:30 -0800 Subject: mtd: nand: fix Samsung SLC detection regression This patch fixes errors seen in identifying old Samsung SLC, due to the following commits: commit e2d3a35ee427aaba99b6c68a56609ce276c51270 mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a mtd: nand: add generic READ ID length calculation functions Some Samsung NAND with "5-byte" ID really appear to have 6-byte IDs, with wraparound like: Samsung K9K8G08U0D ec d3 51 95 58 ec ec d3 Samsung K9F1G08U0C ec f1 00 95 40 ec ec f1 Samsung K9F2G08U0B ec da 10 95 44 00 ec da This bad wraparound makes it hard to reliably detect the difference between Samsung SLC with 5-byte ID and Samsung SLC with 6-byte ID. The fix is to, for now, only use the new Samsung table for MLC. We cannot support the new SLC (K9FAG08U0M) until Samsung gives better ID decode information. Note that this applies in addition to the previous regression fix: commit bc86cf7af2ebda88056538e8edff852ee627f76a mtd: nand: fix Samsung SLC NAND identification regression Together, these patches completely restore the previous detection behavior so that we cannot see any more regressions in Samsung SLC NAND (finger crossed). With luck, I can get a hold of a Samsung representative and stop having to cross my fingers eventually. Reported-by: Sylwester Nawrocki Tested-by: Sylwester Nawrocki Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d5ece6e..1a03b7f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2990,6 +2990,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * ID to decide what to do. */ if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && + (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && id_data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); -- cgit v1.1 From 949a05d03490e39e773e8652ccab9157e6f595b4 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 2 Nov 2012 12:30:53 +0000 Subject: [PARISC] fix virtual aliasing issue in get_shared_area() On Thu, 2012-11-01 at 16:45 -0700, Michel Lespinasse wrote: > Looking at the arch/parisc/kernel/sys_parisc.c implementation of > get_shared_area(), I do have a concern though. The function basically > ignores the pgoff argument, so that if one creates a shared mapping of > pages 0-N of a file, and then a separate shared mapping of pages 1-N > of that same file, both will have the same cache offset for their > starting address. > > This looks like this would create obvious aliasing issues. Am I > misreading this ? I can't understand how this could work good enough > to be undetected, so there must be something I'm missing here ??? This turns out to be correct and we need to pay attention to the pgoff as well as the address when creating the virtual address for the area. Fortunately, the bug is rarely triggered as most applications which use pgoff tend to use large values (git being the primary one, and it uses pgoff in multiples of 16MB) which are larger than our cache coherency modulus, so the problem isn't often seen in practise. Reported-by: Michel Lespinasse Cc: Signed-off-by: James Bottomley --- arch/parisc/kernel/sys_parisc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7426e40..f76c108 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping, struct vm_area_struct *vma; int offset = mapping ? get_offset(mapping) : 0; + offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; + addr = DCACHE_ALIGN(addr - offset) + offset; for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { -- cgit v1.1 From b9196395c905edec512dfd6690428084228c16ec Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Nov 2012 09:10:39 -0500 Subject: drm/radeon: fix logic error in atombios_encoders.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=50431 Reported-by: David Binderman Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Michel Dänzer --- drivers/gpu/drm/radeon/atombios_encoders.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index ba498f8..010bae1 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1625,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); /* some early dce3.2 boards have a bug in their transmitter control table */ - if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) + if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); } if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { -- cgit v1.1 From ae289dc1f474ff380e9d7601f02e4d766cbba408 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 15 Nov 2012 09:22:40 +0100 Subject: s390/3215: fix tty close handling The 3215 console always has the RAW3215_FIXED flag set, which causes raw3215_shutdown() not to wait for outstanding I/O requests if an attached tty gets closed. The flag however can be simply removed, so we can guarantee that all requests belonging to the tty have been processed when the tty is closed. However the tasklet that belongs to the 3215 device may be scheduled even if there is no tty attached anymore, since we have a race between console and tty processing. Thefore unconditional tty_wakekup() in raw3215_wakeup() can cause the following NULL pointer dereference: 3.465368 Unable to handle kernel pointer dereference at virtual kernel address (null) 3.465448 Oops: 0004 #1 SMP 3.465454 Modules linked in: 3.465459 CPU: 1 Not tainted 3.6.0 #1 3.465462 Process swapper/1 (pid: 0, task: 000000003ffa4428, ksp: 000000003ffb7ce0) 3.465466 Krnl PSW : 0404100180000000 0000000000162f86 (__wake_up+0x46/0xb8) 3.465480 R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:1 PM:0 EA:3 Krnl GPRS: fffffffffffffffe 0000000000000000 0000000000000160 0000000000000001 3.465492 0000000000000001 0000000000000004 0000000000000004 000000000096b490 3.465499 0000000000000001 0000000000000100 0000000000000001 0000000000000001 3.465506 070000003fc87d60 0000000000000160 000000003fc87d68 000000003fc87d00 3.465526 Krnl Code: 0000000000162f76: e3c0f0a80004 lg %r12,168(%r15) 0000000000162f7c: 58000370 l %r0,880 #0000000000162f80: c007ffffffff00 xilf %r0,4294967295 >0000000000162f86: ba102000 cs %r1,%r0,0(%r2) 0000000000162f8a: 1211 ltr %r1,%r1 0000000000162f8c: a774002f brc 7,162fea 0000000000162f90: b904002d lgr %r2,%r13 0000000000162f94: b904003a lgr %r3,%r10 3.465597 Call Trace: 3.465599 (<0400000000000000> 0x400000000000000) 3.465602 <000000000048c77e> raw3215_wakeup+0x2e/0x40 3.465607 <0000000000134d66> tasklet_action+0x96/0x168 3.465612 <000000000013423c> __do_softirq+0xd8/0x21c 3.465615 <0000000000134678> irq_exit+0xa8/0xac 3.465617 <000000000046c232> do_IRQ+0x182/0x248 3.465621 <00000000005c8296> io_return+0x0/0x8 3.465625 <00000000005c7cac> vtime_stop_cpu+0x4c/0xb8 3.465629 (<0000000000194e06> tick_nohz_idle_enter+0x4e/0x74) 3.465633 <0000000000104760> cpu_idle+0x170/0x184 3.465636 <00000000005b5182> smp_start_secondary+0xd6/0xe0 3.465641 <00000000005c86be> restart_int_handler+0x56/0x6c 3.465643 <0000000000000000> 0x0 3.465645 Last Breaking-Event-Address: 3.465647 <0000000000403136> tty_wakeup+0x46/0x98 3.465652 3.465654 Kernel panic - not syncing: Fatal exception in interrupt 01: HCPGIR450W CP entered; disabled wait PSW 00020001 80000000 00000000 0010F63C The easiest solution is simply to check if tty is NULL in the tasklet. If it is NULL nothing is to do (no tty attached), otherwise tty_wakeup() can be called, since we hold a reference to the tty. This is not nice... but it is a small patch and it works. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3215.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9ffb6d5..4ed343e 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -44,7 +44,6 @@ #define RAW3215_NR_CCWS 3 #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ -#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ #define RAW3215_WORKING 4 /* set if a request is being worked on */ #define RAW3215_THROTTLED 8 /* set if reading is disabled */ #define RAW3215_STOPPED 16 /* set if writing is disabled */ @@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data) struct tty_struct *tty; tty = tty_port_tty_get(&raw->port); - tty_wakeup(tty); - tty_kref_put(tty); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } } /* @@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) DECLARE_WAITQUEUE(wait, current); unsigned long flags; - if (!(raw->port.flags & ASYNC_INITIALIZED) || - (raw->flags & RAW3215_FIXED)) + if (!(raw->port.flags & ASYNC_INITIALIZED)) return; /* Wait for outstanding requests, then free irq */ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); @@ -926,8 +926,6 @@ static int __init con3215_init(void) dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; - raw->flags |= RAW3215_FIXED; - /* Request the console irq */ if (raw3215_startup(raw) != 0) { raw3215_free_info(raw); -- cgit v1.1 From 0da9a0c2638c8476b4a5021841912f249e3187dc Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Thu, 15 Nov 2012 03:49:05 +0000 Subject: sctp: fix /proc/net/sctp/ memory leak Commit 13d782f ("sctp: Make the proc files per network namespace.") changed the /proc/net/sctp/ struct file_operations opener functions to use single_open_net() and seq_open_net(). Avoid leaking memory by using single_release_net() and seq_release_net() as the release functions. Discovered with Trinity (the syscall fuzzer). Signed-off-by: Tommi Rantala Acked-by: Neil Horman Cc: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/sctp/proc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/sctp/proc.c b/net/sctp/proc.c index c3bea26..9966e7b 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { .open = sctp_snmp_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = single_release_net, }; /* Set up the proc fs entry for 'snmp' object. */ @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { .open = sctp_eps_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; /* Set up the proc fs entry for 'eps' object. */ @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { .open = sctp_assocs_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; /* Set up the proc fs entry for 'assocs' object. */ @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { .open = sctp_remaddr_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; int __net_init sctp_remaddr_proc_init(struct net *net) -- cgit v1.1 From 93532c8a4890871aa0d84dd91b80dad9f58542e0 Mon Sep 17 00:00:00 2001 From: Igor Mazanov Date: Thu, 15 Nov 2012 21:07:00 +0400 Subject: clk: remove inline usage from clk-provider.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users of GCC 4.7 have reported compiler errors due to having inline applied to function declarations in clk-provider.h. The definitions exist in drivers/clk/clk.c. An example error: In file included from arch/arm/mach-omap2/clockdomain.c:25:0: arch/arm/mach-omap2/clockdomain.c: In function ‘clkdm_clk_disable’: include/linux/clk-provider.h:338:12: error: inlining failed in call to always_inline ‘__clk_get_enable_count’: function body not available arch/arm/mach-omap2/clockdomain.c:1001:28: error: called from here make[1]: *** [arch/arm/mach-omap2/clockdomain.o] Error 1 make: *** [arch/arm/mach-omap2] Error 2 This patch removes the use of inline from include/linux/clk-provider.h but keeps the function definitions in drivers/clk/clk.c as inlined since they are one-liners. Signed-off-by: Igor Mazanov Acked-by: Paul Walmsley Signed-off-by: Mike Turquette [mturquette@linaro.org: improved subject, added changelog] --- include/linux/clk-provider.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c127315..f9f5e9e 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -inline int __clk_get_enable_count(struct clk *clk); -inline int __clk_get_prepare_count(struct clk *clk); +int __clk_get_enable_count(struct clk *clk); +int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); int __clk_is_enabled(struct clk *clk); -- cgit v1.1 From ec34232575083fd0f43d3a101e8ebb041b203761 Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Thu, 15 Nov 2012 04:03:17 +0000 Subject: tcp: fix retransmission in repair mode Currently if a socket was repaired with a few packet in a write queue, a kernel bug may be triggered: kernel BUG at net/ipv4/tcp_output.c:2330! RIP: 0010:[] tcp_retransmit_skb+0x5ff/0x610 According to the initial realization v3.4-rc2-963-gc0e88ff, all skb-s should look like already posted. This patch fixes code according with this sentence. Here are three points, which were not done in the initial patch: 1. A tcp send head should not be changed 2. Initialize TSO state of a skb 3. Reset the retransmission time This patch moves logic from tcp_sendmsg to tcp_write_xmit. A packet passes the ussual way, but isn't sent to network. This patch solves all described problems and handles tcp_sendpages. Cc: Pavel Emelyanov Cc: "David S. Miller" Cc: Alexey Kuznetsov Cc: James Morris Cc: Hideaki YOSHIFUJI Cc: Patrick McHardy Signed-off-by: Andrey Vagin Acked-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_output.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 197c000..083092e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1212,7 +1212,7 @@ new_segment: wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: - if (copied && likely(!tp->repair)) + if (copied) tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) @@ -1223,7 +1223,7 @@ wait_for_memory: } out: - if (copied && likely(!tp->repair)) + if (copied) tcp_push(sk, flags, mss_now, tp->nonagle); release_sock(sk); return copied + copied_syn; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe..2798706 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, tso_segs = tcp_init_tso_segs(sk, skb, mss_now); BUG_ON(!tso_segs); + if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) + goto repair; /* Skip network transmission */ + cwnd_quota = tcp_cwnd_test(tp, skb); if (!cwnd_quota) break; @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) break; +repair: /* Advance the send_head. This one is sent out. * This call will increment packets_out. */ -- cgit v1.1 From a652208e0b52c190e57f2a075ffb5e897fe31c3b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 14 Nov 2012 02:51:04 +0000 Subject: net: correct check in dev_addr_del() Check (ha->addr == dev->dev_addr) is always true because dev_addr_init() sets this. Correct the check to behave properly on addr removal. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/core/dev_addr_lists.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 87cc17d..b079c7b 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, */ ha = list_first_entry(&dev->dev_addrs.list, struct netdev_hw_addr, list); - if (ha->addr == dev->dev_addr && ha->refcount == 1) + if (!memcmp(ha->addr, addr, dev->addr_len) && + ha->type == addr_type && ha->refcount == 1) return -ENOENT; err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, -- cgit v1.1 From 888155bbf63a5f955d7a45932ff05e848f715bf0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 12 Nov 2012 11:07:24 +0000 Subject: vmwgfx: return an -EFAULT if copy_to_user() fails copy_to_user() returns the number of bytes remaining to be copied, but we want to return a negative error code here. I fixed a couple of these last year, but I missed this one. Signed-off-by: Dan Carpenter Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index b07ca2e..7290811 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); ret = copy_to_user(buffer, bounce, size); + if (ret) + ret = -EFAULT; vfree(bounce); if (unlikely(ret != 0)) -- cgit v1.1 From ac207ed2471150e06af0afc76e4becc701fa2733 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 13 Nov 2012 18:31:55 +0000 Subject: ttm: Clear the ttm page allocated from high memory zone correctly The TTM page can be allocated from high memory. In such case it is wrong to use the page_address(page) as the virtual address for the high memory page. bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=50241 Signed-off-by: Zhao Yakui Cc: stable@vger.kernel.org Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 860dc48..bd2a3b4 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, /* clear the pages coming from the pool if requested */ if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { list_for_each_entry(p, &plist, lru) { - clear_page(page_address(p)); + if (PageHighMem(p)) + clear_highpage(p); + else + clear_page(page_address(p)); } } -- cgit v1.1 From 55aa914e9274cf1d55397cc04eb926eb055c79f7 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 9 Nov 2012 12:10:43 +0000 Subject: drm/ttm: remove unneeded preempt_disable/enable It is unnecessary to disable preemption explicitly while calling copy_highpage(). Because copy_highpage() will do it again through kmap_atomic/kunmap_atomic. Signed-off-by: Akinobu Mita Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_tt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index bf82601..7d759a4 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) if (unlikely(to_page == NULL)) goto out_err; - preempt_disable(); copy_highpage(to_page, from_page); - preempt_enable(); page_cache_release(from_page); } @@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) ret = PTR_ERR(to_page); goto out_err; } - preempt_disable(); copy_highpage(to_page, from_page); - preempt_enable(); set_page_dirty(to_page); mark_page_accessed(to_page); page_cache_release(to_page); -- cgit v1.1 From c3c9b370ea4fa2566dfb0c3d88d9f02be0533e7a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 16 Nov 2012 09:26:41 +0900 Subject: ASoC: bells: Fix up git patch application failure It seems git has been getting confused by the very similar contexts for the speaker DAIs and has been applying patches to the wrong places causing all sorts of confusion. Fix this up by hand. Reported-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/samsung/bells.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index b56b9a3..a2ca156 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -212,7 +212,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5110-aif3", + .cpu_dai_name = "wm5102-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF @@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5102-aif3", + .cpu_dai_name = "wm5110-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -- cgit v1.1 From 96e1f18fbb8c146aee9cdad1ebc510b8ccf94b6f Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 15 Nov 2012 11:41:30 +0000 Subject: ASoC: arizona: Fix typo - Swap value in 48k_rates[] and 44k1_rates[] Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/arizona.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c03b65a..054967d 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev); static unsigned int arizona_sysclk_48k_rates[] = { 6144000, 12288000, - 22579200, + 24576000, 49152000, 73728000, 98304000, @@ -278,7 +278,7 @@ static unsigned int arizona_sysclk_48k_rates[] = { static unsigned int arizona_sysclk_44k1_rates[] = { 5644800, 11289600, - 24576000, + 22579200, 45158400, 67737600, 90316800, -- cgit v1.1 From 60817a680b1bd3341b6909fab7d8a1fcc3a78369 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 9 Oct 2012 15:37:48 +0800 Subject: libata-acpi: Fix NULL ptr derference in ata_acpi_dev_handle commit 6b66d95895c149cbc04d4fac5a2f5477c543a8ae didn't handle SATA PMP case in ata_acpi_bind_device and will cause a NULL ptr dereference when user attached a SATA drive to the PMP port. Fix this by checking PMP support. This bug is reported by Dan van der Ster in the following bugzilla page: https://bugzilla.kernel.org/show_bug.cgi?id=48211 Reported-by: Dan van der Ster Tested-by: Dan van der Ster Signed-off-by: Aaron Lu Cc: Signed-off-by: Jeff Garzik Tested-by: Simon --- drivers/ata/libata-acpi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index fd9ecf7..5b0ba3f 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, struct acpi_device *acpi_dev; struct acpi_device_power_state *states; - if (ap->flags & ATA_FLAG_ACPI_SATA) - ata_dev = &ap->link.device[sdev->channel]; - else + if (ap->flags & ATA_FLAG_ACPI_SATA) { + if (!sata_pmp_attached(ap)) + ata_dev = &ap->link.device[sdev->id]; + else + ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id]; + } + else { ata_dev = &ap->link.device[sdev->id]; + } *handle = ata_dev_acpi_handle(ata_dev); -- cgit v1.1 From 9addf6afeef0f2c9a1fef880e2dbe633d15a89bd Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Thu, 8 Nov 2012 20:39:54 +0530 Subject: pata_arasan: Initialize cf clock to 166MHz PATA arasan driver expects the clock to be set to 166 MHz for proper functioning. This patch sets clk to 166 MHz in probe. Signed-off-by: Vipul Kumar Samar Signed-off-by: Viresh Kumar Signed-off-by: Jeff Garzik --- drivers/ata/pata_arasan_cf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 26201eb..71111f2 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev) return ret; } + ret = clk_set_rate(acdev->clk, 166000000); + if (ret) { + dev_warn(acdev->host->dev, "clock set rate failed"); + return ret; + } + spin_lock_irqsave(&acdev->host->lock, flags); /* configure CF interface clock */ writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : -- cgit v1.1 From c37472d3f4ec6bf98b443490e069f31d18bcd6f5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 6 Nov 2012 22:55:32 +0100 Subject: sata_highbank: mark ahci_highbank_probe as __devinit The ahci_highbank_probe function is incorrectly marked as __init, which means it can get discarded at boot time, which might be a problem if for some reason the device only becomes operational after loading another module. Using __devinit instead avoids seeing this warning for every build: WARNING: vmlinux.o(.data+0xf7b0): Section mismatch in reference from the variable ahci_highbank_driver to the function .init.text:ahci_highbank_probe() The variable ahci_highbank_driver references the function __init ahci_highbank_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console Signed-off-by: Arnd Bergmann Cc: Mark Langsdorf Cc: Rob Herring Signed-off-by: Jeff Garzik --- drivers/ata/sata_highbank.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 0d7c4c2..36a141a 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = { }; MODULE_DEVICE_TABLE(of, ahci_of_match); -static int __init ahci_highbank_probe(struct platform_device *pdev) +static int __devinit ahci_highbank_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; -- cgit v1.1 From cd705d5ad49bb8894dda2726dcaef8f63ddeba43 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 21 Oct 2012 18:57:56 +0200 Subject: libata debugging: Warn when unable to find timing descriptor based on xfer_mode ata_timing_find_mode could return NULL which is not checked by all low-level ATA drivers using it and cause a NULL ptr deref. Warn at least so that possible issues can get fixed easily. Signed-off-by: Borislav Petkov Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3cc7096..f46fbd3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) if (xfer_mode == t->mode) return t; + + WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", + __func__, xfer_mode); + return NULL; } -- cgit v1.1 From b03e66a6be91f8389fcd902ab6c1563db1c9c06b Mon Sep 17 00:00:00 2001 From: David Milburn Date: Mon, 29 Oct 2012 18:00:22 -0500 Subject: sata_svw: check DMA start bit before reset If kdump is triggered with pending IO, controller may not respond causing kdump to fail. http://marc.info/?l=linux-ide&m=133032255424658&w=2 During error recovery ata_do_dev_read_id never completes due hang in mmio_insw. ata_do_dev_read_id ata_sff_data_xfer ioread16_rep mmio_insw if DMA start bit is cleared before reset, PIO command is successful and kdump succeeds. Signed-off-by: David Milburn Signed-off-by: Jeff Garzik --- drivers/ata/sata_svw.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 44a4256..08608de 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link, return 0; } +static int k2_sata_softreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + u8 dmactl; + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; + + dmactl = readb(mmio + ATA_DMA_CMD); + + /* Clear the start bit */ + if (dmactl & ATA_DMA_START) { + dmactl &= ~ATA_DMA_START; + writeb(dmactl, mmio + ATA_DMA_CMD); + } + + return ata_sff_softreset(link, class, deadline); +} + +static int k2_sata_hardreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + u8 dmactl; + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; + + dmactl = readb(mmio + ATA_DMA_CMD); + + /* Clear the start bit */ + if (dmactl & ATA_DMA_START) { + dmactl &= ~ATA_DMA_START; + writeb(dmactl, mmio + ATA_DMA_CMD); + } + + return sata_sff_hardreset(link, class, deadline); +} static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { @@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = { static struct ata_port_operations k2_sata_ops = { .inherits = &ata_bmdma_port_ops, + .softreset = k2_sata_softreset, + .hardreset = k2_sata_hardreset, .sff_tf_load = k2_sata_tf_load, .sff_tf_read = k2_sata_tf_read, .sff_check_status = k2_stat_check_status, -- cgit v1.1 From 29448ec129c5c9c7ece2ef28c72a0dafd70c8af2 Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Tue, 16 Oct 2012 22:59:01 +0800 Subject: [libata] PM callbacks should be conditionally compiled on CONFIG_PM_SLEEP This will fix warnings like following when CONFIG_PM_SLEEP is not set: warning: 'xxx_suspend' defined but not used [-Wunused-function] warning: 'xxx_resume' defined but not used [-Wunused-function] Because SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) Only references the callbacks on CONFIG_PM_SLEEP (instead of CONFIG_PM). Cc: Viresh Kumar Cc: linux-ide@vger.kernel.org Signed-off-by: Yuanhan Liu Signed-off-by: Fengguang Wu Signed-off-by: Jeff Garzik --- drivers/ata/ahci_platform.c | 2 +- drivers/ata/pata_arasan_cf.c | 2 +- drivers/ata/sata_highbank.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index b1ae480..b7078af 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ahci_suspend(struct device *dev) { struct ahci_platform_data *pdata = dev_get_platdata(dev); diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 71111f2..371fd2c 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -914,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int arasan_cf_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 36a141a..400bf1c 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ahci_highbank_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); -- cgit v1.1 From 6fc4adca6ce3e1d57a42707019dddcb883578a91 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 15 Nov 2012 18:13:19 +0000 Subject: tilegx: request_irq with a non-null device name This patch simply makes the tilegx net driver call request_irq with a non-null name. It makes the output in /proc/interrupts more obvious, but also helps tools that don't expect to find null there. Signed-off-by: Simon Marchi Acked-by: Chris Metcalf Signed-off-by: David S. Miller --- drivers/net/ethernet/tile/tilegx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 4e98100..66e025a 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) ingress_irq = rc; tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, - 0, NULL, NULL); + 0, "tile_net", NULL); if (rc != 0) { netdev_err(dev, "request_irq failed: %d\n", rc); destroy_irq(ingress_irq); -- cgit v1.1 From e9c00136a4754829faf885cf966c9754c7734660 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 7 Nov 2012 15:05:33 +0100 Subject: batman-adv: fix tt_global_entries flags update Flags carried by a change_entry have to be always copied into the client entry as they may contain important attributes (e.g. TT_CLIENT_WIFI). For instance, a client added by means of the "early detection mechanism" has no flag set at the beginning, so they must be updated once the proper ADD event is received. This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 112edd3..64c0012 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -769,6 +769,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, */ tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; + /* the change can carry possible "attribute" flags like the + * TT_CLIENT_WIFI, therefore they have to be copied in the + * client entry + */ + tt_global_entry->common.flags |= flags; + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a * delete + roaming change for this originator. -- cgit v1.1 From 27b37ebfa2d2a1b6acef6f2d21c497475c9b9709 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 14:21:11 +0100 Subject: batman-adv: correctly pass the client flag on tt_response When a TT response with the full table is sent, the client flags should be sent as well. This patch fix the flags assignment when populating the tt_response to send back This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 64c0012..fec1a00 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1502,7 +1502,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, memcpy(tt_change->addr, tt_common_entry->addr, ETH_ALEN); - tt_change->flags = BATADV_NO_FLAGS; + tt_change->flags = tt_common_entry->flags; tt_count++; tt_change++; -- cgit v1.1 From 1f36aebcc5fa53c5d98f3329186466b5eb76a168 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 21:55:29 +0100 Subject: batman-adv: don't add TEMP clients belonging to other backbone nodes The "early client detection" mechanism must not add clients belonging to other backbone nodes. Such clients must be reached by directly using the LAN instead of the mesh. This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Reported-by: Glen Page Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index fec1a00..baae715 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -2456,6 +2456,13 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, { bool ret = false; + /* if the originator is a backbone node (meaning it belongs to the same + * LAN of this node) the temporary client must not be added because to + * reach such destination the node must use the LAN instead of the mesh + */ + if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) + goto out; + if (!batadv_tt_global_add(bat_priv, orig_node, addr, BATADV_TT_CLIENT_TEMP, atomic_read(&orig_node->last_ttvn))) -- cgit v1.1 From 74490f969155caf1ec945ad2d35d3a8eec6be71d Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 21:55:30 +0100 Subject: batman-adv: process broadcast packets in BLA earlier The logic in the BLA mechanism may decide to drop broadcast packets because the node may still be in the setup phase. For this reason, further broadcast processing like the early client detection mechanism must be done only after the BLA check. This patches moves the invocation to BLA before any other broadcast processing. This was introduced 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Reported-by: Glen Page Signed-off-by: Simon Wunderlich Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/soft-interface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2..ce0684a 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -325,6 +325,12 @@ void batadv_interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; + /* Let the bridge loop avoidance check the packet. If will + * not handle it, we can safely push it up. + */ + if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) + goto out; + if (orig_node) batadv_tt_add_temporary_global_entry(bat_priv, orig_node, ethhdr->h_source); @@ -332,12 +338,6 @@ void batadv_interface_rx(struct net_device *soft_iface, if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; - /* Let the bridge loop avoidance check the packet. If will - * not handle it, we can safely push it up. - */ - if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) - goto out; - netif_rx(skb); goto out; -- cgit v1.1 From 097965ee447e5ccec9776f9b075e64cf7607e5eb Mon Sep 17 00:00:00 2001 From: Nicolas Royer Date: Tue, 6 Nov 2012 17:31:03 +0100 Subject: ARM: at91/AT91SAM9G45: fix crypto peripherals irq issue due to sparse irq support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spare irq support introduced by commit 8fe82a5 (ARM: at91: sparse irq support) involves to add the NR_IRQS_LEGACY offset to irq number. Signed-off-by: Nicolas Royer Acked-by: Nicolas Ferre Acked-by: Eric Bénard Tested-by: Eric Bénard Cc: stable@vger.kernel.org # 3.6 --- arch/arm/mach-at91/at91sam9g45_devices.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index b159607..fcd233c 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; -- cgit v1.1 From 641f3ce64b050961d454a0716bb6dbf528315aac Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 14 Nov 2012 12:18:17 +0100 Subject: ARM: at91/usbh: fix overcurrent gpio setup Use gpio_is_valid also for overcurrent pins (which are currently negative in many board files). Signed-off-by: Johan Hovold Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_devices.c | 2 +- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- arch/arm/mach-at91/at91sam9261_devices.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 1e122bc..3cee0e6 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index aa1e587..414bd85 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index b948769..cd604aa 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index cb85da2..9c61e59 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } -- cgit v1.1 From ecf026dc340f9700ed3c485344913a8a2b10e2e3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 25 Oct 2012 23:02:18 +0800 Subject: ARM i.MX: fix error-valued pointer dereference in clk_register_gate2() The error-valued pointer clk is used for the arg of kfree, it should be kfree(gate) if clk_register() return ERR_PTR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-gate2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 3c1b8ff..cc49c7a 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, clk = clk_register(dev, &gate->hw); if (IS_ERR(clk)) - kfree(clk); + kfree(gate); return clk; } -- cgit v1.1 From 3d5e2abe6e265acc5e1fda810301243e9bac92b2 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Fri, 16 Nov 2012 15:39:24 +0100 Subject: ARM: imx: ehci: fix host power mask bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch sets HPM (Host power mask bit) to bit 16 according to i.MX Reference Manual. Falsely it was set to bit 8, but this controls pull-up Impedance. Reported-by: Michael Burkey Cc: Stable Signed-off-by: Christoph Fritz Acked-by: Eric Bénard Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/ehci-imx25.c | 2 +- arch/arm/mach-imx/ehci-imx35.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c index 412c583..576af74 100644 --- a/arch/arm/mach-imx/ehci-imx25.c +++ b/arch/arm/mach-imx/ehci-imx25.c @@ -30,7 +30,7 @@ #define MX25_H1_SIC_SHIFT 21 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) #define MX25_H1_PP_BIT (1 << 18) -#define MX25_H1_PM_BIT (1 << 8) +#define MX25_H1_PM_BIT (1 << 16) #define MX25_H1_IPPUE_UP_BIT (1 << 7) #define MX25_H1_IPPUE_DOWN_BIT (1 << 6) #define MX25_H1_TLL_BIT (1 << 5) diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c index 779e16e..2933978 100644 --- a/arch/arm/mach-imx/ehci-imx35.c +++ b/arch/arm/mach-imx/ehci-imx35.c @@ -30,7 +30,7 @@ #define MX35_H1_SIC_SHIFT 21 #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) #define MX35_H1_PP_BIT (1 << 18) -#define MX35_H1_PM_BIT (1 << 8) +#define MX35_H1_PM_BIT (1 << 16) #define MX35_H1_IPPUE_UP_BIT (1 << 7) #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) #define MX35_H1_TLL_BIT (1 << 5) -- cgit v1.1 From 8e620b0476696e9428442d3551f3dad47df0e28f Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 15 Nov 2012 17:21:16 +0000 Subject: arm64: Distinguish between user and kernel XN bits On AArch64, the meaning of the XN bit has changed to UXN (user). The PXN (privileged) bit must be set to prevent kernel execution. Without the PXN bit set, the CPU may speculatively access device memory. This patch ensures that all the mappings that the kernel must not execute from (including user mappings) have the PXN bit set. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/io.h | 2 +- arch/arm64/include/asm/pgtable-hwdef.h | 6 +++-- arch/arm64/include/asm/pgtable.h | 40 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 54f6116..d2f05a6 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -222,7 +222,7 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot extern void __iounmap(volatile void __iomem *addr); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) #define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 0f3b458..75fd13d 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -38,7 +38,8 @@ #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) -#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53) +#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54) /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). @@ -57,7 +58,8 @@ #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ -#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ +#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ +#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 8960239..14aba2d 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -62,23 +62,23 @@ extern pgprot_t pgprot_default; #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) -#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) -#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) -#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) -#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) -#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) -#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) - -#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) -#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) -#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) -#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) +#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) +#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) +#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) + +#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) +#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) #endif /* __ASSEMBLY__ */ @@ -130,10 +130,10 @@ extern struct page *empty_zero_page; #define pte_young(pte) (pte_val(pte) & PTE_AF) #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) -#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) +#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_present_exec_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ (PTE_VALID | PTE_USER)) #define PTE_BIT_FUNC(fn,op) \ @@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; + const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); return pte; } -- cgit v1.1 From fa0cbbf145aabbf29c6f28f8a11935c0b0fd86fc Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 12 Nov 2012 17:53:04 -0800 Subject: mm, oom: reintroduce /proc/pid/oom_adj This is mostly a revert of 01dc52ebdf47 ("oom: remove deprecated oom_adj") from Davidlohr Bueso. It reintroduces /proc/pid/oom_adj for backwards compatibility with earlier kernels. It simply scales the value linearly when /proc/pid/oom_score_adj is written. The major difference is that its scheduled removal is no longer included in Documentation/feature-removal-schedule.txt. We do warn users with a single printk, though, to suggest the more powerful and supported /proc/pid/oom_score_adj interface. Reported-by: Artem S. Tashkinov Signed-off-by: David Rientjes Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 16 ++++-- fs/proc/base.c | 109 +++++++++++++++++++++++++++++++++++++ include/uapi/linux/oom.h | 9 +++ 3 files changed, 130 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index a1793d6..3844d21 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -33,7 +33,7 @@ Table of Contents 2 Modifying System Parameters 3 Per-Process Parameters - 3.1 /proc//oom_score_adj - Adjust the oom-killer + 3.1 /proc//oom_adj & /proc//oom_score_adj - Adjust the oom-killer score 3.2 /proc//oom_score - Display current oom-killer score 3.3 /proc//io - Display the IO accounting fields @@ -1320,10 +1320,10 @@ of the kernel. CHAPTER 3: PER-PROCESS PARAMETERS ------------------------------------------------------------------------------ -3.1 /proc//oom_score_adj- Adjust the oom-killer score +3.1 /proc//oom_adj & /proc//oom_score_adj- Adjust the oom-killer score -------------------------------------------------------------------------------- -This file can be used to adjust the badness heuristic used to select which +These file can be used to adjust the badness heuristic used to select which process gets killed in out of memory conditions. The badness heuristic assigns a value to each candidate task ranging from 0 @@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least equivalent to discounting 50% of the task's allowed memory from being considered as scoring against the task. +For backwards compatibility with previous kernels, /proc//oom_adj may also +be used to tune the badness score. Its acceptable values range from -16 +(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17 +(OOM_DISABLE) to disable oom killing entirely for that task. Its value is +scaled linearly with /proc//oom_score_adj. + The value of /proc//oom_score_adj may be reduced no lower than the last value set by a CAP_SYS_RESOURCE process. To reduce the value any lower requires CAP_SYS_RESOURCE. @@ -1375,7 +1381,9 @@ minimal amount of work. ------------------------------------------------------------- This file can be used to check the current score used by the oom-killer is for -any given . +any given . Use it together with /proc//oom_score_adj to tune which +process should be killed in an out-of-memory situation. + 3.3 /proc//io - Display the IO accounting fields ------------------------------------------------------- diff --git a/fs/proc/base.c b/fs/proc/base.c index 144a967..3c231ad 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = { .release = mem_release, }; +static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); + char buffer[PROC_NUMBUF]; + int oom_adj = OOM_ADJUST_MIN; + size_t len; + unsigned long flags; + + if (!task) + return -ESRCH; + if (lock_task_sighand(task, &flags)) { + if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX) + oom_adj = OOM_ADJUST_MAX; + else + oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / + OOM_SCORE_ADJ_MAX; + unlock_task_sighand(task, &flags); + } + put_task_struct(task); + len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj); + return simple_read_from_buffer(buf, count, ppos, buffer, len); +} + +static ssize_t oom_adj_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task; + char buffer[PROC_NUMBUF]; + int oom_adj; + unsigned long flags; + int err; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count)) { + err = -EFAULT; + goto out; + } + + err = kstrtoint(strstrip(buffer), 0, &oom_adj); + if (err) + goto out; + if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) && + oom_adj != OOM_DISABLE) { + err = -EINVAL; + goto out; + } + + task = get_proc_task(file->f_path.dentry->d_inode); + if (!task) { + err = -ESRCH; + goto out; + } + + task_lock(task); + if (!task->mm) { + err = -EINVAL; + goto err_task_lock; + } + + if (!lock_task_sighand(task, &flags)) { + err = -ESRCH; + goto err_task_lock; + } + + /* + * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum + * value is always attainable. + */ + if (oom_adj == OOM_ADJUST_MAX) + oom_adj = OOM_SCORE_ADJ_MAX; + else + oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; + + if (oom_adj < task->signal->oom_score_adj && + !capable(CAP_SYS_RESOURCE)) { + err = -EACCES; + goto err_sighand; + } + + /* + * /proc/pid/oom_adj is provided for legacy purposes, ask users to use + * /proc/pid/oom_score_adj instead. + */ + printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", + current->comm, task_pid_nr(current), task_pid_nr(task), + task_pid_nr(task)); + + task->signal->oom_score_adj = oom_adj; + trace_oom_score_adj_update(task); +err_sighand: + unlock_task_sighand(task, &flags); +err_task_lock: + task_unlock(task); + put_task_struct(task); +out: + return err < 0 ? err : count; +} + +static const struct file_operations proc_oom_adj_operations = { + .read = oom_adj_read, + .write = oom_adj_write, + .llseek = generic_file_llseek, +}; + static ssize_t oom_score_adj_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), + REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), @@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), + REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), diff --git a/include/uapi/linux/oom.h b/include/uapi/linux/oom.h index a49c4af..b29272d 100644 --- a/include/uapi/linux/oom.h +++ b/include/uapi/linux/oom.h @@ -8,4 +8,13 @@ #define OOM_SCORE_ADJ_MIN (-1000) #define OOM_SCORE_ADJ_MAX 1000 +/* + * /proc//oom_adj set to -17 protects from the oom killer for legacy + * purposes. + */ +#define OOM_DISABLE (-17) +/* inclusive */ +#define OOM_ADJUST_MIN (-16) +#define OOM_ADJUST_MAX 15 + #endif /* _UAPI__INCLUDE_LINUX_OOM_H */ -- cgit v1.1 From d3fb695576fc7f9d045da9e1ef001d94b0eea3cb Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Nov 2012 08:58:27 +0800 Subject: Thermal: Add Linux/Thermal subsystem info in MAINTAINER file All the changes made to the generic thermal layer, or platform thermal drivers that make use of the thermal layer, should be sent to linux-pm@vger.kernel.org for discussion. And as the maintainer, I will only apply the patches that have been sent to linux-pm@vger.kernel.org. Signed-off-by: Zhang Rui Signed-off-by: Linus Torvalds --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ff8e763..bb0b27d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7259,6 +7259,14 @@ L: linux-xtensa@linux-xtensa.org S: Maintained F: arch/xtensa/ +THERMAL +M: Zhang Rui +L: linux-pm@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git +S: Supported +F: drivers/thermal/ +F: include/linux/thermal.h + THINKPAD ACPI EXTRAS DRIVER M: Henrique de Moraes Holschuh L: ibm-acpi-devel@lists.sourceforge.net -- cgit v1.1 From 976a702ac9eeacea09e588456ab165dc06f9ee83 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 16 Nov 2012 05:31:53 +0000 Subject: tcp: handle tcp_net_metrics_init() order-5 memory allocation failures order-5 allocations can fail with current kernels, we should try vmalloc() as well. Reported-by: Julien Tinnes Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_metrics.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 53bc584..f696d7c 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -9,6 +8,7 @@ #include #include #include +#include #include #include @@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net) net->ipv4.tcp_metrics_hash_log = order_base_2(slots); size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; - net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); + net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); + if (!net->ipv4.tcp_metrics_hash) + net->ipv4.tcp_metrics_hash = vzalloc(size); + if (!net->ipv4.tcp_metrics_hash) return -ENOMEM; @@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net) tm = next; } } - kfree(net->ipv4.tcp_metrics_hash); + if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash)) + vfree(net->ipv4.tcp_metrics_hash); + else + kfree(net->ipv4.tcp_metrics_hash); } static __net_initdata struct pernet_operations tcp_net_metrics_ops = { -- cgit v1.1 From baefa31db2f2b13a05d1b81bdf2d20d487f58b0a Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Fri, 16 Nov 2012 09:04:15 +0000 Subject: net-rps: Fix brokeness causing OOO packets In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU selected for RFS is not set correctly when CPU is changing. This is causing OOO packets and probably other issues. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index bda6d00..c0946cb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2818,8 +2818,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (unlikely(tcpu != next_cpu) && (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || ((int)(per_cpu(softnet_data, tcpu).input_queue_head - - rflow->last_qtail)) >= 0)) + rflow->last_qtail)) >= 0)) { + tcpu = next_cpu; rflow = set_rps_cpu(dev, skb, rflow, next_cpu); + } if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { *rflowp = rflow; -- cgit v1.1 From a485e827f07bfdd0762059386e6e787bed6e81ee Mon Sep 17 00:00:00 2001 From: Albert Pool Date: Tue, 30 Oct 2012 20:58:06 +0100 Subject: rtlwifi: rtl8192cu: Add new USB ID This is an ISY IWL 2000. Probably a clone of Belkin F7D1102 050d:1102. Its FCC ID is the same. Signed-off-by: Albert Pool Cc: stable@vger.kernel.org Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b..b7e6607 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { /*=== Customer ID ===*/ /****** 8188CU ********/ {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ + {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ -- cgit v1.1 From b1a47aa5e1e159e2cb06d7dfcc17ef5149b09299 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 15 Nov 2012 15:58:47 -0800 Subject: mwifiex: fix system hang issue in cmd timeout error case Reported by Tim Shepard: I was seeing sporadic failures (wedgeups), and the majority of those failures I saw printed the printouts in mwifiex_cmd_timeout_func with cmd = 0xe5 which is CMD_802_11_HS_CFG_ENH. When this happens, two minutes later I get notified that the rtcwake thread is blocked, like this: INFO: task rtcwake:3495 blocked for more than 120 seconds. To get the hung thread unblocked we wake up the cmd wait queue and cancel the ioctl. Cc: "3.4+" Reported-by: Tim Shepard Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8d46510..ae9010e 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; - if (cmd_node->wait_q_enabled) - adapter->cmd_wait_q.status = -ETIMEDOUT; - if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); + + if (cmd_node->wait_q_enabled) { + adapter->cmd_wait_q.status = -ETIMEDOUT; + wake_up_interruptible(&adapter->cmd_wait_q.wait); + mwifiex_cancel_pending_ioctl(adapter); + /* reset cmd_sent flag to unblock new commands */ + adapter->cmd_sent = false; + } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); -- cgit v1.1 From dd321acddc3be1371263b8c9e6c6f2af89f63d57 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 15 Nov 2012 15:58:48 -0800 Subject: mwifiex: report error to MMC core if we cannot suspend When host_sleep_config command fails we should return error to MMC core to indicate the failure for our device. The misspelled variable is also removed as it's redundant. Cc: "3.0+" Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sdio.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fc8a9bf..82cf0fa 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; - int hs_actived = 0; int i; int ret = 0; @@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev) adapter = card->adapter; /* Enable the Host Sleep */ - hs_actived = mwifiex_enable_hs(adapter); - if (hs_actived) { - pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (!mwifiex_enable_hs(adapter)) { + dev_err(adapter->dev, "cmd: failed to suspend\n"); + return -EFAULT; } + dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + /* Indicate device suspended */ adapter->is_suspended = true; -- cgit v1.1 From 38c1a01cf10c6e4049b4ffbd4a6af655df2a46e1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Nov 2012 20:46:19 +0100 Subject: wireless: add back sysfs directory commit 35b2a113cb0298d4f9a1263338b456094a414057 broke (at least) Fedora's networking scripts, they check for the existence of the wireless directory. As the files aren't used, add the directory back and not the files. Also do it for both drivers based on the old wireless extensions and cfg80211, regardless of whether the compat code for wext is built into cfg80211 or not. Cc: stable@vger.kernel.org [3.6] Reported-by: Dave Airlie Reported-by: Bill Nottingham Signed-off-by: Johannes Berg --- net/core/net-sysfs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index bcf02f6..017a8ba 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -429,6 +429,17 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) +static struct attribute *wireless_attrs[] = { + NULL +}; + +static struct attribute_group wireless_group = { + .name = "wireless", + .attrs = wireless_attrs, +}; +#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) + if (net->ieee80211_ptr) + *groups++ = &wireless_group; +#if IS_ENABLED(CONFIG_WIRELESS_EXT) + else if (net->wireless_handlers) + *groups++ = &wireless_group; +#endif +#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); -- cgit v1.1 From 29282fde80d44e587f8c152b10049a56e61659f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Nov 2012 15:20:17 +0100 Subject: KVM: x86: Fix invalid secondary exec controls in vmx_cpuid_update() The commit [ad756a16: KVM: VMX: Implement PCID/INVPCID for guests with EPT] introduced the unconditional access to SECONDARY_VM_EXEC_CONTROL, and this triggers kernel warnings like below on old CPUs: vmwrite error: reg 401e value a0568000 (err 12) Pid: 13649, comm: qemu-kvm Not tainted 3.7.0-rc4-test2+ #154 Call Trace: [] vmwrite_error+0x27/0x29 [kvm_intel] [] vmcs_writel+0x1b/0x20 [kvm_intel] [] vmx_cpuid_update+0x74/0x170 [kvm_intel] [] kvm_vcpu_ioctl_set_cpuid2+0x76/0x90 [kvm] [] kvm_arch_vcpu_ioctl+0xc37/0xed0 [kvm] [] ? __vunmap+0x9c/0x110 [] ? vmx_vcpu_load+0x39/0x1a0 [kvm_intel] [] ? kvm_arch_vcpu_load+0x52/0x1a0 [kvm] [] ? vcpu_load+0x74/0xd0 [kvm] [] kvm_vcpu_ioctl+0x110/0x5e0 [kvm] [] ? kvm_dev_ioctl+0x4d/0x4a0 [kvm] [] do_vfs_ioctl+0x8f/0x530 [] ? remove_vma+0x56/0x60 [] ? do_munmap+0x328/0x400 [] ? fget_light+0x4c/0x100 [] sys_ioctl+0x91/0xb0 [] system_call_fastpath+0x1a/0x1f This patch adds a check for the availability of secondary exec control to avoid these warnings. Cc: [v3.6+] Signed-off-by: Takashi Iwai Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/vmx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad6b1dd..f858159 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) } } - exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); /* Exposing INVPCID only when PCID is exposed */ best = kvm_find_cpuid_entry(vcpu, 0x7, 0); if (vmx_invpcid_supported() && best && (best->ebx & bit(X86_FEATURE_INVPCID)) && guest_cpuid_has_pcid(vcpu)) { + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); } else { - exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; - vmcs_write32(SECONDARY_VM_EXEC_CONTROL, - exec_control); + if (cpu_has_secondary_exec_ctrls()) { + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, + exec_control); + } if (best) best->ebx &= ~bit(X86_FEATURE_INVPCID); } -- cgit v1.1 From 63c3b902e517012b127d6528434b928ceaa10f7b Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Fri, 16 Nov 2012 14:14:47 -0800 Subject: mm: add anon_vma_lock to validate_mm() Iterating over the vma->anon_vma_chain without anon_vma_lock may cause NULL ptr deref in anon_vma_interval_tree_verify(), because the node in the chain might have been removed. BUG: unable to handle kernel paging request at fffffffffffffff0 IP: [] anon_vma_interval_tree_verify+0xc/0xa0 PGD 4e28067 PUD 4e29067 PMD 0 Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC CPU 0 Pid: 9050, comm: trinity-child64 Tainted: G W 3.7.0-rc2-next-20121025-sasha-00001-g673f98e-dirty #77 RIP: 0010: anon_vma_interval_tree_verify+0xc/0xa0 Process trinity-child64 (pid: 9050, threadinfo ffff880045f80000, task ffff880048eb0000) Call Trace: validate_mm+0x58/0x1e0 vma_adjust+0x635/0x6b0 __split_vma.isra.22+0x161/0x220 split_vma+0x24/0x30 sys_madvise+0x5da/0x7b0 tracesys+0xe1/0xe6 RIP anon_vma_interval_tree_verify+0xc/0xa0 CR2: fffffffffffffff0 Figured out by Bob Liu. Reported-by: Sasha Levin Cc: Bob Liu Signed-off-by: Michel Lespinasse Reviewed-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/mmap.c b/mm/mmap.c index 2d94235..9a796c4 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -334,8 +334,10 @@ void validate_mm(struct mm_struct *mm) struct vm_area_struct *vma = mm->mmap; while (vma) { struct anon_vma_chain *avc; + vma_lock_anon_vma(vma); list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) anon_vma_interval_tree_verify(avc); + vma_unlock_anon_vma(vma); vma = vma->vm_next; i++; } -- cgit v1.1 From 1756954c61cb5c97c618ccb366482b9c1f891d6d Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 16 Nov 2012 14:14:48 -0800 Subject: mm: fix build warning for uninitialized value do_wp_page() sets mmun_called if mmun_start and mmun_end were initialized and, if so, may call mmu_notifier_invalidate_range_end() with these values. This doesn't prevent gcc from emitting a build warning though: mm/memory.c: In function `do_wp_page': mm/memory.c:2530: warning: `mmun_start' may be used uninitialized in this function mm/memory.c:2531: warning: `mmun_end' may be used uninitialized in this function It's much easier to initialize the variables to impossible values and do a simple comparison to determine if they were initialized to remove the bool entirely. Signed-off-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index fb135ba..221fc9f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2527,9 +2527,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, int ret = 0; int page_mkwrite = 0; struct page *dirty_page = NULL; - unsigned long mmun_start; /* For mmu_notifiers */ - unsigned long mmun_end; /* For mmu_notifiers */ - bool mmun_called = false; /* For mmu_notifiers */ + unsigned long mmun_start = 0; /* For mmu_notifiers */ + unsigned long mmun_end = 0; /* For mmu_notifiers */ old_page = vm_normal_page(vma, address, orig_pte); if (!old_page) { @@ -2708,8 +2707,7 @@ gotten: goto oom_free_new; mmun_start = address & PAGE_MASK; - mmun_end = (address & PAGE_MASK) + PAGE_SIZE; - mmun_called = true; + mmun_end = mmun_start + PAGE_SIZE; mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); /* @@ -2778,7 +2776,7 @@ gotten: page_cache_release(new_page); unlock: pte_unmap_unlock(page_table, ptl); - if (mmun_called) + if (mmun_end > mmun_start) mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); if (old_page) { /* -- cgit v1.1 From 9a5a8f19b43430752067ecaee62fc59e11e88fa6 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Fri, 16 Nov 2012 14:14:49 -0800 Subject: memcg: oom: fix totalpages calculation for memory.swappiness==0 oom_badness() takes a totalpages argument which says how many pages are available and it uses it as a base for the score calculation. The value is calculated by mem_cgroup_get_limit which considers both limit and total_swap_pages (resp. memsw portion of it). This is usually correct but since fe35004fbf9e ("mm: avoid swapping out with swappiness==0") we do not swap when swappiness is 0 which means that we cannot really use up all the totalpages pages. This in turn confuses oom score calculation if the memcg limit is much smaller than the available swap because the used memory (capped by the limit) is negligible comparing to totalpages so the resulting score is too small if adj!=0 (typically task with CAP_SYS_ADMIN or non zero oom_score_adj). A wrong process might be selected as result. The problem can be worked around by checking mem_cgroup_swappiness==0 and not considering swap at all in such a case. Signed-off-by: Michal Hocko Acked-by: David Rientjes Acked-by: Johannes Weiner Acked-by: KOSAKI Motohiro Acked-by: KAMEZAWA Hiroyuki Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/memory.txt | 4 ++++ mm/memcontrol.c | 21 +++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index c07f7b4..71c4da4 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt @@ -466,6 +466,10 @@ Note: 5.3 swappiness Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. +Please note that unlike the global swappiness, memcg knob set to 0 +really prevents from any swapping even if there is a swap storage +available. This might lead to memcg OOM killer if there are no file +pages to reclaim. Following cgroups' swappiness can't be changed. - root cgroup (uses /proc/sys/vm/swappiness). diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7acf43b..93a7e36 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1452,17 +1452,26 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg) static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg) { u64 limit; - u64 memsw; limit = res_counter_read_u64(&memcg->res, RES_LIMIT); - limit += total_swap_pages << PAGE_SHIFT; - memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); /* - * If memsw is finite and limits the amount of swap space available - * to this memcg, return that limit. + * Do not consider swap space if we cannot swap due to swappiness */ - return min(limit, memsw); + if (mem_cgroup_swappiness(memcg)) { + u64 memsw; + + limit += total_swap_pages << PAGE_SHIFT; + memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); + + /* + * If memsw is finite and limits the amount of swap space + * available to this memcg, return that limit. + */ + limit = min(limit, memsw); + } + + return limit; } void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, -- cgit v1.1 From 18f694271b86ee279e88208550cc49fee206b544 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 16 Nov 2012 14:14:52 -0800 Subject: mips, arc: fix build failure Using a cross-compiler to fix another issue, the following build error occurred for mips defconfig: arch/mips/fw/arc/misc.c: In function 'ArcHalt': arch/mips/fw/arc/misc.c:25:2: error: implicit declaration of function 'local_irq_disable' Fix it up by including irqflags.h. Signed-off-by: David Rientjes Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/fw/arc/misc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c index 7cf80ca..f9f5307 100644 --- a/arch/mips/fw/arc/misc.c +++ b/arch/mips/fw/arc/misc.c @@ -11,6 +11,7 @@ */ #include #include +#include #include -- cgit v1.1 From bea8c150a7efbc0f204e709b7274fe273f55e0d3 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 16 Nov 2012 14:14:54 -0800 Subject: memcg: fix hotplugged memory zone oops When MEMCG is configured on (even when it's disabled by boot option), when adding or removing a page to/from its lru list, the zone pointer used for stats updates is nowadays taken from the struct lruvec. (On many configurations, calculating zone from page is slower.) But we have no code to update all the lruvecs (per zone, per memcg) when a memory node is hotadded. Here's an extract from the oops which results when running numactl to bind a program to a newly onlined node: BUG: unable to handle kernel NULL pointer dereference at 0000000000000f60 IP: __mod_zone_page_state+0x9/0x60 Pid: 1219, comm: numactl Not tainted 3.6.0-rc5+ #180 Bochs Bochs Process numactl (pid: 1219, threadinfo ffff880039abc000, task ffff8800383c4ce0) Call Trace: __pagevec_lru_add_fn+0xdf/0x140 pagevec_lru_move_fn+0xb1/0x100 __pagevec_lru_add+0x1c/0x30 lru_add_drain_cpu+0xa3/0x130 lru_add_drain+0x2f/0x40 ... The natural solution might be to use a memcg callback whenever memory is hotadded; but that solution has not been scoped out, and it happens that we do have an easy location at which to update lruvec->zone. The lruvec pointer is discovered either by mem_cgroup_zone_lruvec() or by mem_cgroup_page_lruvec(), and both of those do know the right zone. So check and set lruvec->zone in those; and remove the inadequate attempt to set lruvec->zone from lruvec_init(), which is called before NODE_DATA(node) has been allocated in such cases. Ah, there was one exceptionr. For no particularly good reason, mem_cgroup_force_empty_list() has its own code for deciding lruvec. Change it to use the standard mem_cgroup_zone_lruvec() and mem_cgroup_get_lru_size() too. In fact it was already safe against such an oops (the lru lists in danger could only be empty), but we're better proofed against future changes this way. I've marked this for stable (3.6) since we introduced the problem in 3.5 (now closed to stable); but I have no idea if this is the only fix needed to get memory hotadd working with memcg in 3.6, and received no answer when I enquired twice before. Reported-by: Tang Chen Signed-off-by: Hugh Dickins Acked-by: Johannes Weiner Acked-by: KAMEZAWA Hiroyuki Cc: Konstantin Khlebnikov Cc: Wen Congyang Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 2 +- mm/memcontrol.c | 46 +++++++++++++++++++++++++++++++++++----------- mm/mmzone.c | 6 +----- mm/page_alloc.c | 2 +- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 50aaca8..a23923b 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -752,7 +752,7 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn, unsigned long size, enum memmap_context context); -extern void lruvec_init(struct lruvec *lruvec, struct zone *zone); +extern void lruvec_init(struct lruvec *lruvec); static inline struct zone *lruvec_zone(struct lruvec *lruvec) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 93a7e36..dd39ba0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1055,12 +1055,24 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone, struct mem_cgroup *memcg) { struct mem_cgroup_per_zone *mz; + struct lruvec *lruvec; - if (mem_cgroup_disabled()) - return &zone->lruvec; + if (mem_cgroup_disabled()) { + lruvec = &zone->lruvec; + goto out; + } mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone)); - return &mz->lruvec; + lruvec = &mz->lruvec; +out: + /* + * Since a node can be onlined after the mem_cgroup was created, + * we have to be prepared to initialize lruvec->zone here; + * and if offlined then reonlined, we need to reinitialize it. + */ + if (unlikely(lruvec->zone != zone)) + lruvec->zone = zone; + return lruvec; } /* @@ -1087,9 +1099,12 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) struct mem_cgroup_per_zone *mz; struct mem_cgroup *memcg; struct page_cgroup *pc; + struct lruvec *lruvec; - if (mem_cgroup_disabled()) - return &zone->lruvec; + if (mem_cgroup_disabled()) { + lruvec = &zone->lruvec; + goto out; + } pc = lookup_page_cgroup(page); memcg = pc->mem_cgroup; @@ -1107,7 +1122,16 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) pc->mem_cgroup = memcg = root_mem_cgroup; mz = page_cgroup_zoneinfo(memcg, page); - return &mz->lruvec; + lruvec = &mz->lruvec; +out: + /* + * Since a node can be onlined after the mem_cgroup was created, + * we have to be prepared to initialize lruvec->zone here; + * and if offlined then reonlined, we need to reinitialize it. + */ + if (unlikely(lruvec->zone != zone)) + lruvec->zone = zone; + return lruvec; } /** @@ -3697,17 +3721,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg, int node, int zid, enum lru_list lru) { - struct mem_cgroup_per_zone *mz; + struct lruvec *lruvec; unsigned long flags, loop; struct list_head *list; struct page *busy; struct zone *zone; zone = &NODE_DATA(node)->node_zones[zid]; - mz = mem_cgroup_zoneinfo(memcg, node, zid); - list = &mz->lruvec.lists[lru]; + lruvec = mem_cgroup_zone_lruvec(zone, memcg); + list = &lruvec->lists[lru]; - loop = mz->lru_size[lru]; + loop = mem_cgroup_get_lru_size(lruvec, lru); /* give some margin against EBUSY etc...*/ loop += 256; busy = NULL; @@ -4745,7 +4769,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) for (zone = 0; zone < MAX_NR_ZONES; zone++) { mz = &pn->zoneinfo[zone]; - lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]); + lruvec_init(&mz->lruvec); mz->usage_in_excess = 0; mz->on_tree = false; mz->memcg = memcg; diff --git a/mm/mmzone.c b/mm/mmzone.c index 3cef80f..4596d81 100644 --- a/mm/mmzone.c +++ b/mm/mmzone.c @@ -87,7 +87,7 @@ int memmap_valid_within(unsigned long pfn, } #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ -void lruvec_init(struct lruvec *lruvec, struct zone *zone) +void lruvec_init(struct lruvec *lruvec) { enum lru_list lru; @@ -95,8 +95,4 @@ void lruvec_init(struct lruvec *lruvec, struct zone *zone) for_each_lru(lru) INIT_LIST_HEAD(&lruvec->lists[lru]); - -#ifdef CONFIG_MEMCG - lruvec->zone = zone; -#endif } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5b74de6..c91598b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4505,7 +4505,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, zone->zone_pgdat = pgdat; zone_pcp_init(zone); - lruvec_init(&zone->lruvec, zone); + lruvec_init(&zone->lruvec); if (!size) continue; -- cgit v1.1 From f58b59c1df3cb990d644018e1461cd4acd3c1700 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Fri, 16 Nov 2012 14:14:55 -0800 Subject: swapfile: fix name leak in swapoff There's a name leak introduced by commit 91a27b2a7567 ("vfs: define struct filename and have getname() return it"). Add the missing putname. [akpm@linux-foundation.org: cleanup] Signed-off-by: Xiaotian Feng Reviewed-by: Jeff Layton Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/swapfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 71cd288..f91a255 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1494,9 +1494,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) BUG_ON(!current->mm); pathname = getname(specialfile); - err = PTR_ERR(pathname); if (IS_ERR(pathname)) - goto out; + return PTR_ERR(pathname); victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0); err = PTR_ERR(victim); @@ -1608,6 +1607,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) out_dput: filp_close(victim, NULL); out: + putname(pathname); return err; } -- cgit v1.1 From 2ca3cb50edc351875df13d083524f524cdeb3054 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 16 Nov 2012 14:14:56 -0800 Subject: rapidio: fix kernel-doc warnings Fix rapidio kernel-doc warnings: Warning(drivers/rapidio/rio.c:415): No description found for parameter 'local' Warning(drivers/rapidio/rio.c:415): Excess function parameter 'lstart' description in 'rio_map_inb_region' Warning(include/linux/rio.h:290): No description found for parameter 'switches' Warning(include/linux/rio.h:290): No description found for parameter 'destid_table' Signed-off-by: Randy Dunlap Cc: Matt Porter Acked-by: Alexandre Bounine Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/rio.c | 2 +- include/linux/rio.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index c17ae22..0c6fcb4 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); /** * rio_map_inb_region -- Map inbound memory region. * @mport: Master port. - * @lstart: physical address of memory region to be mapped + * @local: physical address of memory region to be mapped * @rbase: RIO base address assigned to this window * @size: Size of the memory region * @rflags: Flags for mapping. diff --git a/include/linux/rio.h b/include/linux/rio.h index 4187da5..a3e7842 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -275,9 +275,11 @@ struct rio_id_table { * struct rio_net - RIO network info * @node: Node in global list of RIO networks * @devices: List of devices in this network + * @switches: List of switches in this netowrk * @mports: List of master ports accessing this network * @hport: Default port for accessing this network * @id: RIO network ID + * @destid_table: destID allocation table */ struct rio_net { struct list_head node; /* node in list of networks */ -- cgit v1.1 From 96710098ee124951ff2fed7cd8406da92aad011a Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Fri, 16 Nov 2012 14:14:59 -0800 Subject: mm: revert "mm: vmscan: scale number of pages reclaimed by reclaim/compaction based on failures" Jiri Slaby reported the following: (It's an effective revert of "mm: vmscan: scale number of pages reclaimed by reclaim/compaction based on failures".) Given kswapd had hours of runtime in ps/top output yesterday in the morning and after the revert it's now 2 minutes in sum for the last 24h, I would say, it's gone. The intention of the patch in question was to compensate for the loss of lumpy reclaim. Part of the reason lumpy reclaim worked is because it aggressively reclaimed pages and this patch was meant to be a sane compromise. When compaction fails, it gets deferred and both compaction and reclaim/compaction is deferred avoid excessive reclaim. However, since commit c654345924f7 ("mm: remove __GFP_NO_KSWAPD"), kswapd is woken up each time and continues reclaiming which was not taken into account when the patch was developed. Attempts to address the problem ended up just changing the shape of the problem instead of fixing it. The release window gets closer and while a THP allocation failing is not a major problem, kswapd chewing up a lot of CPU is. This patch reverts commit 83fde0f22872 ("mm: vmscan: scale number of pages reclaimed by reclaim/compaction based on failures") and will be revisited in the future. Signed-off-by: Mel Gorman Cc: Zdenek Kabelac Tested-by: Valdis Kletnieks Cc: Jiri Slaby Cc: Rik van Riel Cc: Jiri Slaby Cc: Johannes Hirte Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 8b055e9..48550c6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1760,28 +1760,6 @@ static bool in_reclaim_compaction(struct scan_control *sc) return false; } -#ifdef CONFIG_COMPACTION -/* - * If compaction is deferred for sc->order then scale the number of pages - * reclaimed based on the number of consecutive allocation failures - */ -static unsigned long scale_for_compaction(unsigned long pages_for_compaction, - struct lruvec *lruvec, struct scan_control *sc) -{ - struct zone *zone = lruvec_zone(lruvec); - - if (zone->compact_order_failed <= sc->order) - pages_for_compaction <<= zone->compact_defer_shift; - return pages_for_compaction; -} -#else -static unsigned long scale_for_compaction(unsigned long pages_for_compaction, - struct lruvec *lruvec, struct scan_control *sc) -{ - return pages_for_compaction; -} -#endif - /* * Reclaim/compaction is used for high-order allocation requests. It reclaims * order-0 pages before compacting the zone. should_continue_reclaim() returns @@ -1829,9 +1807,6 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec, * inactive lists are large enough, continue reclaiming */ pages_for_compaction = (2UL << sc->order); - - pages_for_compaction = scale_for_compaction(pages_for_compaction, - lruvec, sc); inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE); if (nr_swap_pages > 0) inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON); -- cgit v1.1 From 498c2280212327858e521e9d21345d4cc2637f54 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 16 Nov 2012 14:15:00 -0800 Subject: mm: highmem: don't treat PKMAP_ADDR(LAST_PKMAP) as a highmem address kmap_to_page returns the corresponding struct page for a virtual address of an arbitrary mapping. This works by checking whether the address falls in the pkmap region and using the pkmap page tables instead of the linear mapping if appropriate. Unfortunately, the bounds checking means that PKMAP_ADDR(LAST_PKMAP) is incorrectly treated as a highmem address and we can end up walking off the end of pkmap_page_table and subsequently passing junk to pte_page. This patch fixes the bound check to stay within the pkmap tables. Signed-off-by: Will Deacon Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/highmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/highmem.c b/mm/highmem.c index d517cd1..2da13a5 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -98,7 +98,7 @@ struct page *kmap_to_page(void *vaddr) { unsigned long addr = (unsigned long)vaddr; - if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) { + if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) { int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT; return pte_page(pkmap_page_table[i]); } -- cgit v1.1 From 215c02bc33bbd5ff4d7379a909462d11f0103218 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 16 Nov 2012 14:15:03 -0800 Subject: tmpfs: fix shmem_getpage_gfp() VM_BUG_ON Fuzzing with trinity hit the "impossible" VM_BUG_ON(error) (which Fedora has converted to WARNING) in shmem_getpage_gfp(): WARNING: at mm/shmem.c:1151 shmem_getpage_gfp+0xa5c/0xa70() Pid: 29795, comm: trinity-child4 Not tainted 3.7.0-rc2+ #49 Call Trace: warn_slowpath_common+0x7f/0xc0 warn_slowpath_null+0x1a/0x20 shmem_getpage_gfp+0xa5c/0xa70 shmem_fault+0x4f/0xa0 __do_fault+0x71/0x5c0 handle_pte_fault+0x97/0xae0 handle_mm_fault+0x289/0x350 __do_page_fault+0x18e/0x530 do_page_fault+0x2b/0x50 page_fault+0x28/0x30 tracesys+0xe1/0xe6 Thanks to Johannes for pointing to truncation: free_swap_and_cache() only does a trylock on the page, so the page lock we've held since before confirming swap is not enough to protect against truncation. What cleanup is needed in this case? Just delete_from_swap_cache(), which takes care of the memcg uncharge. Signed-off-by: Hugh Dickins Reported-by: Dave Jones Cc: Johannes Weiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/shmem.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 67afba5..dc12264 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1145,8 +1145,20 @@ repeat: if (!error) { error = shmem_add_to_page_cache(page, mapping, index, gfp, swp_to_radix_entry(swap)); - /* We already confirmed swap, and make no allocation */ - VM_BUG_ON(error); + /* + * We already confirmed swap under page lock, and make + * no memory allocation here, so usually no possibility + * of error; but free_swap_and_cache() only trylocks a + * page, so it is just possible that the entry has been + * truncated or holepunched since swap was confirmed. + * shmem_undo_range() will have done some of the + * unaccounting, now delete_from_swap_cache() will do + * the rest (including mem_cgroup_uncharge_swapcache). + * Reset swap.val? No, leave it so "failed" goes back to + * "repeat": reading a hole and writing should succeed. + */ + if (error) + delete_from_swap_cache(page); } if (error) goto failed; -- cgit v1.1 From 0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 16 Nov 2012 14:15:04 -0800 Subject: tmpfs: change final i_blocks BUG to WARNING Under a particular load on one machine, I have hit shmem_evict_inode()'s BUG_ON(inode->i_blocks), enough times to narrow it down to a particular race between swapout and eviction. It comes from the "if (freed > 0)" asymmetry in shmem_recalc_inode(), and the lack of coherent locking between mapping's nrpages and shmem's swapped count. There's a window in shmem_writepage(), between lowering nrpages in shmem_delete_from_page_cache() and then raising swapped count, when the freed count appears to be +1 when it should be 0, and then the asymmetry stops it from being corrected with -1 before hitting the BUG. One answer is coherent locking: using tree_lock throughout, without info->lock; reasonable, but the raw_spin_lock in percpu_counter_add() on used_blocks makes that messier than expected. Another answer may be a further effort to eliminate the weird shmem_recalc_inode() altogether, but previous attempts at that failed. So far undecided, but for now change the BUG_ON to WARN_ON: in usual circumstances it remains a useful consistency check. Signed-off-by: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/shmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/shmem.c b/mm/shmem.c index dc12264..89341b6 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -643,7 +643,7 @@ static void shmem_evict_inode(struct inode *inode) kfree(info->symlink); simple_xattrs_free(&info->xattrs); - BUG_ON(inode->i_blocks); + WARN_ON(inode->i_blocks); shmem_free_inode(inode->i_sb); clear_inode(inode); } -- cgit v1.1 From 5576646f3c1abd60d72d19829de6f5d8c2ca8ecf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 16 Nov 2012 14:15:06 -0800 Subject: revert "mm: fix-up zone present pages" Revert commit 7f1290f2f2a4 ("mm: fix-up zone present pages") That patch tried to fix a issue when calculating zone->present_pages, but it caused a regression on 32bit systems with HIGHMEM. With that change, reset_zone_present_pages() resets all zone->present_pages to zero, and fixup_zone_present_pages() is called to recalculate zone->present_pages when the boot allocator frees core memory pages into buddy allocator. Because highmem pages are not freed by bootmem allocator, all highmem zones' present_pages becomes zero. Various options for improving the situation are being discussed but for now, let's return to the 3.6 code. Cc: Jianguo Wu Cc: Jiang Liu Cc: Petr Tesarik Cc: "Luck, Tony" Cc: Mel Gorman Cc: Yinghai Lu Cc: Minchan Kim Cc: Johannes Weiner Acked-by: David Rientjes Tested-by: Chris Clayton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/mm/init.c | 1 - include/linux/mm.h | 4 ---- mm/bootmem.c | 10 +--------- mm/memory_hotplug.c | 7 ------- mm/nobootmem.c | 3 --- mm/page_alloc.c | 34 ---------------------------------- 6 files changed, 1 insertion(+), 58 deletions(-) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index acd5b68..082e383 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -637,7 +637,6 @@ mem_init (void) high_memory = __va(max_low_pfn * PAGE_SIZE); - reset_zone_present_pages(); for_each_online_pgdat(pgdat) if (pgdat->bdata->node_bootmem_map) totalram_pages += free_all_bootmem_node(pgdat); diff --git a/include/linux/mm.h b/include/linux/mm.h index fa06804..bcaab4e 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1684,9 +1684,5 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; } static inline bool page_is_guard(struct page *page) { return false; } #endif /* CONFIG_DEBUG_PAGEALLOC */ -extern void reset_zone_present_pages(void); -extern void fixup_zone_present_pages(int nid, unsigned long start_pfn, - unsigned long end_pfn); - #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/mm/bootmem.c b/mm/bootmem.c index 434be4a..f468185 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -198,8 +198,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) int order = ilog2(BITS_PER_LONG); __free_pages_bootmem(pfn_to_page(start), order); - fixup_zone_present_pages(page_to_nid(pfn_to_page(start)), - start, start + BITS_PER_LONG); count += BITS_PER_LONG; start += BITS_PER_LONG; } else { @@ -210,9 +208,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) if (vec & 1) { page = pfn_to_page(start + off); __free_pages_bootmem(page, 0); - fixup_zone_present_pages( - page_to_nid(page), - start + off, start + off + 1); count++; } vec >>= 1; @@ -226,11 +221,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) pages = bdata->node_low_pfn - bdata->node_min_pfn; pages = bootmem_bootmap_pages(pages); count += pages; - while (pages--) { - fixup_zone_present_pages(page_to_nid(page), - page_to_pfn(page), page_to_pfn(page) + 1); + while (pages--) __free_pages_bootmem(page++, 0); - } bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 56b758a..e4eeaca 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -106,7 +106,6 @@ static void get_page_bootmem(unsigned long info, struct page *page, void __ref put_page_bootmem(struct page *page) { unsigned long type; - struct zone *zone; type = (unsigned long) page->lru.next; BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || @@ -117,12 +116,6 @@ void __ref put_page_bootmem(struct page *page) set_page_private(page, 0); INIT_LIST_HEAD(&page->lru); __free_pages_bootmem(page, 0); - - zone = page_zone(page); - zone_span_writelock(zone); - zone->present_pages++; - zone_span_writeunlock(zone); - totalram_pages++; } } diff --git a/mm/nobootmem.c b/mm/nobootmem.c index 714d5d6..bd82f6b 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c @@ -116,8 +116,6 @@ static unsigned long __init __free_memory_core(phys_addr_t start, return 0; __free_pages_memory(start_pfn, end_pfn); - fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT), - start_pfn, end_pfn); return end_pfn - start_pfn; } @@ -128,7 +126,6 @@ unsigned long __init free_low_memory_core_early(int nodeid) phys_addr_t start, end, size; u64 i; - reset_zone_present_pages(); for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL) count += __free_memory_core(start, end); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c91598b..7bb35ac 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -6098,37 +6098,3 @@ void dump_page(struct page *page) dump_page_flags(page->flags); mem_cgroup_print_bad_page(page); } - -/* reset zone->present_pages */ -void reset_zone_present_pages(void) -{ - struct zone *z; - int i, nid; - - for_each_node_state(nid, N_HIGH_MEMORY) { - for (i = 0; i < MAX_NR_ZONES; i++) { - z = NODE_DATA(nid)->node_zones + i; - z->present_pages = 0; - } - } -} - -/* calculate zone's present pages in buddy system */ -void fixup_zone_present_pages(int nid, unsigned long start_pfn, - unsigned long end_pfn) -{ - struct zone *z; - unsigned long zone_start_pfn, zone_end_pfn; - int i; - - for (i = 0; i < MAX_NR_ZONES; i++) { - z = NODE_DATA(nid)->node_zones + i; - zone_start_pfn = z->zone_start_pfn; - zone_end_pfn = zone_start_pfn + z->spanned_pages; - - /* if the two regions intersect */ - if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn)) - z->present_pages += min(end_pfn, zone_end_pfn) - - max(start_pfn, zone_start_pfn); - } -} -- cgit v1.1 From f4a75d2eb7b1e2206094b901be09adb31ba63681 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 16 Nov 2012 17:42:40 -0800 Subject: Linux 3.7-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6edac73..9f6ca12 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Terrified Chipmunk # *DOCUMENTATION* -- cgit v1.1 From e41105687b90819d04226ee454e2dd0fc1130810 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 23 Oct 2012 16:16:23 +0200 Subject: iommu/amd: Update MAINTAINERS entry I have no access to my AMD email address anymore. Update entry in MAINTAINERS to the new address. Signed-off-by: Joerg Roedel --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index bb0b27d..0f043a7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -526,10 +526,10 @@ F: drivers/video/geode/ F: arch/x86/include/asm/geode.h AMD IOMMU (AMD-VI) -M: Joerg Roedel +M: Joerg Roedel L: iommu@lists.linux-foundation.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git -S: Supported +S: Maintained F: drivers/iommu/amd_iommu*.[ch] F: include/linux/amd-iommu.h -- cgit v1.1 From b334b64862efd0eee8d07f2faabbe4b56ee974cd Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Sun, 11 Nov 2012 21:49:30 +0100 Subject: iommu/tegra-smmu.c: fix dentry reference leak in smmu_debugfs_stats_show(). Call to d_find_alias() needs a corresponding dput(). Signed-off-by: Cyril Roelandt Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index a649f14..c0f7a42 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v) stats[i], val, offs); } seq_printf(s, "\n"); + dput(dent); return 0; } -- cgit v1.1 From 3da4af0affbb797e8ac4c2b4598da0c34b8cc52a Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 13 Nov 2012 10:22:03 -0700 Subject: intel-iommu: Fix lookup in add device We can't assume this device exists, fall back to the bridge itself. Signed-off-by: Alex Williamson Tested-by: Matthew Thode Cc: stable@vger.kernel.org Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d4a4cd4..0badfa4 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) static int intel_iommu_add_device(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_dev *bridge, *dma_pdev; + struct pci_dev *bridge, *dma_pdev = NULL; struct iommu_group *group; int ret; @@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev) dma_pdev = pci_get_domain_bus_and_slot( pci_domain_nr(pdev->bus), bridge->subordinate->number, 0); - else + if (!dma_pdev) dma_pdev = pci_dev_get(bridge); } else dma_pdev = pci_dev_get(pdev); -- cgit v1.1 From 42e2976f131d65555d5c1d6c3d47facc63577814 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 12 Nov 2012 22:09:44 +1100 Subject: xfs: fix attr tree double split corruption In certain circumstances, a double split of an attribute tree is needed to insert or replace an attribute. In rare situations, this can go wrong, leaving the attribute tree corrupted. In this case, the attr being replaced is the last attr in a leaf node, and the replacement is larger so doesn't fit in the same leaf node. When we have the initial condition of a node format attribute btree with two leaves at index 1 and 2. Call them L1 and L2. The leaf L1 is completely full, there is not a single byte of free space in it. L2 is mostly empty. The attribute being replaced - call it X - is the last attribute in L1. The way an attribute replace is executed is that the replacement attribute - call it Y - is first inserted into the tree, but has an INCOMPLETE flag set on it so that list traversals ignore it. Once this transaction is committed, a second transaction it run to atomically mark Y as COMPLETE and X as INCOMPLETE, so that a traversal will now find Y and skip X. Once that transaction is committed, attribute X is then removed. So, the initial condition is: +--------+ +--------+ | L1 | | L2 | | fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 | | fsp: 0 | | fsp: N | |--------| |--------| | attr A | | attr 1 | |--------| |--------| | attr B | | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr X | | attr n | +--------+ +--------+ So now we go to replace X, and see that L1:fsp = 0 - it is full so we can't insert Y in the same leaf. So we record the the location of attribute X so we can track it for later use, then we split L1 into L1 and L3 and reblance across the two leafs. We end with: +--------+ +--------+ +--------+ | L1 | | L3 | | L2 | | fwd: 3 |---->| fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 |<----| bwd: 3 | | fsp: M | | fsp: J | | fsp: N | |--------| |--------| |--------| | attr A | | attr X | | attr 1 | |--------| +--------+ |--------| | attr B | | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr W | | attr n | +--------+ +--------+ And we track that the original attribute is now at L3:0. We then try to insert Y into L1 again, and find that there isn't enough room because the new attribute is larger than the old one. Hence we have to split again to make room for Y. We end up with this: +--------+ +--------+ +--------+ +--------+ | L1 | | L4 | | L3 | | L2 | | fwd: 4 |---->| fwd: 3 |---->| fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 |<----| bwd: 4 |<----| bwd: 3 | | fsp: M | | fsp: J | | fsp: J | | fsp: N | |--------| |--------| |--------| |--------| | attr A | | attr Y | | attr X | | attr 1 | |--------| + INCOMP + +--------+ |--------| | attr B | +--------+ | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr W | | attr n | +--------+ +--------+ And now we have the new (incomplete) attribute @ L4:0, and the original attribute at L3:0. At this point, the first transaction is committed, and we move to the flipping of the flags. This is where we are supposed to end up with this: +--------+ +--------+ +--------+ +--------+ | L1 | | L4 | | L3 | | L2 | | fwd: 4 |---->| fwd: 3 |---->| fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 |<----| bwd: 4 |<----| bwd: 3 | | fsp: M | | fsp: J | | fsp: J | | fsp: N | |--------| |--------| |--------| |--------| | attr A | | attr Y | | attr X | | attr 1 | |--------| +--------+ + INCOMP + |--------| | attr B | +--------+ | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr W | | attr n | +--------+ +--------+ But that doesn't happen properly - the attribute tracking indexes are not pointing to the right locations. What we end up with is both the old attribute to be removed pointing at L4:0 and the new attribute at L4:1. On a debug kernel, this assert fails like so: XFS: Assertion failed: args->index2 < be16_to_cpu(leaf2->hdr.count), file: fs/xfs/xfs_attr_leaf.c, line: 2725 because the new attribute location does not exist. On a production kernel, this goes unnoticed and the code proceeds ahead merrily and removes L4 because it thinks that is the block that is no longer needed. This leaves the hash index node pointing to entries L1, L4 and L2, but only blocks L1, L3 and L2 to exist. Further, the leaf level sibling list is L1 <-> L4 <-> L2, but L4 is now free space, and so everything is busted. This corruption is caused by the removal of the old attribute triggering a join - it joins everything correctly but then frees the wrong block. xfs_repair will report something like: bad sibling back pointer for block 4 in attribute fork for inode 131 problem with attribute contents in inode 131 would clear attr fork bad nblocks 8 for inode 131, would reset to 3 bad anextents 4 for inode 131, would reset to 0 The problem lies in the assignment of the old/new blocks for tracking purposes when the double leaf split occurs. The first split tries to place the new attribute inside the current leaf (i.e. "inleaf == true") and moves the old attribute (X) to the new block. This sets up the old block/index to L1:X, and newly allocated block to L3:0. It then moves attr X to the new block and tries to insert attr Y at the old index. That fails, so it splits again. With the second split, the rebalance ends up placing the new attr in the second new block - L4:0 - and this is where the code goes wrong. What is does is it sets both the new and old block index to the second new block. Hence it inserts attr Y at the right place (L4:0) but overwrites the current location of the attr to replace that is held in the new block index (currently L3:0). It over writes it with L4:1 - the index we later assert fail on. Hopefully this table will show this in a foramt that is a bit easier to understand: Split old attr index new attr index vanilla patched vanilla patched before 1st L1:26 L1:26 N/A N/A after 1st L3:0 L3:0 L1:26 L1:26 after 2nd L4:0 L3:0 L4:1 L4:0 ^^^^ ^^^^ wrong wrong The fix is surprisingly simple, for all this analysis - just stop the rebalance on the out-of leaf case from overwriting the new attr index - it's already correct for the double split case. Signed-off-by: Dave Chinner Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_attr_leaf.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index d330111..70eec18 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -1291,6 +1291,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, leaf2 = blk2->bp->b_addr; ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); + ASSERT(leaf2->hdr.count == 0); args = state->args; trace_xfs_attr_leaf_rebalance(args); @@ -1361,6 +1362,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * I assert that since all callers pass in an empty * second buffer, this code should never execute. */ + ASSERT(0); /* * Figure the total bytes to be added to the destination leaf. @@ -1422,10 +1424,24 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, args->index2 = 0; args->blkno2 = blk2->blkno; } else { + /* + * On a double leaf split, the original attr location + * is already stored in blkno2/index2, so don't + * overwrite it overwise we corrupt the tree. + */ blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); - args->index = args->index2 = blk2->index; - args->blkno = args->blkno2 = blk2->blkno; + args->index = blk2->index; + args->blkno = blk2->blkno; + if (!state->extravalid) { + /* + * set the new attr location to match the old + * one and let the higher level split code + * decide where in the leaf to place it. + */ + args->index2 = blk2->index; + args->blkno2 = blk2->blkno; + } } } else { ASSERT(state->inleaf == 1); -- cgit v1.1 From 3daed8bc3e49b9695ae931b9f472b5b90d1965b3 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 12 Nov 2012 22:09:45 +1100 Subject: xfs: fix broken error handling in xfs_vm_writepage When we shut down the filesystem, it might first be detected in writeback when we are allocating a inode size transaction. This happens after we have moved all the pages into the writeback state and unlocked them. Unfortunately, if we fail to set up the transaction we then abort writeback and try to invalidate the current page. This then triggers are BUG() in block_invalidatepage() because we are trying to invalidate an unlocked page. Fixing this is a bit of a chicken and egg problem - we can't allocate the transaction until we've clustered all the pages into the IO and we know the size of it (i.e. whether the last block of the IO is beyond the current EOF or not). However, we don't want to hold pages locked for long periods of time, especially while we lock other pages to cluster them into the write. To fix this, we need to make a clear delineation in writeback where errors can only be handled by IO completion processing. That is, once we have marked a page for writeback and unlocked it, we have to report errors via IO completion because we've already started the IO. We may not have submitted any IO, but we've changed the page state to indicate that it is under IO so we must now use the IO completion path to report errors. To do this, add an error field to xfs_submit_ioend() to pass it the error that occurred during the building on the ioend chain. When this is non-zero, mark each ioend with the error and call xfs_finish_ioend() directly rather than building bios. This will immediately push the ioends through completion processing with the error that has occurred. Signed-off-by: Dave Chinner Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_aops.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e562dd4..e57e2da 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh) * * The fix is two passes across the ioend list - one to start writeback on the * buffer_heads, and then submit them for I/O on the second pass. + * + * If @fail is non-zero, it means that we have a situation where some part of + * the submission process has failed after we have marked paged for writeback + * and unlocked them. In this situation, we need to fail the ioend chain rather + * than submit it to IO. This typically only happens on a filesystem shutdown. */ STATIC void xfs_submit_ioend( struct writeback_control *wbc, - xfs_ioend_t *ioend) + xfs_ioend_t *ioend, + int fail) { xfs_ioend_t *head = ioend; xfs_ioend_t *next; @@ -506,6 +512,18 @@ xfs_submit_ioend( next = ioend->io_list; bio = NULL; + /* + * If we are failing the IO now, just mark the ioend with an + * error and finish it. This will run IO completion immediately + * as there is only one reference to the ioend at this point in + * time. + */ + if (fail) { + ioend->io_error = -fail; + xfs_finish_ioend(ioend); + continue; + } + for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { if (!bio) { @@ -1060,7 +1078,18 @@ xfs_vm_writepage( xfs_start_page_writeback(page, 1, count); - if (ioend && imap_valid) { + /* if there is no IO to be submitted for this page, we are done */ + if (!ioend) + return 0; + + ASSERT(iohead); + + /* + * Any errors from this point onwards need tobe reported through the IO + * completion path as we have marked the initial page as under writeback + * and unlocked it. + */ + if (imap_valid) { xfs_off_t end_index; end_index = imap.br_startoff + imap.br_blockcount; @@ -1079,20 +1108,15 @@ xfs_vm_writepage( wbc, end_index); } - if (iohead) { - /* - * Reserve log space if we might write beyond the on-disk - * inode size. - */ - if (ioend->io_type != XFS_IO_UNWRITTEN && - xfs_ioend_is_append(ioend)) { - err = xfs_setfilesize_trans_alloc(ioend); - if (err) - goto error; - } - xfs_submit_ioend(wbc, iohead); - } + /* + * Reserve log space if we might write beyond the on-disk inode size. + */ + err = 0; + if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend)) + err = xfs_setfilesize_trans_alloc(ioend); + + xfs_submit_ioend(wbc, iohead, err); return 0; -- cgit v1.1 From d69043c42d8c6414fa28ad18d99973aa6c1c2e24 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 12 Nov 2012 22:09:46 +1100 Subject: xfs: drop buffer io reference when a bad bio is built Error handling in xfs_buf_ioapply_map() does not handle IO reference counts correctly. We increment the b_io_remaining count before building the bio, but then fail to decrement it in the failure case. This leads to the buffer never running IO completion and releasing the reference that the IO holds, so at unmount we can leak the buffer. This leak is captured by this assert failure during unmount: XFS: Assertion failed: atomic_read(&pag->pag_ref) == 0, file: fs/xfs/xfs_mount.c, line: 273 This is not a new bug - the b_io_remaining accounting has had this problem for a long, long time - it's just very hard to get a zero length bio being built by this code... Further, the buffer IO error can be overwritten on a multi-segment buffer by subsequent bio completions for partial sections of the buffer. Hence we should only set the buffer error status if the buffer is not already carrying an error status. This ensures that a partial IO error on a multi-segment buffer will not be lost. This part of the problem is a regression, however. cc: Signed-off-by: Dave Chinner Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_buf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 933b793..4b0b8dd 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1197,9 +1197,14 @@ xfs_buf_bio_end_io( { xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; - xfs_buf_ioerror(bp, -error); + /* + * don't overwrite existing errors - otherwise we can lose errors on + * buffers that require multiple bios to complete. + */ + if (!bp->b_error) + xfs_buf_ioerror(bp, -error); - if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) + if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); _xfs_buf_ioend(bp, 1); @@ -1279,6 +1284,11 @@ next_chunk: if (size) goto next_chunk; } else { + /* + * This is guaranteed not to be the last io reference count + * because the caller (xfs_buf_iorequest) holds a count itself. + */ + atomic_dec(&bp->b_io_remaining); xfs_buf_ioerror(bp, EIO); bio_put(bio); } -- cgit v1.1 From e91337609afdfaa1936c91b519ba7d7e426814cc Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Sun, 28 Oct 2012 12:23:24 +0000 Subject: mvebu-gpio: Disable blinking when enabling a GPIO for output The plat-orion GPIO driver would disable any pin blinking whenever using a pin for output. Do the same here, as a blinking LED will continue to blink regardless of what the GPIO pin level is. Signed-off-by: Jamie Lentin Acked-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index cf7afb9..be65c04 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) return mvchip->membase + GPIO_OUT_OFF; } +static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) +{ + return mvchip->membase + GPIO_BLINK_EN_OFF; +} + static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_IO_CONF_OFF; @@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) return (u >> pin) & 1; } +static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) +{ + struct mvebu_gpio_chip *mvchip = + container_of(chip, struct mvebu_gpio_chip, chip); + unsigned long flags; + u32 u; + + spin_lock_irqsave(&mvchip->lock, flags); + u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); + if (value) + u |= 1 << pin; + else + u &= ~(1 << pin); + writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); + spin_unlock_irqrestore(&mvchip->lock, flags); +} + static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) { struct mvebu_gpio_chip *mvchip = @@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, if (ret) return ret; + mvebu_gpio_blink(chip, pin, 0); mvebu_gpio_set(chip, pin, value); spin_lock_irqsave(&mvchip->lock, flags); -- cgit v1.1 From cb144fe8e0e70ccb12e93c9c9f010a25b3f2a158 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 1 Nov 2012 11:22:11 +0100 Subject: gpio: adnp: Depend on OF_GPIO instead of OF The driver accesses the of_node field of struct gpio_chip, which is only available if OF_GPIO is selected. This solves a build issue on SPARC which conflicts with OF_GPIO and therefore does not provide this field. Signed-off-by: Thierry Reding Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f11d8e3..47150f5 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ config GPIO_ADNP tristate "Avionic Design N-bit GPIO expander" - depends on I2C && OF + depends on I2C && OF_GPIO help This option enables support for N GPIOs found on Avionic Design I2C GPIO expanders. The register space will be extended by powers -- cgit v1.1 From cbf24fad8e6e97b7cd7dd1099f5b801689dc234a Mon Sep 17 00:00:00 2001 From: "Daniel M. Weeks" Date: Tue, 6 Nov 2012 23:51:05 -0500 Subject: gpio-mcp23s08: Build I2C support even when CONFIG_I2C=m The driver has both SPI and I2C pieces. The appropriate pieces are built based on whether SPI and/or I2C is/are enabled. However, it was only checking if I2C was built-in, never if it was built as a module. This patch checks for either since building both this driver and I2C as modules is possible. Signed-off-by: Daniel M. Weeks Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f42518..ce1c847 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -77,7 +77,7 @@ struct mcp23s08_driver_data { /*----------------------------------------------------------------------*/ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) { @@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, break; #endif /* CONFIG_SPI_MASTER */ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) case MCP_TYPE_008: mcp->ops = &mcp23008_ops; mcp->chip.ngpio = 8; @@ -473,7 +473,7 @@ fail: /*----------------------------------------------------------------------*/ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) static int __devinit mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id) -- cgit v1.1 From 34fa78b59c52d1db3513db4c1a999db26b2e9ac2 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 17 Nov 2012 22:27:04 +0100 Subject: m68k: fix sigset_t accessor functions The sigaddset/sigdelset/sigismember functions that are implemented with bitfield insn cannot allow the sigset argument to be placed in a data register since the sigset is wider than 32 bits. Remove the "d" constraint from the asm statements. The effect of the bug is that sending RT signals does not work, the signal number is truncated modulo 32. Signed-off-by: Andreas Schwab Signed-off-by: Geert Uytterhoeven Cc: stable@vger.kernel.org --- arch/m68k/include/asm/signal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h index 67e489d..2df26b5 100644 --- a/arch/m68k/include/asm/signal.h +++ b/arch/m68k/include/asm/signal.h @@ -41,7 +41,7 @@ struct k_sigaction { static inline void sigaddset(sigset_t *set, int _sig) { asm ("bfset %0{%1,#1}" - : "+od" (*set) + : "+o" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig) static inline void sigdelset(sigset_t *set, int _sig) { asm ("bfclr %0{%1,#1}" - : "+od" (*set) + : "+o" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) int ret; asm ("bfextu %1{%2,#1},%0" : "=d" (ret) - : "od" (*set), "id" ((_sig-1) ^ 31) + : "o" (*set), "id" ((_sig-1) ^ 31) : "cc"); return ret; } -- cgit v1.1 From e1b69fdf33f63cfa600b992172d7376f9d9ef2e9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 15 Oct 2012 17:57:36 +0200 Subject: iwlwifi: don't WARN when a non empty queue is disabled This can happen when we shut down suddenly an interface. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 105e3af..79a4ddc 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 rd_ptr, wr_ptr; - int n_bd = trans_pcie->txq[txq_id].q.n_bd; if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { WARN_ONCE(1, "queue %d not used", txq_id); return; } - rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); - wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); - - WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", - txq_id, rd_ptr, wr_ptr); - iwl_txq_set_inactive(trans, txq_id); IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); } -- cgit v1.1 From e99ddfde6ae0dd2662bb40435696002b590e4057 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 31 Oct 2012 16:35:30 +0100 Subject: ALSA: ua101, usx2y: fix broken MIDI output Commit 88a8516a2128 (ALSA: usbaudio: implement USB autosuspend) added autosuspend code to all files making up the snd-usb-audio driver. However, midi.c is part of snd-usb-lib and is also used by other drivers, not all of which support autosuspend. Thus, calls to usb_autopm_get_interface() could fail, and this unexpected error would result in the MIDI output being completely unusable. Make it work by ignoring the error that is expected with drivers that do not support autosuspend. Reported-by: Colin Fletcher Reported-by: Devin Venable Reported-by: Dr Nick Bailey Reported-by: Jannis Achstetter Reported-by: Rui Nuno Capela Cc: Oliver Neukum Cc: 2.6.39+ Signed-off-by: Clemens Ladisch --- sound/usb/midi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/usb/midi.c b/sound/usb/midi.c index c83f614..eeefbce 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint { struct snd_usb_midi_out_endpoint* ep; struct snd_rawmidi_substream *substream; int active; + bool autopm_reference; uint8_t cable; /* cable number << 4 */ uint8_t state; #define STATE_UNKNOWN 0 @@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) return -ENXIO; } err = usb_autopm_get_interface(umidi->iface); - if (err < 0) + port->autopm_reference = err >= 0; + if (err < 0 && err != -EACCES) return -EIO; substream->runtime->private_data = port; port->state = STATE_UNKNOWN; @@ -1087,9 +1089,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) { struct snd_usb_midi* umidi = substream->rmidi->private_data; + struct usbmidi_out_port *port = substream->runtime->private_data; substream_open(substream, 0); - usb_autopm_put_interface(umidi->iface); + if (port->autopm_reference) + usb_autopm_put_interface(umidi->iface); return 0; } -- cgit v1.1 From 3587b1b097d70c2eb9fee95ea7995d13c05f66e5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Nov 2012 19:19:00 +0000 Subject: fanotify: fix FAN_Q_OVERFLOW case of fanotify_read() If the FAN_Q_OVERFLOW bit set in event->mask, the fanotify event metadata will not contain a valid file descriptor, but copy_event_to_user() didn't check for that, and unconditionally does a fd_install() on the file descriptor. Which in turn will cause a BUG_ON() in __fd_install(). Introduced by commit 352e3b249284 ("fanotify: sanitize failure exits in copy_event_to_user()") Mea culpa - missed that path ;-/ Reported-by: Alex Shi Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- fs/notify/fanotify/fanotify_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 721d692..6fcaeb8 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -258,7 +258,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, if (ret) goto out_close_fd; - fd_install(fd, f); + if (fd != FAN_NOFD) + fd_install(fd, f); return fanotify_event_metadata.event_len; out_close_fd: -- cgit v1.1 From 4113014f2d7bef992ed373c30b6b4ba4be6969ea Mon Sep 17 00:00:00 2001 From: Kelly Doran Date: Thu, 15 Nov 2012 14:37:28 +1000 Subject: drm/nvc0/disp: fix thinko in vblank regression fix.. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 05a909a..15b182c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) if (chan->vblank.crtc != crtc) continue; - if (nv_device(priv)->chipset == 0x50) { - nv_wr32(priv, 0x001704, chan->vblank.channel); - nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); - bar->flush(bar); - nv_wr32(priv, 0x001570, chan->vblank.offset); - nv_wr32(priv, 0x001574, chan->vblank.value); - } else { + if (nv_device(priv)->chipset >= 0xc0) { nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); bar->flush(bar); nv_wr32(priv, 0x06000c, @@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060014, chan->vblank.value); + } else { + nv_wr32(priv, 0x001704, chan->vblank.channel); + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); + bar->flush(bar); + if (nv_device(priv)->chipset == 0x50) { + nv_wr32(priv, 0x001570, chan->vblank.offset); + nv_wr32(priv, 0x001574, chan->vblank.value); + } else { + nv_wr32(priv, 0x060010, chan->vblank.offset); + nv_wr32(priv, 0x060014, chan->vblank.value); + } } list_del(&chan->vblank.head); -- cgit v1.1 From 1f150b3e7a722ebfc68eec5d83a9fe1ee8d75d71 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 11 Nov 2012 19:58:52 +0100 Subject: drm/nv40: allocate ctxprog with kmalloc Some archs defconfigs have CONFIG_FRAME_WARN set to 1024, which lead to this warning: drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c: warning: the frame size of 1184 bytes is larger than 1024 bytes Reported-by: Geert Uytterhoeven Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c | 12 +++++++++--- drivers/gpu/drm/nouveau/core/engine/graph/nv40.c | 4 +++- drivers/gpu/drm/nouveau/core/engine/graph/nv40.h | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c index e45035e..7bbb1e1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c @@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) }); } -void +int nv40_grctx_init(struct nouveau_device *device, u32 *size) { - u32 ctxprog[256], i; + u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i; struct nouveau_grctx ctx = { .device = device, .mode = NOUVEAU_GRCTX_PROG, .data = ctxprog, - .ctxprog_max = ARRAY_SIZE(ctxprog) + .ctxprog_max = 256, }; + if (!ctxprog) + return -ENOMEM; + nv40_grctx_generate(&ctx); nv_wr32(device, 0x400324, 0); for (i = 0; i < ctx.ctxprog_len; i++) nv_wr32(device, 0x400328, ctxprog[i]); *size = ctx.ctxvals_pos * 4; + + kfree(ctxprog); + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 4250012..cc6574e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object) return ret; /* generate and upload context program */ - nv40_grctx_init(nv_device(priv), &priv->size); + ret = nv40_grctx_init(nv_device(priv), &priv->size); + if (ret) + return ret; /* No context present currently */ nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h index d2ac975..7da35a4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h @@ -15,7 +15,7 @@ nv44_graph_class(void *priv) return !(0x0baf & (1 << (device->chipset & 0x0f))); } -void nv40_grctx_init(struct nouveau_device *, u32 *size); +int nv40_grctx_init(struct nouveau_device *, u32 *size); void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); #endif -- cgit v1.1 From bf7e438bcaff4b732f86bb2eb48fc4fee04dc31b Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 11 Nov 2012 20:00:09 +0100 Subject: drm/nouveau: fix crash with noaccel=1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Ortwin Glück Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_abi16.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index cc79c79..cbf1fc6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) if (unlikely(!abi16)) return -ENOMEM; + + if (!drm->channel) + return nouveau_abi16_put(abi16, -ENODEV); + client = nv_client(abi16->client); if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) -- cgit v1.1 From d9c390561d1c4e520773e62781bbf89bb6845353 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 16 Nov 2012 17:47:16 +0100 Subject: drm/nouveau: add missing pll_calc calls Fixes a null pointer dereference when reclocking on my fermi. Signed-off-by: Maarten Lankhorst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/include/subdev/clock.h | 3 ++- drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c | 19 +++++++++++++++++++ drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 39e73b9..41b7a6a 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h @@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, int clk, struct nouveau_pll_vals *); int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, struct nouveau_pll_vals *); - +int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, + int clk, struct nouveau_pll_vals *); #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index cc8d7d1..9068c98 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c @@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) return ret; } +int +nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, + int clk, struct nouveau_pll_vals *pv) +{ + int ret, N, M, P; + + ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P); + + if (ret > 0) { + pv->refclk = info->refclk; + pv->N1 = N; + pv->M1 = M; + pv->log2P = P; + } + return ret; +} + + static int nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.pll_set = nva3_clock_pll_set; + priv->base.pll_calc = nva3_clock_pll_calc; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index 5ccce0b..f6962c9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.pll_set = nvc0_clock_pll_set; + priv->base.pll_calc = nva3_clock_pll_calc; return 0; } -- cgit v1.1 From 3bb076af2ae571a48465972d5747175cec3564cd Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sat, 17 Nov 2012 21:33:15 +0100 Subject: drm/nouveau/bios: fix DCB v1.5 parsing memcmp->nv_strncmp conversion, in addition to name change, should have inverted the return value. But nv_strncmp does not act like strncmp - it does not check for string terminator, returns true/false instead of -1/0/1 and has different parameters order. Let's rename it to nv_memcmp and let it act like memcmp. Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/include/core/object.h | 14 +++++++++----- drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h index 818feab..486f1a9 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h @@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data) return temp; } -static inline bool -nv_strncmp(void *obj, u32 addr, u32 len, const char *str) +static inline int +nv_memcmp(void *obj, u32 addr, const char *str, u32 len) { + unsigned char c1, c2; + while (len--) { - if (nv_ro08(obj, addr++) != *(str++)) - return false; + c1 = nv_ro08(obj, addr++); + c2 = *(str++); + if (c1 != c2) + return c1 - c2; } - return true; + return 0; } #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 7d75038..c511971 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c @@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) } } else if (*ver >= 0x15) { - if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) { + if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) { u16 i2c = nv_ro16(bios, dcb + 2); *hdr = 4; *cnt = (i2c - dcb) / 10; -- cgit v1.1 From 8495c0da20bc496ac9d5da2b292adb28f61d2713 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sun, 18 Nov 2012 23:41:50 +0100 Subject: sis900: fix sis900_set_mode call parameters. Leftover of 57d6d456cfb89264f87d24f52640ede23fdf12bd ("sis900: stop using net_device.{base_addr, irq} and convert to __iomem."). It is needed for suspend / resume to work. Signed-off-by: Francois Romieu Tested-by: Jan Janssen Cc: Daniele Venzano Signed-off-by: David S. Miller --- drivers/net/ethernet/sis/sis900.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index fb9f6b3..edf5edb 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev) netif_start_queue(net_dev); /* Workaround for EDB */ - sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); + sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); /* Enable all known interrupts by setting the interrupt mask. */ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); -- cgit v1.1 From fae2ae2a900a5c7bb385fe4075f343e7e2d5daa2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Nov 2012 22:27:03 -0500 Subject: sparc64: not any error from do_sigaltstack() should fail rt_sigreturn() If a signal handler is executed on altstack and another signal comes, we will end up with rt_sigreturn() on return from the second handler getting -EPERM from do_sigaltstack(). It's perfectly OK, since we are not asking to change the settings; in fact, they couldn't have been changed during the second handler execution exactly because we'd been on altstack all along. 64bit sigreturn on sparc treats any error from do_sigaltstack() as "SIGSEGV now"; we need to switch to the same semantics we are using on other architectures. Cc: stable@vger.kernel.org Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/kernel/signal_64.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 867de2f..689e1ba 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); - - if (err) + if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) goto segv; err |= __get_user(rwin_save, &sf->rwin_save); -- cgit v1.1 From c91cb7a75eaf65358aac5ea2b512ac60a9437ff4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 16 Nov 2012 09:14:12 -0800 Subject: Input: mousedev - move /dev/input/mice to the correct minor When doing conversion to dynamic input numbers I inadvertently moved /dev/input/mice from c,13,63 to c,13,31. We need to fix this so that setups with statically populated /dev continue working. Tested-by: Krzysztof Mazur Tested-by: Pavel Machek Signed-off-by: Dmitry Torokhov --- drivers/input/mousedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 8f02e3d..4c842c3 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -12,8 +12,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define MOUSEDEV_MINOR_BASE 32 -#define MOUSEDEV_MINORS 32 -#define MOUSEDEV_MIX 31 +#define MOUSEDEV_MINORS 31 +#define MOUSEDEV_MIX 63 #include #include -- cgit v1.1 From e37212aa5df1937bc19c0d0982d216675020a7ca Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Wed, 3 Oct 2012 12:05:00 +0530 Subject: ARM: davinci: dm644x: fix out range signal for ED Fix the video clock setting when custom timings are used with pclock <= 27MHz. Existing video clock selection uses PLL2 mode which results in a 54MHz clock whereas using the MXI mode results in a 27MHz clock (which is the one actually desired). This bug affects the Enhanced Definition (ED) support on DM644x. Without this patch, out-range signals errors are were observed on the TV when viewing ED. An out-of-range signal is often caused when the field rate is above the rate that the television will handle. Signed-off-by: Lad, Prabhakar Signed-off-by: Manjunath Hadli Cc: Sekhar Nori [nsekhar@ti.com: reword commit message based on on-list discussion] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/dm644x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index cd0c8b1..14e9947 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, break; case VPBE_ENC_CUSTOM_TIMINGS: if (pclock <= 27000000) { - v |= DM644X_VPSS_MUXSEL_PLL2_MODE | - DM644X_VPSS_DACCLKEN; + v |= DM644X_VPSS_DACCLKEN; writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); } else { /* -- cgit v1.1 From c415187b689842e8bb85135c070c822c2505f805 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Mon, 19 Nov 2012 10:40:15 +0530 Subject: OMAPFB: Fix possible null pointer dereferencing Commit 952cbaaa9b8beacc425f9aedf370468cbb737a2c (OMAPFB: Change dssdev->manager references) added checks for OMAPFB_WAITFORVSYNC ioctl to verify that the display, output and overlay manager exist. However, the code erroneously uses && for each part, which means that OMAPFB_WAITFORVSYNC may crash the kernel if no display, output or manager is associated with the framebuffer. This patch fixes the issue by using ||. Signed-off-by: Tushar Behera Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 606b89f..d630b26 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) case OMAPFB_WAITFORVSYNC: DBG("ioctl WAITFORVSYNC\n"); - if (!display && !display->output && !display->output->manager) { + if (!display || !display->output || !display->output->manager) { r = -EINVAL; break; } -- cgit v1.1 From 963f2076e3b4d62e219b3fa60de7b50e335f5783 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Mon, 19 Nov 2012 15:48:46 +0530 Subject: i2c: s3c2410: Fix code to free gpios Store the requested gpios so that they can be freed on error/removal. Signed-off-by: Abhilash Kesavan Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-s3c2410.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3e0335f..9d90272 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); goto free_gpio; } + i2c->gpios[idx] = gpio; ret = gpio_request(gpio, "i2c-bus"); if (ret) { -- cgit v1.1 From 989c3187156ad197ae473fa9d9d506eef9624f12 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Nov 2012 14:14:58 +0100 Subject: ALSA: hda - Fix recursive suspend/resume call When the bus reset is performed during the suspend/resume (including the power-saving too), it calls snd_hda_suspend() and snd_hda_resume() again, and deadlocks eventually. For avoiding the recursive call, add a new flag indicating that the PM is being performed, and don't go to the bus reset mode when it's on. Reported-and-tested-by: Julian Wollrath Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 11 +++++++++-- sound/pci/hda/hda_codec.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 70d4848..cebe2dfd 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -228,7 +228,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, } mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); - if (res && *res == -1 && bus->rirb_error) { + if (!codec->in_pm && res && *res == -1 && bus->rirb_error) { if (bus->response_reset) { snd_printd("hda_codec: resetting BUS due to " "fatal communication error\n"); @@ -238,7 +238,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, goto again; } /* clear reset-flag when the communication gets recovered */ - if (!err) + if (!err || codec->in_pm) bus->response_reset = 0; return err; } @@ -3616,6 +3616,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) { unsigned int state; + codec->in_pm = 1; + if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec); hda_cleanup_all_streams(codec); @@ -3630,6 +3632,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) codec->power_transition = 0; codec->power_jiffies = jiffies; spin_unlock(&codec->power_lock); + codec->in_pm = 0; return state; } @@ -3638,6 +3641,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) */ static void hda_call_codec_resume(struct hda_codec *codec) { + codec->in_pm = 1; + /* set as if powered on for avoiding re-entering the resume * in the resume / power-save sequence */ @@ -3656,6 +3661,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) snd_hda_codec_resume_cache(codec); } snd_hda_jack_report_sync(codec); + + codec->in_pm = 0; snd_hda_power_down(codec); /* flag down before returning */ } #endif /* CONFIG_PM */ diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 507fe8a..4f4e545 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -869,6 +869,7 @@ struct hda_codec { unsigned int power_on :1; /* current (global) power-state */ unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ unsigned int pm_down_notified:1; /* PM notified to controller */ + unsigned int in_pm:1; /* suspend/resume being performed */ int power_transition; /* power-state in transition */ int power_count; /* current (global) power refcount */ struct delayed_work power_work; /* delayed task for powerdown */ -- cgit v1.1 From da8fb123b041e487d28f54d3a77a15139cb9e3b9 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sat, 17 Nov 2012 21:20:50 +0530 Subject: ath9k_hw: Fix regression in device reset Commit "ath9k: improve suspend/resume reliability" broke ath9k_htc and bringing up the device would hang indefinitely. Fix this. Cc: stable@vger.kernel.org Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8e1559a..1829b44 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) switch (type) { case ATH9K_RESET_POWER_ON: ret = ath9k_hw_set_reset_power_on(ah); - if (!ret) + if (ret) ah->reset_power_on = true; break; case ATH9K_RESET_WARM: -- cgit v1.1 From 2ea3c6a2c779e5a6487d2b436770232162dfbbe3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Nov 2012 20:03:37 +0100 Subject: ALSA: hda - Limit runtime PM support only to known Intel chips We've got a report that the runtime PM may make the codec the unresponsive on AMD platforms. Since the feature has been tested only on the recent Intel platforms, it's safer to limit the support to such devices for now. This patch adds a new DCAPS bit flag indicating the runtime PM support, and mark it for Intel controllers. Reported-and-tested-by: Julian Wollrath Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cd2dbaf..f9d870e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -556,6 +556,12 @@ enum { #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ +#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ + +/* quirks for Intel PCH */ +#define AZX_DCAPS_INTEL_PCH \ + (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ + AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME) /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -2433,6 +2439,9 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up) { struct azx *chip = bus->private_data; + if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) + return; + if (power_up) pm_runtime_get_sync(&chip->pci->dev); else @@ -2548,7 +2557,8 @@ static int azx_runtime_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; - if (!power_save_controller) + if (!power_save_controller || + !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) return -EAGAIN; azx_stop_chip(chip); @@ -3429,39 +3439,30 @@ static void __devexit azx_remove(struct pci_dev *pci) static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* PBG */ { PCI_DEVICE(0x8086, 0x1d20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE}, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point */ { PCI_DEVICE(0x8086, 0x8c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c21), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Haswell */ { PCI_DEVICE(0x8086, 0x0c0c), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, { PCI_DEVICE(0x8086, 0x0d0c), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, /* 5 Series/3400 */ { PCI_DEVICE(0x8086, 0x3b56), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | -- cgit v1.1 From 3bb3e1fc47aca554e7e2cc4deeddc24750987ac2 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 14:55:52 +0100 Subject: reiserfs: Fix lock ordering during remount When remounting reiserfs dquot_suspend() or dquot_resume() can be called. These functions take dqonoff_mutex which ranks above write lock so we have to drop it before calling into quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 1078ae1..5372980 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1335,7 +1335,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) kfree(qf_names[i]); #endif err = -EINVAL; - goto out_err; + goto out_unlock; } #ifdef CONFIG_QUOTA handle_quota_files(s, qf_names, &qfmt); @@ -1379,7 +1379,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) if (blocks) { err = reiserfs_resize(s, blocks); if (err != 0) - goto out_err; + goto out_unlock; } if (*mount_flags & MS_RDONLY) { @@ -1389,9 +1389,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) /* it is read-only already */ goto out_ok; + /* + * Drop write lock. Quota will retake it when needed and lock + * ordering requires calling dquot_suspend() without it. + */ + reiserfs_write_unlock(s); err = dquot_suspend(s, -1); if (err < 0) goto out_err; + reiserfs_write_lock(s); /* try to remount file system with read-only permissions */ if (sb_umount_state(rs) == REISERFS_VALID_FS @@ -1401,7 +1407,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) err = journal_begin(&th, s, 10); if (err) - goto out_err; + goto out_unlock; /* Mounting a rw partition read-only. */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -1416,7 +1422,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) if (reiserfs_is_journal_aborted(journal)) { err = journal->j_errno; - goto out_err; + goto out_unlock; } handle_data_mode(s, mount_options); @@ -1425,7 +1431,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ err = journal_begin(&th, s, 10); if (err) - goto out_err; + goto out_unlock; /* Mount a partition which is read-only, read-write */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -1442,10 +1448,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) SB_JOURNAL(s)->j_must_wait = 1; err = journal_end(&th, s, 10); if (err) - goto out_err; + goto out_unlock; if (!(*mount_flags & MS_RDONLY)) { + /* + * Drop write lock. Quota will retake it when needed and lock + * ordering requires calling dquot_resume() without it. + */ + reiserfs_write_unlock(s); dquot_resume(s, -1); + reiserfs_write_lock(s); finish_unfinished(s); reiserfs_xattr_init(s, *mount_flags); } @@ -1455,9 +1467,10 @@ out_ok: reiserfs_write_unlock(s); return 0; +out_unlock: + reiserfs_write_unlock(s); out_err: kfree(new_opts); - reiserfs_write_unlock(s); return err; } -- cgit v1.1 From b9e06ef2e8706fe669b51f4364e3aeed58639eb2 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 16:34:17 +0100 Subject: reiserfs: Protect reiserfs_quota_on() with write lock In reiserfs_quota_on() we do quite some work - for example unpacking tail of a quota file. Thus we have to hold write lock until a moment we call back into the quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 5372980..e59d6dd 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2216,8 +2216,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, struct reiserfs_transaction_handle th; int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA; - if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) - return -EINVAL; + reiserfs_write_lock(sb); + if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) { + err = -EINVAL; + goto out; + } /* Quotafile not on the same filesystem? */ if (path->dentry->d_sb != sb) { @@ -2259,8 +2262,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (err) goto out; } - err = dquot_quota_on(sb, type, format_id, path); + reiserfs_write_unlock(sb); + return dquot_quota_on(sb, type, format_id, path); out: + reiserfs_write_unlock(sb); return err; } -- cgit v1.1 From 361d94a338a3fd0cee6a4ea32bbc427ba228e628 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 18:25:38 +0100 Subject: reiserfs: Protect reiserfs_quota_write() with write lock Calls into reiserfs journalling code and reiserfs_get_block() need to be protected with write lock. We remove write lock around calls to high level quota code in the next patch so these paths would suddently become unprotected. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index e59d6dd..c101704 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2338,7 +2338,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, tocopy = sb->s_blocksize - offset < towrite ? sb->s_blocksize - offset : towrite; tmp_bh.b_state = 0; + reiserfs_write_lock(sb); err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE); + reiserfs_write_unlock(sb); if (err) goto out; if (offset || tocopy != sb->s_blocksize) @@ -2354,10 +2356,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, flush_dcache_page(bh->b_page); set_buffer_uptodate(bh); unlock_buffer(bh); + reiserfs_write_lock(sb); reiserfs_prepare_for_journal(sb, bh, 1); journal_mark_dirty(current->journal_info, sb, bh); if (!journal_quota) reiserfs_add_ordered_list(inode, bh); + reiserfs_write_unlock(sb); brelse(bh); offset = 0; towrite -= tocopy; -- cgit v1.1 From 7af11686933726e99af22901d622f9e161404e6b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 17:05:14 +0100 Subject: reiserfs: Move quota calls out of write lock Calls into highlevel quota code cannot happen under the write lock. These calls take dqio_mutex which ranks above write lock. So drop write lock before calling back into quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/inode.c | 10 +++++++--- fs/reiserfs/stree.c | 4 ++++ fs/reiserfs/super.c | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f27f01a..d83736f 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - dquot_initialize(inode); + reiserfs_write_unlock(inode->i_sb); err = dquot_alloc_inode(inode); + reiserfs_write_lock(inode->i_sb); if (err) goto out_end_trans; if (!dir->i_nlink) { @@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, out_end_trans: journal_end(th, th->t_super, th->t_blocks_allocated); + reiserfs_write_unlock(inode->i_sb); /* Drop can be outside and it needs more credits so it's better to have it outside */ dquot_drop(inode); + reiserfs_write_lock(inode->i_sb); inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); @@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) /* must be turned off for recursive notify_change calls */ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); - depth = reiserfs_write_lock_once(inode->i_sb); if (is_quota_modification(inode, attr)) dquot_initialize(inode); - + depth = reiserfs_write_lock_once(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate @@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) error = journal_begin(&th, inode->i_sb, jbegin_count); if (error) goto out; + reiserfs_write_unlock_once(inode->i_sb, depth); error = dquot_transfer(inode, attr); + depth = reiserfs_write_lock_once(inode->i_sb); if (error) { journal_end(&th, inode->i_sb, jbegin_count); goto out; diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index f8afa4b..2f40a4c 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree key2type(&(key->on_disk_key))); #endif + reiserfs_write_unlock(inode->i_sb); retval = dquot_alloc_space_nodirty(inode, pasted_size); + reiserfs_write_lock(inode->i_sb); if (retval) { pathrelse(search_path); return retval; @@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, "reiserquota insert_item(): allocating %u id=%u type=%c", quota_bytes, inode->i_uid, head2type(ih)); #endif + reiserfs_write_unlock(inode->i_sb); /* We can't dirty inode here. It would be immediately written but * appropriate stat item isn't inserted yet... */ retval = dquot_alloc_space_nodirty(inode, quota_bytes); + reiserfs_write_lock(inode->i_sb); if (retval) { pathrelse(path); return retval; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c101704..418bdc3 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s) retval = remove_save_link_only(s, &save_link_key, 0); continue; } + reiserfs_write_unlock(s); dquot_initialize(inode); + reiserfs_write_lock(s); if (truncate && S_ISDIR(inode->i_mode)) { /* We got a truncate request for a dir which is impossible. @@ -2108,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot) REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (ret) goto out; + reiserfs_write_unlock(dquot->dq_sb); ret = dquot_commit(dquot); + reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; - out: +out: reiserfs_write_unlock(dquot->dq_sb); return ret; } @@ -2130,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (ret) goto out; + reiserfs_write_unlock(dquot->dq_sb); ret = dquot_acquire(dquot); + reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; - out: +out: reiserfs_write_unlock(dquot->dq_sb); return ret; } @@ -2150,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot) ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); + reiserfs_write_unlock(dquot->dq_sb); if (ret) { /* Release dquot anyway to avoid endless cycle in dqput() */ dquot_release(dquot); goto out; } ret = dquot_release(dquot); + reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; - out: reiserfs_write_unlock(dquot->dq_sb); +out: return ret; } @@ -2187,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type) ret = journal_begin(&th, sb, 2); if (ret) goto out; + reiserfs_write_unlock(sb); ret = dquot_commit_info(sb, type); + reiserfs_write_lock(sb); err = journal_end(&th, sb, 2); if (!ret && err) ret = err; - out: +out: reiserfs_write_unlock(sb); return ret; } -- cgit v1.1 From ae49eeec785025373e28dc24c8351c6bba688d99 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Thu, 11 Oct 2012 12:28:38 +0200 Subject: ext3: Avoid underflow of in ext3_trim_fs() Currently if len argument in ext3_trim_fs() is smaller than one block, the 'end' variable underflow. Avoid that by returning EINVAL if len is smaller than file system block. Also remove useless unlikely(). Signed-off-by: Lukas Czerner Signed-off-by: Jan Kara --- fs/ext3/balloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 7320a66..22548f5 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -2101,8 +2101,9 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range) end = start + (range->len >> sb->s_blocksize_bits) - 1; minlen = range->minlen >> sb->s_blocksize_bits; - if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) || - unlikely(start >= max_blks)) + if (minlen > EXT3_BLOCKS_PER_GROUP(sb) || + start >= max_blks || + range->len < sb->s_blocksize) return -EINVAL; if (end >= max_blks) end = max_blks - 1; -- cgit v1.1 From 16a78e9fed5e8baa8480ae3413f4328c4537c599 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Fri, 12 Oct 2012 15:25:43 +0200 Subject: NFC: Fix nfc_llcp_local chained list insertion list_add was called with swapped parameters Signed-off-by: Thierry Escande Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index cc10d07..9e8f4b2 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - list_add(&llcp_devices, &local->list); + list_add(&local->list, &llcp_devices); return 0; } -- cgit v1.1 From 60ad07ab6bc86f48b6ebda1788d79ca5f88d824c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 25 Oct 2012 17:29:45 +0200 Subject: NFC: pn533: Fix missing lock while operating on commands list In pn533_wq_cmd command was removed from list without cmd_lock held (race with pn533_send_cmd_frame_async) which could lead to list corruption. Delete command from list before releasing lock. Signed-off-by: Szymon Janc Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 97c440a..328f2b6 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work) cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); + list_del(&cmd->queue); + mutex_unlock(&dev->cmd_lock); __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, cmd->in_frame_len, cmd->cmd_complete, cmd->arg, cmd->flags); - list_del(&cmd->queue); kfree(cmd); } -- cgit v1.1 From 770f750bc2b8312489c8e45306f551d08a319d3c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 29 Oct 2012 14:04:43 +0100 Subject: NFC: pn533: Fix use after free cmd was freed in pn533_dep_link_up regardless of pn533_send_cmd_frame_async return code. Cmd is passed as argument to pn533_in_dep_link_up_complete callback and should be freed there. Signed-off-by: Szymon Janc Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 328f2b6..84a2e77 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1820,12 +1820,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, dev->in_maxlen, pn533_in_dep_link_up_complete, cmd, GFP_KERNEL); - if (rc) - goto out; - - -out: - kfree(cmd); + if (rc < 0) + kfree(cmd); return rc; } -- cgit v1.1 From 70418e6efcf4f8652cc08e3f2ab8ae35f0948fd9 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Thu, 11 Oct 2012 14:04:00 +0200 Subject: NFC: pn533: Fix mem leak in pn533_in_dep_link_up cmd is allocated in pn533_dep_link_up and passed as an arg to pn533_send_cmd_frame_async together with a complete cb. arg is passed to the cb and must be kfreed there. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 84a2e77..807bbb8 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1679,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { - struct pn533_cmd_jump_dep *cmd; struct pn533_cmd_jump_dep_response *resp; struct nfc_target nfc_target; u8 target_gt_len; int rc; + struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; + u8 active = cmd->active; + + kfree(arg); if (params_len == -ENOENT) { nfc_dev_dbg(&dev->interface->dev, ""); @@ -1705,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, } resp = (struct pn533_cmd_jump_dep_response *) params; - cmd = (struct pn533_cmd_jump_dep *) arg; rc = resp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, @@ -1735,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, if (rc == 0) rc = nfc_dep_link_is_up(dev->nfc_dev, dev->nfc_dev->targets[0].idx, - !cmd->active, NFC_RF_INITIATOR); + !active, NFC_RF_INITIATOR); return 0; } -- cgit v1.1 From 5b412fd11c918171c98a253d8a3484afa9f69ca5 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Thu, 15 Nov 2012 18:24:28 +0100 Subject: NFC: Fix pn533 target mode memory leak In target mode, sent sk_buff were not freed in pn533_tm_send_complete Signed-off-by: Thierry Escande Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 807bbb8..30ae18a 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -2077,8 +2077,12 @@ error: static int pn533_tm_send_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { + struct sk_buff *skb_out = arg; + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + dev_kfree_skb(skb_out); + if (params_len < 0) { nfc_dev_err(&dev->interface->dev, "Error %d when sending data", @@ -2116,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, dev->in_maxlen, pn533_tm_send_complete, - NULL, GFP_KERNEL); + skb, GFP_KERNEL); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); -- cgit v1.1 From ab05613a0646dcc11049692d54bae76ca9ffa910 Mon Sep 17 00:00:00 2001 From: majianpeng Date: Tue, 6 Nov 2012 17:13:44 +0800 Subject: md: Reassigned the parameters if read_seqretry returned true in func md_is_badblock. This bug was introduced by commit(v3.0-rc7-126-g2230dfe). So fix is suitable for 3.0.y thru 3.6.y. Cc: stable@vger.kernel.org Signed-off-by: Jianpeng Ma Signed-off-by: NeilBrown --- drivers/md/md.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ab768a..14db6ab 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7936,9 +7936,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, sector_t *first_bad, int *bad_sectors) { int hi; - int lo = 0; + int lo; u64 *p = bb->page; - int rv = 0; + int rv; sector_t target = s + sectors; unsigned seq; @@ -7953,7 +7953,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, retry: seq = read_seqbegin(&bb->lock); - + lo = 0; + rv = 0; hi = bb->count; /* Binary search between lo and hi for 'target' -- cgit v1.1 From 35f9ac2dcec8f79d7059ce174fd7b7ee3290d620 Mon Sep 17 00:00:00 2001 From: majianpeng Date: Thu, 8 Nov 2012 08:56:27 +0800 Subject: md: Avoid write invalid address if read_seqretry returned true. If read_seqretry returned true and bbp was changed, it will write invalid address which can cause some serious problem. This bug was introduced by commit v3.0-rc7-130-g2699b67. So fix is suitable for 3.0.y thru 3.6.y. Reported-by: zhuwenfeng@kedacom.com Tested-by: zhuwenfeng@kedacom.com Cc: stable@vger.kernel.org Signed-off-by: Jianpeng Ma Signed-off-by: NeilBrown --- drivers/md/md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 14db6ab..4c7d880 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1817,10 +1817,10 @@ retry: memset(bbp, 0xff, PAGE_SIZE); for (i = 0 ; i < bb->count ; i++) { - u64 internal_bb = *p++; + u64 internal_bb = p[i]; u64 store_bb = ((BB_OFFSET(internal_bb) << 10) | BB_LEN(internal_bb)); - *bbp++ = cpu_to_le64(store_bb); + bbp[i] = cpu_to_le64(store_bb); } bb->changed = 0; if (read_seqretry(&bb->lock, seq)) -- cgit v1.1 From 5eff3c439d3478ba9e8ba5f8c0aaf6e6fadb6e58 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 19 Nov 2012 10:47:48 +1100 Subject: md: make sure everything is freed when dm-raid stops an array. md_stop() would stop an array, but not free various attached data structures. For internal arrays, these are freed later in do_md_stop() or mddev_put(), but they don't apply for dm-raid arrays. So get md_stop() to free them, and only all it from dm-raid. For internal arrays we now call __md_stop. Reported-by: majianpeng Signed-off-by: NeilBrown --- drivers/md/md.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 4c7d880..6120071 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_stop_writes); -void md_stop(struct mddev *mddev) +static void __md_stop(struct mddev *mddev) { mddev->ready = 0; mddev->pers->stop(mddev); @@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev) mddev->pers = NULL; clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } + +void md_stop(struct mddev *mddev) +{ + /* stop the array and free an attached data structures. + * This is called from dm-raid + */ + __md_stop(mddev); + bitmap_destroy(mddev); + if (mddev->bio_set) + bioset_free(mddev->bio_set); +} + EXPORT_SYMBOL_GPL(md_stop); static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) @@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode, set_disk_ro(disk, 0); __md_stop_writes(mddev); - md_stop(mddev); + __md_stop(mddev); mddev->queue->merge_bvec_fn = NULL; mddev->queue->backing_dev_info.congested_fn = NULL; -- cgit v1.1 From 3272dd9b0fe4bc09321219ab65dc5eda3e82445c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 16 Nov 2012 00:33:59 +0000 Subject: of/net/mdio-gpio: Fix pdev->id issue when using devicetrees. When the mdio-gpio driver is probed via device trees, the platform device id is set as -1, However the pdev->id is re-used as bus-id for while creating mdio gpio bus. So For device tree case the mdio-gpio bus name appears as "gpio-ffffffff" where as for non-device tree case the bus name appears as "gpio-" Which means the bus_id is fixed in device tree case, so we can't have two mdio gpio buses via device trees. Assigning a logical bus number via device tree solves the problem and the bus name is much consistent with non-device tree bus name. Without this patch 1. we can't support two mdio-gpio buses via device trees. 2. we should always pass gpio-ffffffff as bus name to phy_connect, very different to non-device tree bus name. So, setting up the bus_id via aliases from device tree is the right solution and other drivers do similar thing. Signed-off-by: Srinivas Kandagatla Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/mdio-gpio.txt | 9 ++++++++- drivers/net/phy/mdio-gpio.c | 11 +++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/mdio-gpio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt index bc954952..c79bab0 100644 --- a/Documentation/devicetree/bindings/net/mdio-gpio.txt +++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt @@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order: MDC, MDIO. +Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases" +node. + Example: -mdio { +aliases { + mdio-gpio0 = <&mdio0>; +}; + +mdio0: mdio { compatible = "virtual,mdio-gpio"; #address-cells = <1>; #size-cells = <0>; diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 899274f..2ed1140 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev) { struct mdio_gpio_platform_data *pdata; struct mii_bus *new_bus; - int ret; + int ret, bus_id; - if (pdev->dev.of_node) + if (pdev->dev.of_node) { pdata = mdio_gpio_of_get_data(pdev); - else + bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); + } else { pdata = pdev->dev.platform_data; + bus_id = pdev->id; + } if (!pdata) return -ENODEV; - new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); + new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id); if (!new_bus) return -ENODEV; -- cgit v1.1 From 4ac6875eeb97a49bad7bc8d56b5ec935904fc6e7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 19 Nov 2012 13:11:26 +1100 Subject: md/raid5: round discard alignment up to power of 2. blkdev_issue_discard currently assumes that the granularity is a power of 2. So in raid5, round the chosen number up to avoid embarrassment. Cc: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/raid5.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c5439dc..baea94f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5529,6 +5529,10 @@ static int run(struct mddev *mddev) * discard data disk but write parity disk */ stripe = stripe * PAGE_SIZE; + /* Round up to power of 2, as discard handling + * currently assumes that */ + while ((stripe-1) & stripe) + stripe = (stripe | (stripe-1)) + 1; mddev->queue->limits.discard_alignment = stripe; mddev->queue->limits.discard_granularity = stripe; /* -- cgit v1.1 From 91280e755a43fd2a6a20bfeab3a571321de68b76 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 20 Nov 2012 20:39:28 +0900 Subject: ARM: EXYNOS: PL330 MDMA1 fix for revision 0 of Exynos4210 SOC Commit 8214513 ("ARM: EXYNOS: fix address for EXYNOS4 MDMA1") changed EXYNOS specific setup of PL330 DMA engine to use 'non-secure' mdma1 address instead of 'secure' one (from 0x12840000 to 0x12850000) to fix issue with some Exynos4212 SOCs. Unfortunately it brakes PL330 setup for revision 0 of Exynos4210 SOC (mdma1 device cannot be found at 'non-secure' address): [ 0.566245] dma-pl330 dma-pl330.2: PERIPH_ID 0x0, PCELL_ID 0x0 ! [ 0.566278] dma-pl330: probe of dma-pl330.2 failed with error -22 Fix it by using 'secure' mdma1 address on Exynos4210 revision 0 SOC. Reviewed-by: Tomasz Figa Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/dma.c | 3 +++ arch/arm/mach-exynos/include/mach/map.h | 1 + 2 files changed, 4 insertions(+) diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index 21d568b..87e07d6 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -275,6 +275,9 @@ static int __init exynos_dma_init(void) exynos_pdma1_pdata.nr_valid_peri = ARRAY_SIZE(exynos4210_pdma1_peri); exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; + + if (samsung_rev() == EXYNOS4210_REV_0) + exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1; } else if (soc_is_exynos4212() || soc_is_exynos4412()) { exynos_pdma0_pdata.nr_valid_peri = ARRAY_SIZE(exynos4212_pdma0_peri); diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 8480849..ed4da45 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -90,6 +90,7 @@ #define EXYNOS4_PA_MDMA0 0x10810000 #define EXYNOS4_PA_MDMA1 0x12850000 +#define EXYNOS4_PA_S_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 #define EXYNOS5_PA_MDMA0 0x10800000 -- cgit v1.1 From 8c8a4b610b537b64326f4eea261984f12f8da073 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 20 Nov 2012 14:23:18 +0200 Subject: KVM: Retire as maintainer After six and a half years of writing and maintaining KVM, it is time to move to new things. Update my MAINTAINERS entry to reflect that. Signed-off-by: Avi Kivity --- CREDITS | 5 +++++ MAINTAINERS | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index d8fe12a..2346b09 100644 --- a/CREDITS +++ b/CREDITS @@ -1823,6 +1823,11 @@ S: Kattreinstr 38 S: D-64295 S: Germany +N: Avi Kivity +E: avi.kivity@gmail.com +D: Kernel-based Virtual Machine (KVM) +S: Ra'annana, Israel + N: Andi Kleen E: andi@firstfloor.org U: http://www.halobates.de diff --git a/MAINTAINERS b/MAINTAINERS index bb0b27d..6b5b0b7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4280,7 +4280,6 @@ F: include/linux/lockd/ F: include/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) -M: Avi Kivity M: Marcelo Tosatti L: kvm@vger.kernel.org W: http://kvm.qumranet.com -- cgit v1.1 From 484cbfd2a36fd2e32942cd9dff0cb2492b2be607 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 20 Nov 2012 14:37:24 +0200 Subject: KVM: taking co-maintenance Updating MAINTAINERS file. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6b5b0b7..b273360 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4281,6 +4281,7 @@ F: include/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) M: Marcelo Tosatti +M: Gleb Natapov L: kvm@vger.kernel.org W: http://kvm.qumranet.com S: Supported -- cgit v1.1 From 804cc4a0ad3a896ca295f771a28c6eb36ced7903 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 19 Nov 2012 09:11:27 -0500 Subject: drm/radeon: properly track the crtc not_enabled case evergreen_mc_stop() The save struct is not initialized previously so explicitly mark the crtcs as not used when they are not in use. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/evergreen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index af31f82..219942c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav break; udelay(1); } + } else { + save->crtc_enabled[i] = false; } } -- cgit v1.1 From 45171002b01b2e2ec4f991eca81ffd8430fd0aec Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 19 Nov 2012 21:17:31 +0100 Subject: radeon: add AGPMode 1 quirk for RV250 The Intel 82855PM host bridge / Mobility FireGL 9000 RV250 combination in an (outdated) ThinkPad T41 needs AGPMode 1 for suspend/resume (under KMS, that is). So add a quirk for it. (Change R250 to RV250 in comment for preceding quirk too.) Signed-off-by: Paul Bolle Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_agp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 10ea17a..4243334 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, PCI_VENDOR_ID_DELL, 0x00e3, 2}, - /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ + /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, PCI_VENDOR_ID_DELL, 0x0149, 1}, + /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ + { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, + PCI_VENDOR_ID_IBM, 0x0531, 1}, /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, 0x1025, 0x0061, 1}, -- cgit v1.1 From da9da01d9199b5bb15289d0859053c9aa3a34ac0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 20 Nov 2012 06:31:57 +0000 Subject: ne2000: add the right platform device Without this udev doesn't have a way to key the ne device to the platform device. Signed-off-by: Alan Cox Signed-off-by: David S. Miller --- drivers/net/ethernet/8390/ne.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index d04911d..47618e5 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c @@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev) dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; } + SET_NETDEV_DEV(dev, &pdev->dev); err = do_ne_probe(dev); if (err) { free_netdev(dev); -- cgit v1.1 From 1a4901177574083c35fafc24c4d151c2a7c7647c Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 17 Nov 2012 20:25:09 +0000 Subject: ixp4xx_eth: avoid calling dma_pool_create() with NULL dev Use &port->netdev->dev instead of NULL since dma_pool_create() doesn't allow NULL dev. Signed-off-by: Xi Wang Cc: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/ethernet/xscale/ixp4xx_eth.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 98934bd..477d672 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1102,10 +1102,12 @@ static int init_queues(struct port *port) { int i; - if (!ports_open) - if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, - POOL_ALLOC_SIZE, 32, 0))) + if (!ports_open) { + dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, + POOL_ALLOC_SIZE, 32, 0); + if (!dma_pool) return -ENOMEM; + } if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, &port->desc_tab_phys))) -- cgit v1.1 From 3e2f61cd7a4e7642dcac4371734426e572f10370 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 17 Nov 2012 20:25:10 +0000 Subject: ixp4xx_hss: avoid calling dma_pool_create() with NULL dev Use &port->netdev->dev instead of NULL since dma_pool_create() doesn't allow NULL dev. Signed-off-by: Xi Wang Cc: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/wan/ixp4xx_hss.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 3f575af..e9a3da5 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port) { int i; - if (!ports_open) - if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, - POOL_ALLOC_SIZE, 32, 0))) + if (!ports_open) { + dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, + POOL_ALLOC_SIZE, 32, 0); + if (!dma_pool) return -ENOMEM; + } if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, &port->desc_tab_phys))) -- cgit v1.1 From b4dd006760d671337b62532277b0296bcee8dfd4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 20 Nov 2012 15:14:51 -0500 Subject: ipv6: fix inet6_csk_update_pmtu() return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of error, inet6_csk_update_pmtu() should consistently return NULL. Bug added in commit 35ad9b9cf7d8a (ipv6: Add helper inet6_csk_update_pmtu().) Reported-by: Lluís Batlle i Rossell Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/inet6_connection_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index c4f9341..3064785 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) return NULL; dst->ops->update_pmtu(dst, sk, NULL, mtu); - return inet6_csk_route_socket(sk, &fl6); + dst = inet6_csk_route_socket(sk, &fl6); + return IS_ERR(dst) ? NULL : dst; } EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); -- cgit v1.1 From caaa8c6339ccefee6e834c4a8b0bec7e721e7357 Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Sat, 27 Oct 2012 20:34:15 -0200 Subject: x86: remove dummy long from EFI stub Commit 2e064b1 (x86, efi: Fix issue of overlapping .reloc section for EFI_STUB) removed a dummy reloc added by commit 291f363 (x86, efi: EFI boot stub support), but forgot to remove the dummy long used by that reloc. Reviewed-by: Jordan Justen Tested-by: Lee G Rosenbaum Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Cesar Eduardo Barros Signed-off-by: Matt Fleming --- arch/x86/boot/header.S | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 2a01744..8c132a6 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -476,6 +476,3 @@ die: setup_corrupt: .byte 7 .string "No setup signature found...\n" - - .data -dummy: .long 0 -- cgit v1.1 From 2355a62bcbdcc4b567425bab036bfab6ade87eed Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 20 Nov 2012 09:59:11 +0000 Subject: irda: sir_dev: Fix copy/paste typo Signed-off-by: Alexander Shiyan Signed-off-by: David S. Miller --- drivers/net/irda/sir_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 5039f08..43e9ab4 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) break; case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->reset) { + if (dev->dongle_drv->set_speed) { ret = dev->dongle_drv->set_speed(dev, fsm->param); if (ret < 0) { fsm->result = ret; -- cgit v1.1 From aecb55be41b1bab432e81d550ebce010e7d178c6 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 20 Nov 2012 10:23:13 +0000 Subject: net: fix build failure in xilinx Commit 71c6c837 (drivers/net: fix tasklet misuse issue) introduced a build failure in the xilinx driver. axienet_dma_err_handler isn't declared before its use in axienet_open. This patch provides the prototype before axienet_open. Cc: Xiaotian Feng Signed-off-by: Jeff Mahoney Signed-off-by: David S. Miller --- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 77e6db9..a788501 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -894,6 +894,8 @@ out: return IRQ_HANDLED; } +static void axienet_dma_err_handler(unsigned long data); + /** * axienet_open - Driver open routine. * @ndev: Pointer to net_device structure -- cgit v1.1 From 0f905a43ce955b638139bd84486194770a6a2c08 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 20 Nov 2012 13:07:46 +0000 Subject: x86, efi: Fix processor-specific memcpy() build error Building for Athlon/Duron/K7 results in the following build error, arch/x86/boot/compressed/eboot.o: In function `__constant_memcpy3d': eboot.c:(.text+0x385): undefined reference to `_mmx_memcpy' arch/x86/boot/compressed/eboot.o: In function `efi_main': eboot.c:(.text+0x1a22): undefined reference to `_mmx_memcpy' because the boot stub code doesn't link with the kernel proper, and therefore doesn't have access to the 3DNow version of memcpy. So, follow the example of misc.c and #undef memcpy so that we use the version provided by misc.c. See https://bugzilla.kernel.org/show_bug.cgi?id=50391 Reported-by: Al Viro Reported-by: Ryan Underwood Cc: H. Peter Anvin Cc: stable@vger.kernel.org Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/eboot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c760e07..e87b0ca 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -12,6 +12,8 @@ #include #include +#undef memcpy /* Use memcpy from misc.c */ + #include "eboot.h" static efi_system_table_t *sys_table; -- cgit v1.1 From ae6a5d37725853325a2b3460165fbc5613ce2916 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:17:51 +0000 Subject: ASoC: kirkwood-dma: fix use of virt_to_phys() This is part of a patch found in Rabeeh Khoury's git tree for the cubox. You can not use virt_to_phys() on the address returned from dma_alloc_coherent(); it may not be part of the kernel direct-mapped memory. Fix this to use the DMA address instead. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index b9f1659..afe1930 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -178,7 +178,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) } dram = mv_mbus_dram_info(); - addr = virt_to_phys(substream->dma_buffer.area); + addr = substream->dma_buffer.addr; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { prdata->play_stream = substream; kirkwood_dma_conf_mbus_windows(priv->io, -- cgit v1.1 From 25ec6bbb63e7eec905d94ccb59cdd54cf22ee618 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:18:11 +0000 Subject: ASoC: kirkwood-dma: don't ignore other irq causes on error Ignoring the real cause of the interrupt is not a good idea; this behaviour has been observed to bring Dove platforms to silently lockup. Instead, on error fall through to the normal interrupt processing. This is especially important on Dove platforms as errors are handled separately, and allows us to clear down the real cause of the interrupt. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index afe1930..2ba0814 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -71,7 +71,6 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) printk(KERN_WARNING "%s: got err interrupt 0x%lx\n", __func__, cause); writel(cause, priv->io + KIRKWOOD_ERR_CAUSE); - return IRQ_HANDLED; } /* we've enabled only bytes interrupts ... */ -- cgit v1.1 From 2424d458108e275ca736dabc792ee9b6733994c5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:18:32 +0000 Subject: ASoC: kirkwood-i2s: fix DCO lock detection This is part of a patch found in Rabeeh Khoury's git tree for the cubox, which is further attributed to Sebastian Hesselbrath. Rather than masking the KIRKWOOD_DCO_SPCR_STATUS register contents against the registers virtual address, let's actually use the bit definition for the locked status, as required in the documentation. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 542538d..485af80 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -95,7 +95,7 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) do { cpu_relax(); value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); - value &= KIRKWOOD_DCO_SPCR_STATUS; + value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; } while (value == 0); } -- cgit v1.1 From 982b604bc56a3da874e489051fc7adb49b1eba65 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:18:52 +0000 Subject: ASoC: kirkwood-i2s: fix DMA underruns Stress testing the driver with multiple start/stop events causes kirkwood-dma to report underrun errors (which used to cause the kernel to lock up solidly). This is because kirkwood-i2s is not respecting the restrictions imposed on clearing the 'pause' bit. Follow what the spec says; the busy bit must be read as being clear twice before the pause bit can be released. This solves the underruns. However, it has been noticed that the busy bit occasionally does not clear itself, hence the waiting is bounded to 5ms maximum to avoid a new reason for the kernel to lockup. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 67 ++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 485af80..826306d 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -180,67 +180,76 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); - unsigned long value; - - /* - * specs says KIRKWOOD_PLAYCTL must be read 2 times before - * changing it. So read 1 time here and 1 later. - */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); + uint32_t ctl, value; + + ctl = readl(priv->io + KIRKWOOD_PLAYCTL); + if (ctl & KIRKWOOD_PLAYCTL_PAUSE) { + unsigned timeout = 5000; + /* + * The Armada510 spec says that if we enter pause mode, the + * busy bit must be read back as clear _twice_. Make sure + * we respect that otherwise we get DMA underruns. + */ + do { + value = ctl; + ctl = readl(priv->io + KIRKWOOD_PLAYCTL); + if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)) + break; + udelay(1); + } while (timeout--); + + if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) + dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", + ctl); + } switch (cmd) { case SNDRV_PCM_TRIGGER_START: /* stop audio, enable interrupts */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value |= KIRKWOOD_PLAYCTL_PAUSE; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_PAUSE; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); /* configure audio & enable i2s playback */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value &= ~KIRKWOOD_PLAYCTL_BURST_MASK; - value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE + ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK; + ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | KIRKWOOD_PLAYCTL_SPDIF_EN); if (priv->burst == 32) - value |= KIRKWOOD_PLAYCTL_BURST_32; + ctl |= KIRKWOOD_PLAYCTL_BURST_32; else - value |= KIRKWOOD_PLAYCTL_BURST_128; - value |= KIRKWOOD_PLAYCTL_I2S_EN; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_BURST_128; + ctl |= KIRKWOOD_PLAYCTL_I2S_EN; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_STOP: /* stop audio, disable interrupts */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); value = readl(priv->io + KIRKWOOD_INT_MASK); value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); /* disable all playbacks */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; default: -- cgit v1.1 From 3ccdf5bbdf5f2488e4a36692d055ba9c43ae6717 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:19:13 +0000 Subject: ASoC: kirkwood-i2s: more pause-mode fixes Don't even momentarily set the pause status when starting the channel; if we do, we should check the busy bit to ensure that we comply with the spec. In any case, it isn't necessary; we will not active on a START event so there is no need to pause the DMA. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 826306d..1d5db48 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -205,10 +205,6 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - /* stop audio, enable interrupts */ - ctl |= KIRKWOOD_PLAYCTL_PAUSE; - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); - value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); @@ -269,11 +265,6 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - /* stop audio, enable interrupts */ - value = readl(priv->io + KIRKWOOD_RECCTL); - value |= KIRKWOOD_RECCTL_PAUSE; - writel(value, priv->io + KIRKWOOD_RECCTL); - value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_REC_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); -- cgit v1.1 From 68fa965dd923177eafad49b7a0045fc610917341 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Fri, 16 Nov 2012 18:36:49 +0000 Subject: xen/privcmd: Correctly return success from IOCTL_PRIVCMD_MMAPBATCH This is a regression introduced by ceb90fa0 (xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl). It broke xentrace as it used xc_map_foreign() instead of xc_map_foreign_bulk(). Most code-paths prefer the MMAPBATCH_V2, so this wasn't very obvious that it broke. The return value is set early on to -EINVAL, and if all goes well, the "set top bits of the MFN's" never gets called, so the return value is still EINVAL when the function gets to the end, causing the caller to think it went wrong (which it didn't!) Now also including Andres "move the ret = -EINVAL into the error handling path, as this avoids other similar errors in future. Signed-off-by: Mats Petersson Acked-by: Andres Lagar-Cavilla Acked-by: David Vrabel Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/privcmd.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 8adb9cc..71f5c45 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) down_write(&mm->mmap_sem); vma = find_vma(mm, m.addr); - ret = -EINVAL; if (!vma || vma->vm_ops != &privcmd_vm_ops || (m.addr != vma->vm_start) || ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || !privcmd_enforce_singleshot_mapping(vma)) { up_write(&mm->mmap_sem); + ret = -EINVAL; goto out; } @@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) up_write(&mm->mmap_sem); - if (state.global_error && (version == 1)) { - /* Write back errors in second pass. */ - state.user_mfn = (xen_pfn_t *)m.arr; - state.err = err_array; - ret = traverse_pages(m.num, sizeof(xen_pfn_t), - &pagelist, mmap_return_errors_v1, &state); + if (version == 1) { + if (state.global_error) { + /* Write back errors in second pass. */ + state.user_mfn = (xen_pfn_t *)m.arr; + state.err = err_array; + ret = traverse_pages(m.num, sizeof(xen_pfn_t), + &pagelist, mmap_return_errors_v1, &state); + } else + ret = 0; + } else if (version == 2) { ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); if (ret) -- cgit v1.1 From 1022623842cb72ee4d0dbf02f6937f38c92c3f41 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 Sep 2012 20:54:48 +0200 Subject: x86-32: Fix invalid stack address while in softirq In 32 bit the stack address provided by kernel_stack_pointer() may point to an invalid range causing NULL pointer access or page faults while in NMI (see trace below). This happens if called in softirq context and if the stack is empty. The address at ®s->sp is then out of range. Fixing this by checking if regs and ®s->sp are in the same stack context. Otherwise return the previous stack pointer stored in struct thread_info. If that address is invalid too, return address of regs. BUG: unable to handle kernel NULL pointer dereference at 0000000a IP: [] print_context_stack+0x6e/0x8d *pde = 00000000 Oops: 0000 [#1] SMP Modules linked in: Pid: 4434, comm: perl Not tainted 3.6.0-rc3-oprofile-i386-standard-g4411a05 #4 Hewlett-Packard HP xw9400 Workstation/0A1Ch EIP: 0060:[] EFLAGS: 00010093 CPU: 0 EIP is at print_context_stack+0x6e/0x8d EAX: ffffe000 EBX: 0000000a ECX: f4435f94 EDX: 0000000a ESI: f4435f94 EDI: f4435f94 EBP: f5409ec0 ESP: f5409ea0 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 CR0: 8005003b CR2: 0000000a CR3: 34ac9000 CR4: 000007d0 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Process perl (pid: 4434, ti=f5408000 task=f5637850 task.ti=f4434000) Stack: 000003e8 ffffe000 00001ffc f4e39b00 00000000 0000000a f4435f94 c155198c f5409ef0 c1003723 c155198c f5409f04 00000000 f5409edc 00000000 00000000 f5409ee8 f4435f94 f5409fc4 00000001 f5409f1c c12dce1c 00000000 c155198c Call Trace: [] dump_trace+0x7b/0xa1 [] x86_backtrace+0x40/0x88 [] ? oprofile_add_sample+0x56/0x84 [] oprofile_add_sample+0x75/0x84 [] op_amd_check_ctrs+0x46/0x260 [] profile_exceptions_notify+0x23/0x4c [] nmi_handle+0x31/0x4a [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] do_nmi+0xa0/0x2ff [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] nmi_stack_correct+0x28/0x2d [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] ? do_softirq+0x4b/0x7f [] irq_exit+0x35/0x5b [] smp_apic_timer_interrupt+0x6c/0x7a [] apic_timer_interrupt+0x2a/0x30 Code: 89 fe eb 08 31 c9 8b 45 0c ff 55 ec 83 c3 04 83 7d 10 00 74 0c 3b 5d 10 73 26 3b 5d e4 73 0c eb 1f 3b 5d f0 76 1a 3b 5d e8 73 15 <8b> 13 89 d0 89 55 e0 e8 ad 42 03 00 85 c0 8b 55 e0 75 a6 eb cc EIP: [] print_context_stack+0x6e/0x8d SS:ESP 0068:f5409ea0 CR2: 000000000000000a ---[ end trace 62afee3481b00012 ]--- Kernel panic - not syncing: Fatal exception in interrupt V2: * add comments to kernel_stack_pointer() * always return a valid stack address by falling back to the address of regs Reported-by: Yang Wei Cc: Signed-off-by: Robert Richter Link: http://lkml.kernel.org/r/20120912135059.GZ8285@erda.amd.com Signed-off-by: H. Peter Anvin Cc: Jun Zhang --- arch/x86/include/asm/ptrace.h | 15 ++++----------- arch/x86/kernel/ptrace.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index dcfde52..19f16eb 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs) } #endif -/* - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode - * when it traps. The previous stack will be directly underneath the saved - * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. - * - * This is valid only for kernel mode traps. - */ -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) -{ #ifdef CONFIG_X86_32 - return (unsigned long)(®s->sp); +extern unsigned long kernel_stack_pointer(struct pt_regs *regs); #else +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ return regs->sp; -#endif } +#endif #define GET_IP(regs) ((regs)->ip) #define GET_FP(regs) ((regs)->bp) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index b00b33a..2484e33 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -166,6 +166,34 @@ static inline bool invalid_selector(u16 value) #define FLAG_MASK FLAG_MASK_32 +/* + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode + * when it traps. The previous stack will be directly underneath the saved + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. + * + * Now, if the stack is empty, '®s->sp' is out of range. In this + * case we try to take the previous stack. To always return a non-null + * stack pointer we fall back to regs as stack if no previous stack + * exists. + * + * This is valid only for kernel mode traps. + */ +unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); + unsigned long sp = (unsigned long)®s->sp; + struct thread_info *tinfo; + + if (context == (sp & ~(THREAD_SIZE - 1))) + return sp; + + tinfo = (struct thread_info *)context; + if (tinfo->previous_esp) + return tinfo->previous_esp; + + return (unsigned long)regs; +} + static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); -- cgit v1.1 From cb57a2b4cff7edf2a4e32c0163200e9434807e0a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 20 Nov 2012 22:21:02 -0800 Subject: x86-32: Export kernel_stack_pointer() for modules Modules, in particular oprofile (and possibly other similar tools) need kernel_stack_pointer(), so export it using EXPORT_SYMBOL_GPL(). Cc: Yang Wei Cc: Robert Richter Cc: Jun Zhang Cc: Link: http://lkml.kernel.org/r/20120912135059.GZ8285@erda.amd.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/ptrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 2484e33..5e0596b 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -193,6 +194,7 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) return (unsigned long)regs; } +EXPORT_SYMBOL_GPL(kernel_stack_pointer); static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { -- cgit v1.1 From 36c46ca4f322a7bf89aad5462a3a1f61713edce7 Mon Sep 17 00:00:00 2001 From: Boris Ostrovsky Date: Thu, 15 Nov 2012 13:41:50 -0500 Subject: x86, microcode, AMD: Add support for family 16h processors Add valid patch size for family 16h processors. [ hpa: promoting to urgent/stable since it is hw enabling and trivial ] Signed-off-by: Boris Ostrovsky Acked-by: Andreas Herrmann Link: http://lkml.kernel.org/r/1353004910-2204-1-git-send-email-boris.ostrovsky@amd.com Signed-off-by: H. Peter Anvin Cc: --- arch/x86/kernel/microcode_amd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index b3e67ba..efdec7c 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, #define F1XH_MPB_MAX_SIZE 2048 #define F14H_MPB_MAX_SIZE 1824 #define F15H_MPB_MAX_SIZE 4096 +#define F16H_MPB_MAX_SIZE 3458 switch (c->x86) { case 0x14: @@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, case 0x15: max_size = F15H_MPB_MAX_SIZE; break; + case 0x16: + max_size = F16H_MPB_MAX_SIZE; + break; default: max_size = F1XH_MPB_MAX_SIZE; break; -- cgit v1.1 From ee4eb87be2c3f69c2c4d9f1c1d98e363a7ad18ab Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Nov 2012 11:18:39 +0000 Subject: x86-64: Fix ordering of CFI directives and recent ASM_CLAC additions While these got added in the right place everywhere else, entry_64.S is the odd one where they ended up before the initial CFI directive(s). In order to cover the full code ranges, the CFI directive must be first, though. Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/5093BA1F02000078000A600E@nat28.tlf.novell.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/entry_64.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b51b2c7..1328fe4 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -995,8 +995,8 @@ END(interrupt) */ .p2align CONFIG_X86_L1_CACHE_SHIFT common_interrupt: - ASM_CLAC XCPT_FRAME + ASM_CLAC addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ interrupt do_IRQ /* 0(%rsp): old_rsp-ARGOFFSET */ @@ -1135,8 +1135,8 @@ END(common_interrupt) */ .macro apicinterrupt num sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC pushq_cfi $~(\num) .Lcommon_\sym: interrupt \do_sym @@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \ */ .macro zeroentry sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1208,8 +1208,8 @@ END(\sym) .macro paranoidzeroentry sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1227,8 +1227,8 @@ END(\sym) #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1247,8 +1247,8 @@ END(\sym) .macro errorentry sym do_sym ENTRY(\sym) - ASM_CLAC XCPT_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 @@ -1266,8 +1266,8 @@ END(\sym) /* error code is on the stack already */ .macro paranoiderrorentry sym do_sym ENTRY(\sym) - ASM_CLAC XCPT_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 -- cgit v1.1 From af02dde8a609d8d071c4b31a82df811a55690a4a Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 21 Nov 2012 08:57:58 +0100 Subject: ALSA: hda - Add support for Realtek ALC292 We found a new codec ID 292, and that just a simple quirk would enable sound output/input on this ALC292 chip. BugLink: https://bugs.launchpad.net/bugs/1081466 Cc: stable@vger.kernel.org Tested-by: Acelan Kao Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 68fd492..ad68d22 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7065,6 +7065,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, + { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, -- cgit v1.1 From 34c3d1926bdaf45d3a891dd577482abcdd9faa34 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 21 Nov 2012 10:03:10 +0100 Subject: ALSA: hda - Cirrus: Correctly clear line_out_pins when moving to speaker If this array is not cleared, the jack related code later might fail to create "Internal Speaker Phantom Jack" on Dell Inspiron 3420 and Dell Vostro 2420. BugLink: https://bugs.launchpad.net/bugs/1076840 Cc: stable@vger.kernel.org (3.6+) Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_cirrus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index d5f3a26..3bcb671 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -466,6 +466,7 @@ static int parse_output(struct hda_codec *codec) memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->line_outs = 0; + memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins)); } return 0; -- cgit v1.1 From 88a693b5c1287be4da937699cb82068ce9db0135 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 8 Nov 2012 16:09:27 -0800 Subject: selinux: fix sel_netnode_insert() suspicious rcu dereference =============================== [ INFO: suspicious RCU usage. ] 3.5.0-rc1+ #63 Not tainted ------------------------------- security/selinux/netnode.c:178 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by trinity-child1/8750: #0: (sel_netnode_lock){+.....}, at: [] sel_netnode_sid+0x16a/0x3e0 stack backtrace: Pid: 8750, comm: trinity-child1 Not tainted 3.5.0-rc1+ #63 Call Trace: [] lockdep_rcu_suspicious+0xfd/0x130 [] sel_netnode_sid+0x3b1/0x3e0 [] ? sel_netnode_find+0x1a0/0x1a0 [] selinux_socket_bind+0xf6/0x2c0 [] ? trace_hardirqs_off+0xd/0x10 [] ? lock_release_holdtime.part.9+0x15/0x1a0 [] ? lock_hrtimer_base+0x31/0x60 [] security_socket_bind+0x16/0x20 [] sys_bind+0x7a/0x100 [] ? sysret_check+0x22/0x5d [] ? trace_hardirqs_on_caller+0x10d/0x1a0 [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b This patch below does what Paul McKenney suggested in the previous thread. Signed-off-by: Dave Jones Reviewed-by: Paul E. McKenney Acked-by: Paul Moore Cc: Eric Paris Cc: Signed-off-by: Andrew Morton Signed-off-by: James Morris --- security/selinux/netnode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 28f911c..c5454c0 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node) if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { struct sel_netnode *tail; tail = list_entry( - rcu_dereference(sel_netnode_hash[idx].list.prev), + rcu_dereference_protected(sel_netnode_hash[idx].list.prev, + lockdep_is_held(&sel_netnode_lock)), struct sel_netnode, list); list_del_rcu(&tail->list); kfree_rcu(tail, rcu); -- cgit v1.1 From f36c374782e40a3812f729838b5b80d2ce601725 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 21 Nov 2012 02:02:16 +0000 Subject: xen/netfront: handle compound page fragments on transmit An SKB paged fragment can consist of a compound page with order > 0. However the netchannel protocol deals only in PAGE_SIZE frames. Handle this in xennet_make_frags by iterating over the frames which make up the page. This is the netfront equivalent to 6a8ed462f16b for netback. Signed-off-by: Ian Campbell Cc: netdev@vger.kernel.org Cc: xen-devel@lists.xen.org Cc: Eric Dumazet Cc: Konrad Rzeszutek Wilk Cc: ANNIE LI Cc: Sander Eikelenboom Cc: Stefan Bader Acked-by: Eric Dumazet Acked-by: Konrad Rzeszutek Wilk Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 98 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index caa0110..fc24eb9 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, /* Grant backend access to each skb fragment page. */ for (i = 0; i < frags; i++) { skb_frag_t *frag = skb_shinfo(skb)->frags + i; + struct page *page = skb_frag_page(frag); - tx->flags |= XEN_NETTXF_more_data; + len = skb_frag_size(frag); + offset = frag->page_offset; - id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); - np->tx_skbs[id].skb = skb_get(skb); - tx = RING_GET_REQUEST(&np->tx, prod++); - tx->id = id; - ref = gnttab_claim_grant_reference(&np->gref_tx_head); - BUG_ON((signed short)ref < 0); + /* Data must not cross a page boundary. */ + BUG_ON(len + offset > PAGE_SIZE<xbdev->otherend_id, - mfn, GNTMAP_readonly); + /* Skip unused frames from start of page */ + page += offset >> PAGE_SHIFT; + offset &= ~PAGE_MASK; - tx->gref = np->grant_tx_ref[id] = ref; - tx->offset = frag->page_offset; - tx->size = skb_frag_size(frag); - tx->flags = 0; + while (len > 0) { + unsigned long bytes; + + BUG_ON(offset >= PAGE_SIZE); + + bytes = PAGE_SIZE - offset; + if (bytes > len) + bytes = len; + + tx->flags |= XEN_NETTXF_more_data; + + id = get_id_from_freelist(&np->tx_skb_freelist, + np->tx_skbs); + np->tx_skbs[id].skb = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + + mfn = pfn_to_mfn(page_to_pfn(page)); + gnttab_grant_foreign_access_ref(ref, + np->xbdev->otherend_id, + mfn, GNTMAP_readonly); + + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = offset; + tx->size = bytes; + tx->flags = 0; + + offset += bytes; + len -= bytes; + + /* Next frame */ + if (offset == PAGE_SIZE && len) { + BUG_ON(!PageCompound(page)); + page++; + offset = 0; + } + } } np->tx.req_prod_pvt = prod; } +/* + * Count how many ring slots are required to send the frags of this + * skb. Each frag might be a compound page. + */ +static int xennet_count_skb_frag_slots(struct sk_buff *skb) +{ + int i, frags = skb_shinfo(skb)->nr_frags; + int pages = 0; + + for (i = 0; i < frags; i++) { + skb_frag_t *frag = skb_shinfo(skb)->frags + i; + unsigned long size = skb_frag_size(frag); + unsigned long offset = frag->page_offset; + + /* Skip unused frames from start of page */ + offset &= ~PAGE_MASK; + + pages += PFN_UP(offset + size); + } + + return pages; +} + static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; @@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) grant_ref_t ref; unsigned long mfn; int notify; - int frags = skb_shinfo(skb)->nr_frags; + int slots; unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); unsigned long flags; - frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); - if (unlikely(frags > MAX_SKB_FRAGS + 1)) { - printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", - frags); - dump_stack(); + slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + + xennet_count_skb_frag_slots(skb); + if (unlikely(slots > MAX_SKB_FRAGS + 1)) { + net_alert_ratelimited( + "xennet: skb rides the rocket: %d slots\n", slots); goto drop; } spin_lock_irqsave(&np->tx_lock, flags); if (unlikely(!netif_carrier_ok(dev) || - (frags > 1 && !xennet_can_sg(dev)) || + (slots > 1 && !xennet_can_sg(dev)) || netif_needs_gso(skb, netif_skb_features(skb)))) { spin_unlock_irqrestore(&np->tx_lock, flags); goto drop; -- cgit v1.1 From 0e376bd0b791ac6ac6bdb051492df0769c840848 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 21 Nov 2012 04:35:03 +0000 Subject: bonding: Bonding driver does not consider the gso_max_size/gso_max_segs setting of slave devices. Patch sets the lowest gso_max_size and gso_max_segs values of the slave devices during enslave and detach. Signed-off-by: Sarveshwar Bandi Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b2530b0..5f5b69f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond) struct net_device *bond_dev = bond->dev; netdev_features_t vlan_features = BOND_VLAN_FEATURES; unsigned short max_hard_header_len = ETH_HLEN; + unsigned int gso_max_size = GSO_MAX_SIZE; + u16 gso_max_segs = GSO_MAX_SEGS; int i; unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; @@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond) dst_release_flag &= slave->dev->priv_flags; if (slave->dev->hard_header_len > max_hard_header_len) max_hard_header_len = slave->dev->hard_header_len; + + gso_max_size = min(gso_max_size, slave->dev->gso_max_size); + gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); } done: bond_dev->vlan_features = vlan_features; bond_dev->hard_header_len = max_hard_header_len; + bond_dev->gso_max_segs = gso_max_segs; + netif_set_gso_max_size(bond_dev, gso_max_size); flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; bond_dev->priv_flags = flags | dst_release_flag; -- cgit v1.1 From 916492b1e1a186260951831c53a53d8a448dc026 Mon Sep 17 00:00:00 2001 From: Chun-Yi Lee Date: Wed, 21 Nov 2012 11:26:09 +0000 Subject: sign-file: fix the perl warning message when extracting ASN.1 There have the following warning message when running modules install for sign ko files: # make modules_install ... INSTALL drivers/input/touchscreen/pcap_ts.ko Found = in conditional, should be == at scripts/sign-file line 164. Found = in conditional, should be == at scripts/sign-file line 161. Found = in conditional, should be == at scripts/sign-file line 159. This patch change replace '=' by '==' in elsif conditions for avoid the above warning messages. Signed-off-by: Chun-Yi Lee Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- scripts/sign-file | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/sign-file b/scripts/sign-file index 87ca59d..974a20b 100755 --- a/scripts/sign-file +++ b/scripts/sign-file @@ -156,12 +156,12 @@ sub asn1_extract($$@) if ($l == 0x1) { $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)); - } elsif ($l = 0x2) { + } elsif ($l == 0x2) { $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2)); - } elsif ($l = 0x3) { + } elsif ($l == 0x3) { $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16; $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2)); - } elsif ($l = 0x4) { + } elsif ($l == 0x4) { $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4)); } else { die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n"; -- cgit v1.1 From 403f43c937d24832b18524f65415c0bbba6b5064 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 21 Nov 2012 02:34:45 +0000 Subject: team: bcast: convert return value of team_dev_queue_xmit() to bool correctly The thing is that team_dev_queue_xmit() returns NET_XMIT_* or -E*. bc_trasmit() should return true in case all went well. So use ! to get correct retval from team_dev_queue_xmit() result. This bug caused iface statistics to be badly computed. This bug was introduced by: team: add broadcast mode (5fc889911a99043a97da1daa0d010ad72cbc3042) Reported-by: Dan Carpenter Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_broadcast.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c index 9db0171..c5db428 100644 --- a/drivers/net/team/team_mode_broadcast.c +++ b/drivers/net/team/team_mode_broadcast.c @@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) if (last) { skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { - ret = team_dev_queue_xmit(team, last, - skb2); + ret = !team_dev_queue_xmit(team, last, + skb2); if (!sum_ret) sum_ret = ret; } @@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) } } if (last) { - ret = team_dev_queue_xmit(team, last, skb); + ret = !team_dev_queue_xmit(team, last, skb); if (!sum_ret) sum_ret = ret; } -- cgit v1.1 From c4f4925439f13a243aecfb36c693613603c0bfbd Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 20 Nov 2012 23:00:10 -0800 Subject: Input: ads7846 - enable pendown GPIO debounce time setting Some platforms need the pendown GPIO debounce time setting programmed. Since the pendown GPIO is handled by the driver, the debounce time should also be handled along with the pendown GPIO request. Signed-off-by: Igor Grinberg Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 6 +++++- include/linux/spi/ads7846.h | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index f02028e..78e5d9a 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); -static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) +static int __devinit ads7846_setup_pendown(struct spi_device *spi, + struct ads7846 *ts) { struct ads7846_platform_data *pdata = spi->dev.platform_data; int err; @@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 ts->gpio_pendown = pdata->gpio_pendown; + if (pdata->gpio_pendown_debounce) + gpio_set_debounce(pdata->gpio_pendown, + pdata->gpio_pendown_debounce); } else { dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); return -EINVAL; diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index c64de9d..2f694f3 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -46,8 +46,9 @@ struct ads7846_platform_data { u16 debounce_rep; /* additional consecutive good readings * required after the first two */ int gpio_pendown; /* the GPIO used to decide the pendown - * state if get_pendown_state == NULL - */ + * state if get_pendown_state == NULL */ + int gpio_pendown_debounce; /* platform specific debounce time for + * the gpio_pendown */ int (*get_pendown_state)(void); int (*filter_init) (const struct ads7846_platform_data *pdata, void **filter_data); -- cgit v1.1 From 0a0d62857366d8a6531e7fed1c3ccdd9a2b5b40b Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 20 Nov 2012 23:00:51 -0800 Subject: ARM - OMAP: ads7846: fix pendown debounce setting Commit 97ee9f01 (ARM: OMAP: fix the ads7846 init code) have enabled the pendown GPIO debounce time setting by the below sequence: gpio_request_one() gpio_set_debounce() gpio_free() It also revealed a bug in the OMAP GPIO handling code which prevented the GPIO debounce clock to be disabled and CORE transition to low power states. Commit c9c55d9 (gpio/omap: fix off-mode bug: clear debounce settings on free/reset) fixes the OMAP GPIO handling code by making sure that the GPIO debounce clock gets disabled if no GPIO is requested from current bank. While fixing the OMAP GPIO handling code (in the right way), the above commit makes the gpio_request->set_debounce->free sequence invalid as after freeing the GPIO, the debounce settings are lost. Fix the debounce settings by moving the debounce initialization to the actual GPIO requesting code - the ads7846 driver. Signed-off-by: Igor Grinberg Acked-by: Tony Lindgren Signed-off-by: Dmitry Torokhov --- arch/arm/mach-omap2/common-board-devices.c | 34 ++++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 48daac2..84551f2 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, struct spi_board_info *spi_bi = &ads7846_spi_board_info; int err; - err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); - if (err) { - pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); - return; - } + /* + * If a board defines get_pendown_state() function, request the pendown + * GPIO and set the GPIO debounce time. + * If a board does not define the get_pendown_state() function, then + * the ads7846 driver will setup the pendown GPIO itself. + */ + if (board_pdata && board_pdata->get_pendown_state) { + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); + if (err) { + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); + return; + } - if (gpio_debounce) - gpio_set_debounce(gpio_pendown, gpio_debounce); + if (gpio_debounce) + gpio_set_debounce(gpio_pendown, gpio_debounce); + + gpio_export(gpio_pendown, 0); + } spi_bi->bus_num = bus_num; spi_bi->irq = gpio_to_irq(gpio_pendown); + ads7846_config.gpio_pendown = gpio_pendown; + if (board_pdata) { board_pdata->gpio_pendown = gpio_pendown; + board_pdata->gpio_pendown_debounce = gpio_debounce; spi_bi->platform_data = board_pdata; - if (board_pdata->get_pendown_state) - gpio_export(gpio_pendown, 0); - } else { - ads7846_config.gpio_pendown = gpio_pendown; } - if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) - gpio_free(gpio_pendown); - spi_register_board_info(&ads7846_spi_board_info, 1); } #else -- cgit v1.1 From ef5b7c69b7a1b8b8744a6168b6ff02900f81b6ca Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 22 Nov 2012 09:13:36 +1100 Subject: md/raid5: move resolving of reconstruct_state earlier in stripe_handle. The chunk of code in stripe_handle which responds to a *_result value in reconstruct_state is really the completion of some processing that happened outside of handle_stripe (possibly asynchronously) and so should be one of the first things done in handle_stripe(). After the next patch it will be important that it happens before handle_stripe_clean_event(), as that will clear some dev->flags bit that this code tests. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 68 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index baea94f..0fb9885 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3490,40 +3490,6 @@ static void handle_stripe(struct stripe_head *sh) handle_failed_sync(conf, sh, &s); } - /* - * might be able to return some write requests if the parity blocks - * are safe, or on a failed drive - */ - pdev = &sh->dev[sh->pd_idx]; - s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) - || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); - qdev = &sh->dev[sh->qd_idx]; - s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) - || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) - || conf->level < 6; - - if (s.written && - (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) - && !test_bit(R5_LOCKED, &pdev->flags) - && (test_bit(R5_UPTODATE, &pdev->flags) || - test_bit(R5_Discard, &pdev->flags))))) && - (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) - && !test_bit(R5_LOCKED, &qdev->flags) - && (test_bit(R5_UPTODATE, &qdev->flags) || - test_bit(R5_Discard, &qdev->flags)))))) - handle_stripe_clean_event(conf, sh, disks, &s.return_bi); - - /* Now we might consider reading some blocks, either to check/generate - * parity, or to satisfy requests - * or to load a block that is being partially written. - */ - if (s.to_read || s.non_overwrite - || (conf->level == 6 && s.to_write && s.failed) - || (s.syncing && (s.uptodate + s.compute < disks)) - || s.replacing - || s.expanding) - handle_stripe_fill(sh, &s, disks); - /* Now we check to see if any write operations have recently * completed */ @@ -3561,6 +3527,40 @@ static void handle_stripe(struct stripe_head *sh) s.dec_preread_active = 1; } + /* + * might be able to return some write requests if the parity blocks + * are safe, or on a failed drive + */ + pdev = &sh->dev[sh->pd_idx]; + s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) + || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); + qdev = &sh->dev[sh->qd_idx]; + s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) + || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) + || conf->level < 6; + + if (s.written && + (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) + && !test_bit(R5_LOCKED, &pdev->flags) + && (test_bit(R5_UPTODATE, &pdev->flags) || + test_bit(R5_Discard, &pdev->flags))))) && + (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) + && !test_bit(R5_LOCKED, &qdev->flags) + && (test_bit(R5_UPTODATE, &qdev->flags) || + test_bit(R5_Discard, &qdev->flags)))))) + handle_stripe_clean_event(conf, sh, disks, &s.return_bi); + + /* Now we might consider reading some blocks, either to check/generate + * parity, or to satisfy requests + * or to load a block that is being partially written. + */ + if (s.to_read || s.non_overwrite + || (conf->level == 6 && s.to_write && s.failed) + || (s.syncing && (s.uptodate + s.compute < disks)) + || s.replacing + || s.expanding) + handle_stripe_fill(sh, &s, disks); + /* Now to consider new write requests and what else, if anything * should be read. We do not handle new writes when: * 1/ A 'write' operation (copy+xor) is already in flight. -- cgit v1.1 From ca64cae96037de16e4af92678814f5d4bf0c1c65 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 21 Nov 2012 16:33:40 +1100 Subject: md/raid5: Make sure we clear R5_Discard when discard is finished. commit 9e44476851e91c86c98eb92b9bc27fb801f89072 MD: raid5 avoid unnecessary zero page for trim change raid5 to clear R5_Discard when the complete request is handled rather than when submitting the per-device discard request. However it did not clear R5_Discard for the parity device. This means that if the stripe_head was reused before it expired from the cache, the setting would be wrong and a hang would result. Also if the R5_Uptodate bit happens to be set, R5_Discard again won't be cleared. But R5_Uptodate really should be clear at this point. So make sure R5_Discard is cleared in all cases, and clear R5_Uptodate when a 'discard' completes. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 0fb9885..a450268 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf, dev = &sh->dev[i]; if (!test_bit(R5_LOCKED, &dev->flags) && (test_bit(R5_UPTODATE, &dev->flags) || - test_and_clear_bit(R5_Discard, &dev->flags))) { + test_bit(R5_Discard, &dev->flags))) { /* We can return any write requests */ struct bio *wbi, *wbi2; pr_debug("Return write for disc %d\n", i); + if (test_and_clear_bit(R5_Discard, &dev->flags)) + clear_bit(R5_UPTODATE, &dev->flags); wbi = dev->written; dev->written = NULL; while (wbi && wbi->bi_sector < @@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, !test_bit(STRIPE_DEGRADED, &sh->state), 0); } - } + } else if (test_bit(R5_Discard, &sh->dev[i].flags)) + clear_bit(R5_Discard, &sh->dev[i].flags); if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) if (atomic_dec_and_test(&conf->pending_full_writes)) -- cgit v1.1 From ef6c5be658f6a70c1256fbd18e18ee0dc24c3386 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Wed, 21 Nov 2012 14:21:51 -0500 Subject: fix incorrect NR_FREE_PAGES accounting (appears like memory leak) There have been some 3.7-rc reports of vm issues, including some kswapd bugs and, more importantly, some memory "leaks": http://www.spinics.net/lists/linux-mm/msg46187.html https://bugzilla.kernel.org/show_bug.cgi?id=50181 Commit 1fb3f8ca0e92 ("mm: compaction: capture a suitable high-order page immediately when it is made available") took split_free_page() and reused it for the compaction code. It does something curious with capture_free_page() (previously known as split_free_page()): int capture_free_page(struct page *page, int alloc_order, ... __mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order)); - /* Split into individual pages */ - set_page_refcounted(page); - split_page(page, order); + if (alloc_order != order) + expand(zone, page, alloc_order, order, + &zone->free_area[order], migratetype); Note that expand() puts the pages _back_ in the allocator, but it does not bump NR_FREE_PAGES. We "return" 'alloc_order' worth of pages, but we accounted for removing 'order' in the __mod_zone_page_state() call. For the old split_page()-style use (order==alloc_order) the bug will not trigger. But, when called from the compaction code where we occasionally get a larger page out of the buddy allocator than we need, we will run in to this. This patch simply changes the NR_FREE_PAGES manipulation to the correct 'alloc_order' instead of 'order'. I've been able to repeatedly trigger this in my testing environment. The amount "leaked" very closely tracks the imbalance I see in buddy pages vs. NR_FREE_PAGES. I have confirmed that this patch fixes the imbalance Signed-off-by: Dave Hansen Acked-by: Mel Gorman Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7bb35ac..bcb72c6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1405,7 +1405,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype) mt = get_pageblock_migratetype(page); if (unlikely(mt != MIGRATE_ISOLATE)) - __mod_zone_freepage_state(zone, -(1UL << order), mt); + __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt); if (alloc_order != order) expand(zone, page, alloc_order, order, -- cgit v1.1 From 4fe198e6b136c516df493ec325ab8f70d470f477 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Mon, 19 Nov 2012 06:42:21 +0000 Subject: netfilter: ipset: Fix range bug in hash:ip,port,net Due to the missing ininitalization at adding/deleting entries, when a plain_ip,port,net element was the object, multiple elements were added/deleted instead. The bug came from the missing dangling default initialization. The error-prone default initialization is corrected in all hash:* types. Signed-off-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipset/ip_set_hash_ip.c | 4 ++-- net/netfilter/ipset/ip_set_hash_ipport.c | 7 +++---- net/netfilter/ipset/ip_set_hash_ipportip.c | 7 +++---- net/netfilter/ipset/ip_set_hash_ipportnet.c | 7 +++++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index ec3dba5..5c0b785 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c @@ -173,6 +173,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], return adtfn(set, &nip, timeout, flags); } + ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -185,8 +186,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; + } hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index 0171f75..6283351 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c @@ -162,7 +162,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipport4_elem data = { }; - u32 ip, ip_to = 0, p = 0, port, port_to; + u32 ip, ip_to, p = 0, port, port_to; u32 timeout = h->timeout; bool with_ports = false; int ret; @@ -210,7 +210,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip = ntohl(data.ip); + ip_to = ip = ntohl(data.ip); if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -223,8 +223,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; + } port_to = port = ntohs(data.port); if (with_ports && tb[IPSET_ATTR_PORT_TO]) { diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 6344ef5..6a21271 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -166,7 +166,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipportip4_elem data = { }; - u32 ip, ip_to = 0, p = 0, port, port_to; + u32 ip, ip_to, p = 0, port, port_to; u32 timeout = h->timeout; bool with_ports = false; int ret; @@ -218,7 +218,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip = ntohl(data.ip); + ip_to = ip = ntohl(data.ip); if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -231,8 +231,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; + } port_to = port = ntohs(data.port); if (with_ports && tb[IPSET_ATTR_PORT_TO]) { diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index cb71f9a..2d5cd4e 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -215,8 +215,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 }; - u32 ip, ip_to = 0, p = 0, port, port_to; - u32 ip2_from = 0, ip2_to, ip2_last, ip2; + u32 ip, ip_to, p = 0, port, port_to; + u32 ip2_from, ip2_to, ip2_last, ip2; u32 timeout = h->timeout; bool with_ports = false; u8 cidr; @@ -286,6 +286,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } + ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -306,6 +307,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], if (port > port_to) swap(port, port_to); } + + ip2_to = ip2_from; if (tb[IPSET_ATTR_IP2_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to); if (ret) -- cgit v1.1 From e93b5f9f320db431ec8623a4c667811007e07fd7 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 21 Nov 2012 01:37:38 +0000 Subject: netfilter: cttimeout: fix buffer overflow Chen Gang reports: the length of nla_data(cda[CTA_TIMEOUT_NAME]) is not limited in server side. And indeed, its used to strcpy to a fixed-sized buffer. Fortunately, nfnetlink users need CAP_NET_ADMIN. Reported-by: Chen Gang Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_cttimeout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 8847b4d..701c88a 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -41,7 +41,8 @@ MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tu static LIST_HEAD(cttimeout_list); static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { - [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING }, + [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING, + .len = CTNL_TIMEOUT_NAME_MAX - 1}, [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 }, [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 }, [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED }, -- cgit v1.1 From 0181bd5dea2ed0696f84591a92da0b6a1f1a2e62 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 21 Nov 2012 18:37:38 -0500 Subject: drm/radeon: add new SI pci id Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- include/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index af1cbaf..c5c35e6 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -210,6 +210,7 @@ {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x679B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ -- cgit v1.1 From ace5a9b8dbc66ada0aa8c5f67b93527590822c7c Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 21 Nov 2012 13:21:12 +0100 Subject: drm/nouveau: use the correct fence implementation for nv50 Only compile time tested, noticed nv50_fence_create was never used, so fix this. This will probably fix vblank on nv50 cards. Hopefully this is still in time for 3.7 final release. Signed-off-by: Maarten Lankhorst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 0910125..8503b2e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -129,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm) /* initialise synchronisation routines */ if (device->card_type < NV_10) ret = nv04_fence_create(drm); - else if (device->chipset < 0x84) ret = nv10_fence_create(drm); + else if (device->card_type < NV_50) ret = nv10_fence_create(drm); + else if (device->chipset < 0x84) ret = nv50_fence_create(drm); else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); else ret = nvc0_fence_create(drm); if (ret) { -- cgit v1.1 From e7c0c3fa29280d62aa5e11101a674bb3064bd791 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 22 Nov 2012 14:42:49 +1100 Subject: md/raid10: close race that lose writes lost when replacement completes. When a replacement operation completes there is a small window when the original device is marked 'faulty' and the replacement still looks like a replacement. The faulty should be removed and the replacement moved in place very quickly, bit it isn't instant. So the code write out to the array must handle the possibility that the only working device for some slot in the replacement - but it doesn't. If the primary device is faulty it just gives up. This can lead to corruption. So make the code more robust: if either the primary or the replacement is present and working, write to them. Only when neither are present do we give up. This bug has been present since replacement was introduced in 3.3, so it is suitable for any -stable kernel since then. Reported-by: "George Spelvin" Cc: stable@vger.kernel.org Signed-off-by: NeilBrown --- drivers/md/raid10.c | 129 +++++++++++++++++++++++++++------------------------- 1 file changed, 68 insertions(+), 61 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d1295af..ad03251 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1334,18 +1334,21 @@ retry_write: blocked_rdev = rrdev; break; } + if (rdev && (test_bit(Faulty, &rdev->flags) + || test_bit(Unmerged, &rdev->flags))) + rdev = NULL; if (rrdev && (test_bit(Faulty, &rrdev->flags) || test_bit(Unmerged, &rrdev->flags))) rrdev = NULL; r10_bio->devs[i].bio = NULL; r10_bio->devs[i].repl_bio = NULL; - if (!rdev || test_bit(Faulty, &rdev->flags) || - test_bit(Unmerged, &rdev->flags)) { + + if (!rdev && !rrdev) { set_bit(R10BIO_Degraded, &r10_bio->state); continue; } - if (test_bit(WriteErrorSeen, &rdev->flags)) { + if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { sector_t first_bad; sector_t dev_sector = r10_bio->devs[i].addr; int bad_sectors; @@ -1387,8 +1390,10 @@ retry_write: max_sectors = good_sectors; } } - r10_bio->devs[i].bio = bio; - atomic_inc(&rdev->nr_pending); + if (rdev) { + r10_bio->devs[i].bio = bio; + atomic_inc(&rdev->nr_pending); + } if (rrdev) { r10_bio->devs[i].repl_bio = bio; atomic_inc(&rrdev->nr_pending); @@ -1444,69 +1449,71 @@ retry_write: for (i = 0; i < conf->copies; i++) { struct bio *mbio; int d = r10_bio->devs[i].devnum; - if (!r10_bio->devs[i].bio) - continue; + if (r10_bio->devs[i].bio) { + struct md_rdev *rdev = conf->mirrors[d].rdev; + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, + max_sectors); + r10_bio->devs[i].bio = mbio; + + mbio->bi_sector = (r10_bio->devs[i].addr+ + choose_data_offset(r10_bio, + rdev)); + mbio->bi_bdev = rdev->bdev; + mbio->bi_end_io = raid10_end_write_request; + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; + mbio->bi_private = r10_bio; - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); - md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, - max_sectors); - r10_bio->devs[i].bio = mbio; + atomic_inc(&r10_bio->remaining); - mbio->bi_sector = (r10_bio->devs[i].addr+ - choose_data_offset(r10_bio, - conf->mirrors[d].rdev)); - mbio->bi_bdev = conf->mirrors[d].rdev->bdev; - mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; - mbio->bi_private = r10_bio; + cb = blk_check_plugged(raid10_unplug, mddev, + sizeof(*plug)); + if (cb) + plug = container_of(cb, struct raid10_plug_cb, + cb); + else + plug = NULL; + spin_lock_irqsave(&conf->device_lock, flags); + if (plug) { + bio_list_add(&plug->pending, mbio); + plug->pending_cnt++; + } else { + bio_list_add(&conf->pending_bio_list, mbio); + conf->pending_count++; + } + spin_unlock_irqrestore(&conf->device_lock, flags); + if (!plug) + md_wakeup_thread(mddev->thread); + } - atomic_inc(&r10_bio->remaining); + if (r10_bio->devs[i].repl_bio) { + struct md_rdev *rdev = conf->mirrors[d].replacement; + if (rdev == NULL) { + /* Replacement just got moved to main 'rdev' */ + smp_mb(); + rdev = conf->mirrors[d].rdev; + } + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, + max_sectors); + r10_bio->devs[i].repl_bio = mbio; + + mbio->bi_sector = (r10_bio->devs[i].addr + + choose_data_offset( + r10_bio, rdev)); + mbio->bi_bdev = rdev->bdev; + mbio->bi_end_io = raid10_end_write_request; + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; + mbio->bi_private = r10_bio; - cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); - if (cb) - plug = container_of(cb, struct raid10_plug_cb, cb); - else - plug = NULL; - spin_lock_irqsave(&conf->device_lock, flags); - if (plug) { - bio_list_add(&plug->pending, mbio); - plug->pending_cnt++; - } else { + atomic_inc(&r10_bio->remaining); + spin_lock_irqsave(&conf->device_lock, flags); bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; + spin_unlock_irqrestore(&conf->device_lock, flags); + if (!mddev_check_plugged(mddev)) + md_wakeup_thread(mddev->thread); } - spin_unlock_irqrestore(&conf->device_lock, flags); - if (!plug) - md_wakeup_thread(mddev->thread); - - if (!r10_bio->devs[i].repl_bio) - continue; - - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); - md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, - max_sectors); - r10_bio->devs[i].repl_bio = mbio; - - /* We are actively writing to the original device - * so it cannot disappear, so the replacement cannot - * become NULL here - */ - mbio->bi_sector = (r10_bio->devs[i].addr + - choose_data_offset( - r10_bio, - conf->mirrors[d].replacement)); - mbio->bi_bdev = conf->mirrors[d].replacement->bdev; - mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; - mbio->bi_private = r10_bio; - - atomic_inc(&r10_bio->remaining); - spin_lock_irqsave(&conf->device_lock, flags); - bio_list_add(&conf->pending_bio_list, mbio); - conf->pending_count++; - spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); } /* Don't remove the bias on 'remaining' (one_write_done) until -- cgit v1.1 From 884162df2aadd7414bef4935e1a54976fd4e3988 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 22 Nov 2012 15:12:09 +1100 Subject: md/raid10: decrement correct pending counter when writing to replacement. When a write to a replacement device completes, we carefully and correctly found the rdev that the write actually went to and the blithely called rdev_dec_pending on the primary rdev, even if this write was to the replacement. This means that any writes to an array while a replacement was ongoing would cause the nr_pending count for the primary device to go negative, so it could never be removed. This bug has been present since replacement was introduced in 3.3, so it is suitable for any -stable kernel since then. Reported-by: "George Spelvin" Cc: stable@vger.kernel.org Signed-off-by: NeilBrown --- drivers/md/raid10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ad03251..0d5d0ff 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error) */ one_write_done(r10_bio); if (dec_rdev) - rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); + rdev_dec_pending(rdev, conf->mddev); } /* -- cgit v1.1 From 441a179dafc0f99fc8b3a8268eef66958621082e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 21 Nov 2012 19:27:23 +0000 Subject: [PARISC] fix user-triggerable panic on parisc int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset, unsigned int sigsetsize) { sigset_t old_set, new_set; int ret; if (set && get_sigset32(set, &new_set, sigsetsize)) ... static int get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) { compat_sigset_t s; int r; if (sz != sizeof *set) panic("put_sigset32()"); In other words, rt_sigprocmask(69, (void *)69, 69) done by 32bit process will promptly panic the box. Signed-off-by: Al Viro Cc: Signed-off-by: James Bottomley --- arch/parisc/kernel/signal32.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index fd49aed..5dede04 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) { compat_sigset_t s; - if (sz != sizeof *set) panic("put_sigset32()"); + if (sz != sizeof *set) + return -EINVAL; sigset_64to32(&s, set); return copy_to_user(up, &s, sizeof s); @@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) compat_sigset_t s; int r; - if (sz != sizeof *set) panic("put_sigset32()"); + if (sz != sizeof *set) + return -EINVAL; if ((r = copy_from_user(&s, up, sz)) == 0) { sigset_32to64(set, &s); -- cgit v1.1 From 8ad9375f8b7c709b89f7de4de413bb2644ba3c24 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 21 Nov 2012 21:48:51 +0200 Subject: OMAPDSS: do not fail if dpll4_m4_ck is missing Do not fail if dpll4_m4_ck is missing. The clock is not there on omap24xx, so this should not be a hard error. The patch retains the functionality before the commit 185bae10 (OMAPDSS: DSS: Cleanup cpu_is_xxxx checks). Signed-off-by: Aaro Koskinen Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 0bb7406..5f6eea8 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -697,11 +697,15 @@ static int dss_get_clocks(void) dss.dss_clk = clk; - clk = clk_get(NULL, dss.feat->clk_name); - if (IS_ERR(clk)) { - DSSERR("Failed to get %s\n", dss.feat->clk_name); - r = PTR_ERR(clk); - goto err; + if (dss.feat->clk_name) { + clk = clk_get(NULL, dss.feat->clk_name); + if (IS_ERR(clk)) { + DSSERR("Failed to get %s\n", dss.feat->clk_name); + r = PTR_ERR(clk); + goto err; + } + } else { + clk = NULL; } dss.dpll4_m4_ck = clk; -- cgit v1.1 From 947d299686aa9cc8aecf749d54e8475c6e498956 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 22 Nov 2012 20:27:59 +0100 Subject: ALSA: snd-usb: properly initialize the sync endpoint Jeffrey Barish reported an obvious bug in the pcm part of the usb-audio driver which causes the code to not initialize the sync endpoint from configure_endpoint(). Reported-by: Jeffrey Barish Signed-off-by: Daniel Mack Cc: stable@kernel.org [3.5+] Signed-off-by: Takashi Iwai --- sound/usb/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 5c12a3f..ef6fa24 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -459,7 +459,7 @@ static int configure_endpoint(struct snd_usb_substream *subs) return ret; if (subs->sync_endpoint) - ret = snd_usb_endpoint_set_params(subs->data_endpoint, + ret = snd_usb_endpoint_set_params(subs->sync_endpoint, subs->pcm_format, subs->channels, subs->period_bytes, -- cgit v1.1 From 636174219b52b5a8bc51bc23bbcba97cd30a65e3 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Thu, 22 Nov 2012 23:04:14 +0200 Subject: ipv4: do not cache looped multicasts Starting from 3.6 we cache output routes for multicasts only when using route to 224/4. For local receivers we can set RTCF_LOCAL flag depending on the membership but in such case we use maddr and saddr which are not caching keys as before. Additionally, we can not use same place to cache routes that differ in RTCF_LOCAL flag value. Fix it by caching only RTCF_MULTICAST entries without RTCF_LOCAL (send-only, no loopback). As a side effect, we avoid unneeded lookup for fnhe when not caching because multicasts are not redirected and they do not learn PMTU. Thanks to Maxime Bizon for showing the caching problems in __mkroute_output for 3.6 kernels: different RTCF_LOCAL flag in cache can lead to wrong ip_mc_output or ip_output call and the visible problem is that traffic can not reach local receivers via loopback. Reported-by: Maxime Bizon Tested-by: Maxime Bizon Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller --- net/ipv4/route.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 200d287..df25142 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1785,6 +1785,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; + do_cache = true; if (type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; fi = NULL; @@ -1793,6 +1794,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, fl4->flowi4_proto)) flags &= ~RTCF_LOCAL; + else + do_cache = false; /* If multicast route do not exist use * default one, but do not gateway in this case. * Yes, it is hack. @@ -1802,8 +1805,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, } fnhe = NULL; - do_cache = fi != NULL; - if (fi) { + do_cache &= fi != NULL; + if (do_cache) { struct rtable __rcu **prth; struct fib_nh *nh = &FIB_RES_NH(*res); -- cgit v1.1 From 958f9889950ef257f601c4902137caff291d5dd7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 18 Nov 2012 06:25:07 +0100 Subject: i2c: mxs: Handle i2c DMA failure properly Properly terminate the DMA transfer in case the DMA PIO transfer or setup fails for any reason. Signed-off-by: Marek Vasut Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mxs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 286ca19..0670da7 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -287,12 +287,14 @@ read_init_dma_fail: select_init_dma_fail: dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); select_init_pio_fail: + dmaengine_terminate_all(i2c->dmach); return -EINVAL; /* Write failpath. */ write_init_dma_fail: dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); write_init_pio_fail: + dmaengine_terminate_all(i2c->dmach); return -EINVAL; } -- cgit v1.1 From bb4618823a3389086f157fafb2a0d97cade8d89f Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 23 Nov 2012 13:25:39 +1100 Subject: powerpc/pseries: Fix oops with MSIs when missing EEH PEs The new EEH code introduced a small regression, if the EEH PEs are missin (which happens currently in qemu for example), it will deref a NULL pointer in the MSI code. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/msi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index d19f497..e5b0847 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -220,7 +220,8 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) /* Get the top level device in the PE */ edev = of_node_to_eeh_dev(dn); - edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); + if (edev->pe) + edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); dn = eeh_dev_to_of_node(edev); if (!dn) return NULL; -- cgit v1.1 From eac7cc52c6b410e542af431b2ee93f3d7dbfb6af Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 6 Nov 2012 11:47:13 +0100 Subject: floppy: destroy floppy workqueue before cleaning up the queue We need to first destroy the floppy_wq workqueue before cleaning up the queue. Otherwise we might race with still pending work with the workqueue, but all the block queue already gone. This might lead to various oopses, such as CPU 0 Pid: 6, comm: kworker/u:0 Not tainted 3.7.0-rc4 #1 Bochs Bochs RIP: 0010:[] [] blk_peek_request+0xd5/0x1c0 RSP: 0000:ffff88000dc7dd88 EFLAGS: 00010092 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000000 RDX: ffff88000f602688 RSI: ffffffff81fd95d8 RDI: 6b6b6b6b6b6b6b6b RBP: ffff88000dc7dd98 R08: ffffffff81fd95c8 R09: 0000000000000000 R10: ffffffff81fd9480 R11: 0000000000000001 R12: 6b6b6b6b6b6b6b6b R13: ffff88000dc7dfd8 R14: ffff88000dc7dfd8 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffffffff81e21000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001e11000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/u:0 (pid: 6, threadinfo ffff88000dc7c000, task ffff88000dc5ecc0) Stack: 0000000000000000 0000000000000000 ffff88000dc7ddb8 ffffffff8134efee ffff88000dc7ddb8 0000000000000000 ffff88000dc7dde8 ffffffff814aef3c ffffffff81e75d80 ffff88000dc0c640 ffff88000fbfb000 ffffffff814aed90 Call Trace: [] blk_fetch_request+0xe/0x30 [] redo_fd_request+0x1ac/0x400 [] ? start_motor+0x130/0x130 [] process_one_work+0x136/0x450 [] ? manage_workers+0x205/0x2e0 [] worker_thread+0x14d/0x420 [] ? rescuer_thread+0x1a0/0x1a0 [] kthread+0xba/0xc0 [] ? __kthread_parkme+0x80/0x80 [] ret_from_fork+0x7a/0xb0 [] ? __kthread_parkme+0x80/0x80 Code: 0f 84 c0 00 00 00 83 f8 01 0f 85 e2 00 00 00 81 4b 40 00 00 80 00 48 89 df e8 58 f8 ff ff be fb ff ff ff fe ff ff <49> 8b 1c 24 49 39 dc 0f 85 2e ff ff ff 41 0f b6 84 24 28 04 00 RIP [] blk_peek_request+0xd5/0x1c0 RSP Reported-by: Fengguang Wu Tested-by: Fengguang Wu Signed-off-by: Jiri Kosina Signed-off-by: Jens Axboe --- drivers/block/floppy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 1c49d71..2ddd64a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4330,6 +4330,7 @@ out_unreg_region: out_unreg_blkdev: unregister_blkdev(FLOPPY_MAJOR, "fd"); out_put_disk: + destroy_workqueue(floppy_wq); for (drive = 0; drive < N_DRIVE; drive++) { if (!disks[drive]) break; @@ -4340,7 +4341,6 @@ out_put_disk: } put_disk(disks[drive]); } - destroy_workqueue(floppy_wq); return err; } @@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void) unregister_blkdev(FLOPPY_MAJOR, "fd"); platform_driver_unregister(&floppy_driver); + destroy_workqueue(floppy_wq); + for (drive = 0; drive < N_DRIVE; drive++) { del_timer_sync(&motor_off_timer[drive]); @@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void) cancel_delayed_work_sync(&fd_timeout); cancel_delayed_work_sync(&fd_timer); - destroy_workqueue(floppy_wq); if (atomic_read(&usage_count)) floppy_release_irq_and_dma(); -- cgit v1.1 From a8c32a5c98943d370ea606a2e7dc04717eb92206 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 6 Nov 2012 12:24:26 +0100 Subject: dm: fix deadlock with request based dm and queue request_fn recursion Request based dm attempts to re-run the request queue off the request completion path. If used with a driver that potentially does end_io from its request_fn, we could deadlock trying to recurse back into request dispatch. Fix this by punting the request queue run to kblockd. Tested to fix a quickly reproducible deadlock in such a scenario. Cc: stable@kernel.org Acked-by: Alasdair G Kergon Signed-off-by: Jens Axboe --- drivers/md/dm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 02db9183..77e6eff 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue) if (!md_in_flight(md)) wake_up(&md->wait); + /* + * Run this off this callpath, as drivers could invoke end_io while + * inside their request_fn (and holding the queue lock). Calling + * back into ->request_fn() could deadlock attempting to grab the + * queue lock again. + */ if (run_queue) - blk_run_queue(md->queue); + blk_run_queue_async(md->queue); /* * dm_put() must be at the end of this function. See the comment above -- cgit v1.1 From 3208795e612406df04a32b46eb5ea5fccfa51d69 Mon Sep 17 00:00:00 2001 From: Selvan Mani Date: Wed, 7 Nov 2012 06:03:37 -0700 Subject: mtip32xx: fix potential crash on SEC_ERASE_UNIT The mtip driver lifted this code from elsewhere and then added a special handling check for SEC_ERASE_UNIT. If the caller tries to do a security erase but passes no output data for the command then outbuf is not allocated and the driver duly explodes. Reported-by: Dan Carpenter Signed-off-by: Alan Cox Signed-off-by: Selvan Mani Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index adc6f36..dfb7196 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2218,8 +2218,8 @@ static int exec_drive_taskfile(struct driver_data *dd, fis.device); /* check for erase mode support during secure erase.*/ - if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) - && (outbuf[0] & MTIP_SEC_ERASE_MODE)) { + if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf && + (outbuf[0] & MTIP_SEC_ERASE_MODE)) { erasemode = 1; } -- cgit v1.1 From eda45314922f500f3547d36d317efc05ed823e3e Mon Sep 17 00:00:00 2001 From: Selvan Mani Date: Wed, 7 Nov 2012 06:03:53 -0700 Subject: mtip32xx: Fix to make lba address correct in big-endian systems Earlier lba address was assigned directly to lba_low and lba_low_ex, which would result in a different number (bytes reversed) in big-endian systems. Now assigning lba address byte-by-byte to fis. Reported-by: Dan Carpenter Signed-off-by: Selvan Mani Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index dfb7196..df46b5a 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2465,8 +2465,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, fis->opts = 1 << 7; fis->command = (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); - *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); - *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); + fis->lba_low = start & 0xFF; + fis->lba_mid = (start >> 8) & 0xFF; + fis->lba_hi = (start >> 16) & 0xFF; + fis->lba_low_ex = (start >> 24) & 0xFF; + fis->lba_mid_ex = (start >> 32) & 0xFF; + fis->lba_hi_ex = (start >> 40) & 0xFF; fis->device = 1 << 6; fis->features = nsect & 0xFF; fis->features_ex = (nsect >> 8) & 0xFF; -- cgit v1.1 From 4b9e884523f63f7bfd6fcbcdfe6f9f9545d98c13 Mon Sep 17 00:00:00 2001 From: Selvan Mani Date: Wed, 7 Nov 2012 06:03:56 -0700 Subject: mtip32xx: Fix incorrect mask used for erase mode Previous commit use value 3 for erasemode mask. Changing the mask to correct value to 2 Signed-off-by: Selvan Mani Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 5f4a917..8498e99 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -34,7 +34,7 @@ #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 /* check for erase mode support during secure erase */ -#define MTIP_SEC_ERASE_MODE 0x3 +#define MTIP_SEC_ERASE_MODE 0x2 /* # of times to retry timed out/failed IOs */ #define MTIP_MAX_RETRIES 2 -- cgit v1.1 From 7c5d62388e88729775b10a1748f2810e413f1e51 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 8 Nov 2012 07:58:53 +0100 Subject: mtip32xx: fix shift larger than type warning If we're building a 32-bit kernel and CONFIG_LBADF isn't set, sector_t is 32-bits wide. The shifts by 32 and 40 are thus larger than we support. Cast the sector offset to a u64 to avoid these warnings. Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index df46b5a..faa5591 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2439,7 +2439,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, * return value * None */ -static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, +static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, int nsect, int nents, int tag, void *callback, void *data, int dir) { @@ -2447,6 +2447,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, struct mtip_port *port = dd->port; struct mtip_cmd *command = &port->commands[tag]; int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + u64 start = sector; /* Map the scatter list for DMA access */ nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); -- cgit v1.1 From 298d80152c895859bd128552db7a5b228e8a23f7 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 8 Nov 2012 17:35:38 +0800 Subject: mtip32xx: fix potential NULL pointer dereference in mtip_timeout_function() The dereference to port should be moved below the NULL test. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index faa5591..9694dd9 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data) struct mtip_cmd *command; int tag, cmdto_cnt = 0; unsigned int bit, group; - unsigned int num_command_slots = port->dd->slot_groups * 32; + unsigned int num_command_slots; unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; if (unlikely(!port)) @@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data) } /* clear the tag accumulator */ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + num_command_slots = port->dd->slot_groups * 32; for (tag = 0; tag < num_command_slots; tag++) { /* -- cgit v1.1 From 11cfb6ff736dc89b0447b8902d6912692303f6af Mon Sep 17 00:00:00 2001 From: Ed Cashin Date: Thu, 8 Nov 2012 19:17:15 -0500 Subject: aoe: avoid running request handler on plugged queue Calling the request handler directly on a plugged queue defeats the performance improvements provided by the plugging mechanism. Use the __blk_run_queue function instead of calling the request handler directly, so that we don't interfere with the block layer's ability to plug the queue. Signed-off-by: Ed Cashin Signed-off-by: Jens Axboe --- drivers/block/aoe/aoecmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 3804a0a..9fe4f18 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) /* cf. http://lkml.org/lkml/2006/10/31/28 */ if (!fastfail) - q->request_fn(q); + __blk_run_queue(q); } static void -- cgit v1.1 From 836413e8c78ecbc55aa31f3cb600f8ee1aa355a2 Mon Sep 17 00:00:00 2001 From: Selvan Mani Date: Wed, 14 Nov 2012 06:16:35 -0700 Subject: mtip32xx: Fix padding issue Hi Jens, Another tiny patch. Removed __packed before the struct smart_attr and added __packed at end of the structure to fix padding issue. Signed-off-by: Selvan Mani Signed-off-by: Asai Thambi S P Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 8498e99..b174264 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -155,14 +155,14 @@ enum { MTIP_DDF_REBUILD_FAILED_BIT = 8, }; -__packed struct smart_attr{ +struct smart_attr { u8 attr_id; u16 flags; u8 cur; u8 worst; u32 data; u8 res[3]; -}; +} __packed; /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { -- cgit v1.1 From 893d290f1d7496db97c9471bc352ad4a11dc8a25 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 22 Nov 2012 02:00:11 -0800 Subject: block: Don't access request after it might be freed After we've done __elv_add_request() and __blk_run_queue() in blk_execute_rq_nowait(), the request might finish and be freed immediately. Therefore checking if the type is REQ_TYPE_PM_RESUME isn't safe afterwards, because if it isn't, rq might be gone. Instead, check beforehand and stash the result in a temporary. This fixes crashes in blk_execute_rq_nowait() I get occasionally when running with lots of memory debugging options enabled -- I think this race is usually harmless because the window for rq to be reallocated is so small. Signed-off-by: Roland Dreier Cc: stable@kernel.org Signed-off-by: Jens Axboe --- block/blk-exec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/block/blk-exec.c b/block/blk-exec.c index 8b6dc5b..f71eac3 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, rq_end_io_fn *done) { int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; + bool is_pm_resume; WARN_ON(irqs_disabled()); rq->rq_disk = bd_disk; rq->end_io = done; + /* + * need to check this before __blk_run_queue(), because rq can + * be freed before that returns. + */ + is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME; spin_lock_irq(q->queue_lock); @@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, __elv_add_request(q, rq, where); __blk_run_queue(q); /* the queue is stopped so it won't be run */ - if (rq->cmd_type == REQ_TYPE_PM_RESUME) + if (is_pm_resume) q->request_fn(q); spin_unlock_irq(q->queue_lock); } -- cgit v1.1 From 0ec7ec75f674dbf48010081383263771f2611e72 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 15 Nov 2012 12:53:59 +0100 Subject: MIPS: Merge overlapping bootmem ranges Without this, we may end up with something like this in /proc/iomem: 01100000-014fffff : System RAM 01100000-013bf48f : Kernel code 013bf490-0149e01f : Kernel data 01500000-0c0fffff : System RAM but the two System RAM ranges should be one single range. This particular case will result in kexec failure on Octeon systems if the kernel being loaded by kexec is bigger than the already running kernel. Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a53f8ec..290dc6a 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; void __init add_memory_region(phys_t start, phys_t size, long type) { int x = boot_mem_map.nr_map; - struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; + int i; /* Sanity check */ if (start + size < start) { @@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type) } /* - * Try to merge with previous entry if any. This is far less than - * perfect but is sufficient for most real world cases. + * Try to merge with existing entry, if any. */ - if (x && prev->addr + prev->size == start && prev->type == type) { - prev->size += size; + for (i = 0; i < boot_mem_map.nr_map; i++) { + struct boot_mem_map_entry *entry = boot_mem_map.map + i; + unsigned long top; + + if (entry->type != type) + continue; + + if (start + size < entry->addr) + continue; /* no overlap */ + + if (entry->addr + entry->size < start) + continue; /* no overlap */ + + top = max(entry->addr + entry->size, start + size); + entry->addr = min(entry->addr, start); + entry->size = top - entry->addr; + return; } - if (x == BOOT_MEM_MAP_MAX) { + if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { pr_err("Ooops! Too many entries in the memory map!\n"); return; } -- cgit v1.1 From f93a1a00f2bd550f86fd1a9f83c493755aecd15f Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Thu, 15 Nov 2012 18:16:14 -0500 Subject: MIPS: Fix crash that occurs when function tracing is enabled A recent patch changed some irq routines from inlines to functions. These routines are called by the tracer code. Now that they're functions, if they are compiled for function tracing they will call the tracer and crash the system due to infinite recursion. The fix disables tracing in these functions by using "notrace" in the function definition. Signed-off-by: Al Cooper Reviewed-by: David Daney Pathchwork: https://patchwork.linux-mips.org/patch/4564/ Signed-off-by: Ralf Baechle --- arch/mips/lib/mips-atomic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index e091430..cd160be 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c @@ -56,7 +56,7 @@ __asm__( " .set pop \n" " .endm \n"); -void arch_local_irq_disable(void) +notrace void arch_local_irq_disable(void) { preempt_disable(); __asm__ __volatile__( @@ -93,7 +93,7 @@ __asm__( " .set pop \n" " .endm \n"); -unsigned long arch_local_irq_save(void) +notrace unsigned long arch_local_irq_save(void) { unsigned long flags; preempt_disable(); @@ -135,7 +135,7 @@ __asm__( " .set pop \n" " .endm \n"); -void arch_local_irq_restore(unsigned long flags) +notrace void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; @@ -159,7 +159,7 @@ void arch_local_irq_restore(unsigned long flags) EXPORT_SYMBOL(arch_local_irq_restore); -void __arch_local_irq_restore(unsigned long flags) +notrace void __arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; -- cgit v1.1 From a3cea9894157c20a5b1ec08b7e0b5f2019740c10 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 22 Nov 2012 11:58:22 +0100 Subject: MPI: Fix compilation on MIPS with GCC 4.4 and newer Since 4.4 GCC on MIPS no longer recognizes the "h" constraint, leading to this build failure: CC lib/mpi/generic_mpih-mul1.o lib/mpi/generic_mpih-mul1.c: In function 'mpihelp_mul_1': lib/mpi/generic_mpih-mul1.c:50:3: error: impossible constraint in 'asm' This patch updates MPI with the latest umul_ppm implementations for MIPS. Signed-off-by: Manuel Lauss Cc: Linux-MIPS Cc: Dmitry Kasatkin Cc: James Morris Patchwork: https://patchwork.linux-mips.org/patch/4612/ Signed-off-by: Ralf Baechle --- lib/mpi/longlong.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 678ce4f..095ab15 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h @@ -641,7 +641,14 @@ do { \ ************** MIPS ***************** ***************************************/ #if defined(__mips__) && W_TYPE_SIZE == 32 -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 +#define umul_ppmm(w1, w0, u, v) \ +do { \ + UDItype __ll = (UDItype)(u) * (v); \ + w1 = __ll >> 32; \ + w0 = __ll; \ +} while (0) +#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 #define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ : "=l" ((USItype)(w0)), \ @@ -666,7 +673,15 @@ do { \ ************** MIPS/64 ************** ***************************************/ #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 +#define umul_ppmm(w1, w0, u, v) \ +do { \ + typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ + __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ + w1 = __ll >> 64; \ + w0 = __ll; \ +} while (0) +#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 #define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ : "=l" ((UDItype)(w0)), \ -- cgit v1.1 From b26623dab7eeb1e9f5898c7a49458789dd492f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Wed, 21 Nov 2012 10:07:29 +0000 Subject: 8139cp: revert "set ring address before enabling receiver" This patch reverts b01af4579ec41f48e9b9c774e70bd6474ad210db. The original patch was tested with emulated hardware. Real hardware chokes. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=47041 Signed-off-by: Francois Romieu Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/8139cp.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 1c81825..b01f83a 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp) cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); - cpw32_f(HiTxRingAddr, 0); - cpw32_f(HiTxRingAddr + 4, 0); - - ring_dma = cp->ring_dma; - cpw32_f(RxRingAddr, ring_dma & 0xffffffff); - cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); - - ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; - cpw32_f(TxRingAddr, ring_dma & 0xffffffff); - cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); - cp_start_hw(cp); cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ @@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp) cpw8(Config5, cpr8(Config5) & PMEStatus); + cpw32_f(HiTxRingAddr, 0); + cpw32_f(HiTxRingAddr + 4, 0); + + ring_dma = cp->ring_dma; + cpw32_f(RxRingAddr, ring_dma & 0xffffffff); + cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); + + ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; + cpw32_f(TxRingAddr, ring_dma & 0xffffffff); + cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); + cpw16(MultiIntr, 0); cpw8_f(Cfg9346, Cfg9346_Lock); -- cgit v1.1 From cc9b310165e7ea2f3dc90e1eea6ce57c9b7981d1 Mon Sep 17 00:00:00 2001 From: Zhi Yong Wu Date: Thu, 22 Nov 2012 00:10:01 +0000 Subject: vxlan: fix command usage in its doc Some commands don't work in its example doc. The patch will fix it. Signed-off-by: Zhi Yong Wu Signed-off-by: David S. Miller --- Documentation/networking/vxlan.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/networking/vxlan.txt b/Documentation/networking/vxlan.txt index 5b34b76..6d99351 100644 --- a/Documentation/networking/vxlan.txt +++ b/Documentation/networking/vxlan.txt @@ -32,7 +32,7 @@ no entry is in the forwarding table. # ip link delete vxlan0 3. Show vxlan info - # ip -d show vxlan0 + # ip -d link show vxlan0 It is possible to create, destroy and display the vxlan forwarding table using the new bridge command. @@ -41,7 +41,7 @@ forwarding table using the new bridge command. # bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0 2. Delete forwarding table entry - # bridge fdb delete 00:17:42:8a:b4:05 + # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0 3. Show forwarding table # bridge fdb show dev vxlan0 -- cgit v1.1 From 4a25417c20fac00b3afd58ce27408f964d19e708 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 22 Nov 2012 07:16:17 +0000 Subject: bnx2x: remove redundant warning log fix bug where a register which was only meant to be read in 578xx/57712 devices causes a bogus error message to be logged when read from other devices. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bd1fd3d..01611b3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9545,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp) */ static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) { - u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); - if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { - BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); - REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp)); + if (!CHIP_IS_E1x(bp)) { + u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { + BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, + 1 << BP_FUNC(bp)); + } } } -- cgit v1.1 From a7227a0faa117d0bc532aea546ae5ac5f89e8ed7 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 23 Nov 2012 20:55:06 +0100 Subject: PM / QoS: fix wrong error-checking condition dev_pm_qos_add_request() can return 0, 1, or a negative error code, therefore the correct error test is "if (error < 0)." Checking just for non-zero return code leads to erroneous setting of the req->dev pointer to NULL, which then leads to a repeated call to dev_pm_qos_add_ancestor_request() in st1232_ts_irq_handler(). This in turn leads to an Oops, when the I2C host adapter is unloaded and reloaded again because of the inconsistent state of its QoS request list. Signed-off-by: Guennadi Liakhovetski Cc: Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 74a67e0..fbbd4ed 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, if (ancestor) error = dev_pm_qos_add_request(ancestor, req, value); - if (error) + if (error < 0) req->dev = NULL; return error; -- cgit v1.1 From 0e622d39197f0b64b9e043fe75ac3634bf9f3a05 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Fri, 23 Nov 2012 12:24:09 +0100 Subject: of/address: sparc: Declare of_iomap as an extern function for sparc again This bug-fix makes sure that of_iomap is defined extern for sparc so that the sparc-specific implementation of_iomap is once again used when including include/linux/of_address.h in a sparc context. OF_GPIO that is now available for sparc relies on this. The bug was inadvertently introduced in a850a75, "of/address: add empty static inlines for !CONFIG_OF", that added a static dummy inline for of_iomap when !CONFIG_OF_ADDRESS. However, CONFIG_OF_ADDRESS is never defined for sparc, but there is a sparc-specific implementation /arch/sparc/kernel/of_device_common.c. This fix takes the same approach as 0bce04b that solved the equivalent problem for of_address_to_resource. Signed-off-by: Andreas Larsson Acked-by: David Miller Signed-off-by: Grant Likely --- arch/sparc/include/asm/prom.h | 5 ++++- include/linux/of_address.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index f930031..67c6257 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -63,10 +63,13 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); -/* SPARC has a local implementation */ +/* SPARC has local implementations */ extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); #define of_address_to_resource of_address_to_resource +void __iomem *of_iomap(struct device_node *node, int index); +#define of_iomap of_iomap + #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/include/linux/of_address.h b/include/linux/of_address.h index e20e3af..0506eb5 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -42,10 +42,12 @@ static inline struct device_node *of_find_matching_node_by_address( { return NULL; } +#ifndef of_iomap static inline void __iomem *of_iomap(struct device_node *device, int index) { return NULL; } +#endif static inline const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) { -- cgit v1.1 From d846b17475d52f037437d125cd19c28f1d36e4f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 24 Nov 2012 11:58:24 +0100 Subject: ALSA: hda - Fix build without CONFIG_PM I forgot this again... codec->in_pm is in #ifdef CONFIG_PM Reported-by: Markus Trippelsdorf Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index cebe2dfd..d010de1 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -95,6 +95,7 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); #ifdef CONFIG_PM +#define codec_in_pm(codec) ((codec)->in_pm) static void hda_power_work(struct work_struct *work); static void hda_keep_power_on(struct hda_codec *codec); #define hda_codec_is_power_on(codec) ((codec)->power_on) @@ -104,6 +105,7 @@ static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up) bus->ops.pm_notify(bus, power_up); } #else +#define codec_in_pm(codec) 0 static inline void hda_keep_power_on(struct hda_codec *codec) {} #define hda_codec_is_power_on(codec) 1 #define hda_call_pm_notify(bus, state) {} @@ -228,7 +230,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, } mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); - if (!codec->in_pm && res && *res == -1 && bus->rirb_error) { + if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { if (bus->response_reset) { snd_printd("hda_codec: resetting BUS due to " "fatal communication error\n"); @@ -238,7 +240,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, goto again; } /* clear reset-flag when the communication gets recovered */ - if (!err || codec->in_pm) + if (!err || codec_in_pm(codec)) bus->response_reset = 0; return err; } -- cgit v1.1 From e716e014384688d1a50d1aa5213ee74748c6d4e0 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Thu, 22 Nov 2012 21:58:26 +0000 Subject: powerpc/eeh: Do not invalidate PE properly While the EEH does recovery on the specific PE that has PCI errors, the PCI devices belonging to the PE will be removed and the PE will be marked as invalid since we still need the information stored in the PE. We only invalidate the PE when it doesn't have associated EEH devices and valid child PEs. However, the code used to check that is wrong. The patch fixes that. Signed-off-by: Gavin Shan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/eeh_pe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c index 797cd18..d16c8de 100644 --- a/arch/powerpc/platforms/pseries/eeh_pe.c +++ b/arch/powerpc/platforms/pseries/eeh_pe.c @@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe) if (list_empty(&pe->edevs)) { cnt = 0; list_for_each_entry(child, &pe->child_list, child) { - if (!(pe->type & EEH_PE_INVALID)) { + if (!(child->type & EEH_PE_INVALID)) { cnt++; break; } -- cgit v1.1 From 9489e9dcae718d5fde988e4a684a0f55b5f94d17 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 25 Nov 2012 17:59:19 -0800 Subject: Linux 3.7-rc7 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9f6ca12..3d2fc46 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Terrified Chipmunk # *DOCUMENTATION* -- cgit v1.1