/* * omap-dmic.h -- OMAP Digital Microphone Controller * * 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 _OMAP_DMIC_H #define _OMAP_DMIC_H #define OMAP_DMIC_REVISION_REG 0x00 #define OMAP_DMIC_SYSCONFIG_REG 0x10 #define OMAP_DMIC_IRQSTATUS_RAW_REG 0x24 #define OMAP_DMIC_IRQSTATUS_REG 0x28 #define OMAP_DMIC_IRQENABLE_SET_REG 0x2C #define OMAP_DMIC_IRQENABLE_CLR_REG 0x30 #define OMAP_DMIC_IRQWAKE_EN_REG 0x34 #define OMAP_DMIC_DMAENABLE_SET_REG 0x38 #define OMAP_DMIC_DMAENABLE_CLR_REG 0x3C #define OMAP_DMIC_DMAWAKEEN_REG 0x40 #define OMAP_DMIC_CTRL_REG 0x44 #define OMAP_DMIC_DATA_REG 0x48 #define OMAP_DMIC_FIFO_CTRL_REG 0x4C #define OMAP_DMIC_FIFO_DMIC1R_DATA_REG 0x50 #define OMAP_DMIC_FIFO_DMIC1L_DATA_REG 0x54 #define OMAP_DMIC_FIFO_DMIC2R_DATA_REG 0x58 #define OMAP_DMIC_FIFO_DMIC2L_DATA_REG 0x5C #define OMAP_DMIC_FIFO_DMIC3R_DATA_REG 0x60 #define OMAP_DMIC_FIFO_DMIC3L_DATA_REG 0x64 /* IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR bit fields */ #define OMAP_DMIC_IRQ (1 << 0) #define OMAP_DMIC_IRQ_FULL (1 << 1) #define OMAP_DMIC_IRQ_ALMST_EMPTY (1 << 2) #define OMAP_DMIC_IRQ_EMPTY (1 << 3) #define OMAP_DMIC_IRQ_MASK 0x07 /* DMIC_DMAENABLE bit fields */ #define OMAP_DMIC_DMA_ENABLE 0x1 /* DMIC_CTRL bit fields */ #define OMAP_DMIC_UP1_ENABLE (1 << 0) #define OMAP_DMIC_UP2_ENABLE (1 << 1) #define OMAP_DMIC_UP3_ENABLE (1 << 2) #define OMAP_DMIC_UP_ENABLE_MASK 0x7 #define OMAP_DMIC_FORMAT (1 << 3) #define OMAP_DMIC_POLAR1 (1 << 4) #define OMAP_DMIC_POLAR2 (1 << 5) #define OMAP_DMIC_POLAR3 (1 << 6) #define OMAP_DMIC_POLAR_MASK (0x7 << 4) #define OMAP_DMIC_CLK_DIV(x) (((x) & 0x7) << 7) #define OMAP_DMIC_CLK_DIV_MASK (0x7 << 7) #define OMAP_DMIC_RESET (1 << 10) #define OMAP_DMICOUTFORMAT_LJUST (0 << 3) #define OMAP_DMICOUTFORMAT_RJUST (1 << 3) /* DMIC_FIFO_CTRL bit fields */ #define OMAP_DMIC_THRES_MAX 0xF enum omap_dmic_clk { OMAP_DMIC_SYSCLK_PAD_CLKS, /* PAD_CLKS */ OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS, /* SLIMBUS_CLK */ OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS, /* DMIC_SYNC_MUX_CLK */ OMAP_DMIC_ABE_DMIC_CLK, /* abe_dmic_clk */ }; #endif 847dda6659'/>
path: root/net/irda/qos.c
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2017-01-06 19:21:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-01-07 18:22:40 -0800
commitea07b862ac8ef9b8c8358517d2e39f847dda6659 (patch)
treea1db46e9dd5dcf4c26dca819fad0b69fbb37e073 /net/irda/qos.c
parentb0b9b3df27d100a975b4e8818f35382b64a5e35c (diff)
mm: workingset: fix use-after-free in shadow node shrinker
Several people report seeing warnings about inconsistent radix tree nodes followed by crashes in the workingset code, which all looked like use-after-free access from the shadow node shrinker. Dave Jones managed to reproduce the issue with a debug patch applied, which confirmed that the radix tree shrinking indeed frees shadow nodes while they are still linked to the shadow LRU: WARNING: CPU: 2 PID: 53 at lib/radix-tree.c:643 delete_node+0x1e4/0x200 CPU: 2 PID: 53 Comm: kswapd0 Not tainted 4.10.0-rc2-think+ #3 Call Trace: delete_node+0x1e4/0x200 __radix_tree_delete_node+0xd/0x10 shadow_lru_isolate+0xe6/0x220 __list_lru_walk_one.isra.4+0x9b/0x190 list_lru_walk_one+0x23/0x30 scan_shadow_nodes+0x2e/0x40 shrink_slab.part.44+0x23d/0x5d0 shrink_node+0x22c/0x330 kswapd+0x392/0x8f0 This is the WARN_ON_ONCE(!list_empty(&node->private_list)) placed in the inlined radix_tree_shrink(). The problem is with 14b468791fa9 ("mm: workingset: move shadow entry tracking to radix tree exceptional tracking"), which passes an update callback into the radix tree to link and unlink shadow leaf nodes when tree entries change, but forgot to pass the callback when reclaiming a shadow node. While the reclaimed shadow node itself is unlinked by the shrinker, its deletion from the tree can cause the left-most leaf node in the tree to be shrunk. If that happens to be a shadow node as well, we don't unlink it from the LRU as we should. Consider this tree, where the s are shadow entries: root->rnode | [0 n] | | [s ] [sssss] Now the shadow node shrinker reclaims the rightmost leaf node through the shadow node LRU: root->rnode | [0 ] | [s ] Because the parent of the deleted node is the first level below the root and has only one child in the left-most slot, the intermediate level is shrunk and the node containing the single shadow is put in its place: root->rnode | [s ] The shrinker again sees a single left-most slot in a first level node and thus decides to store the shadow in root->rnode directly and free the node - which is a leaf node on the shadow node LRU. root->rnode | s Without the update callback, the freed node remains on the shadow LRU, where it causes later shrinker runs to crash. Pass the node updater callback into __radix_tree_delete_node() in case the deletion causes the left-most branch in the tree to collapse too. Also add warnings when linked nodes are freed right away, rather than wait for the use-after-free when the list is scanned much later. Fixes: 14b468791fa9 ("mm: workingset: move shadow entry tracking to radix tree exceptional tracking") Reported-by: Dave Chinner <david@fromorbit.com> Reported-by: Hugh Dickins <hughd@google.com> Reported-by: Andrea Arcangeli <aarcange@redhat.com> Reported-and-tested-by: Dave Jones <davej@codemonkey.org.uk> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Christoph Hellwig <hch@lst.de> Cc: Chris Leech <cleech@redhat.com> Cc: Lee Duncan <lduncan@suse.com> Cc: Jan Kara <jack@suse.cz> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Matthew Wilcox <mawilcox@linuxonhyperv.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'net/irda/qos.c')