All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 5.4 393/459] char: hpet: Use flexible-array member
From: Sasha Levin @ 2020-02-14 16:00 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: Gustavo A. R. Silva, Greg Kroah-Hartman, Sasha Levin
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>

[ Upstream commit 987f028b8637cfa7658aa456ae73f8f21a7a7f6f ]

Old code in the kernel uses 1-byte and 0-byte arrays to indicate the
presence of a "variable length array":

struct something {
    int length;
    u8 data[1];
};

struct something *instance;

instance = kmalloc(sizeof(*instance) + size, GFP_KERNEL);
instance->length = size;
memcpy(instance->data, source, size);

There is also 0-byte arrays. Both cases pose confusion for things like
sizeof(), CONFIG_FORTIFY_SOURCE, etc.[1] Instead, the preferred mechanism
to declare variable-length types such as the one above is a flexible array
member[2] which need to be the last member of a structure and empty-sized:

struct something {
        int stuff;
        u8 data[];
};

Also, by making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
unadvertenly introduced[3] to the codebase from now on.

[1] https://github.com/KSPP/linux/issues/21
[2] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Link: https://lore.kernel.org/r/20200120235326.GA29231@embeddedor.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/char/hpet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 9ac6671bb5141..aed2c45f7968c 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -110,7 +110,7 @@ struct hpets {
 	unsigned long hp_delta;
 	unsigned int hp_ntimer;
 	unsigned int hp_which;
-	struct hpet_dev hp_dev[1];
+	struct hpet_dev hp_dev[];
 };
 
 static struct hpets *hpets;
-- 
2.20.1


^ permalink raw reply related

* [PATCH 2/5] aio-posix: don't pass ns timeout to epoll_wait()
From: Stefan Hajnoczi @ 2020-02-14 17:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, Kevin Wolf, qemu-block, Max Reitz, Stefan Hajnoczi,
	Marc-André Lureau, Paolo Bonzini
In-Reply-To: <20200214171712.541358-1-stefanha@redhat.com>

Don't pass the nanosecond timeout into epoll_wait(), which expects
milliseconds.

The epoll_wait() timeout value does not matter if qemu_poll_ns()
determined that the poll fd is ready, but passing a value in the wrong
units is still ugly.  Pass a 0 timeout to epoll_wait() instead.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 util/aio-posix.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/util/aio-posix.c b/util/aio-posix.c
index 31a8e03ca7..b21bcd8e97 100644
--- a/util/aio-posix.c
+++ b/util/aio-posix.c
@@ -116,6 +116,9 @@ static int aio_epoll(AioContext *ctx, int64_t timeout)
 
     if (timeout > 0) {
         ret = qemu_poll_ns(&pfd, 1, timeout);
+        if (ret > 0) {
+            timeout = 0;
+        }
     }
     if (timeout <= 0 || ret > 0) {
         ret = epoll_wait(ctx->epollfd, events,
-- 
2.24.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 430/459] powerpc: Do not consider weak unresolved symbol relocations as bad
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Alexandre Ghiti, Stephen Rothwell, Michael Ellerman, Sasha Levin,
	linuxppc-dev, netdev, bpf
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Alexandre Ghiti <alex@ghiti.fr>

[ Upstream commit 43e76cd368fbb67e767da5363ffeaa3989993c8c ]

Commit 8580ac9404f6 ("bpf: Process in-kernel BTF") introduced two weak
symbols that may be unresolved at link time which result in an absolute
relocation to 0. relocs_check.sh emits the following warning:

"WARNING: 2 bad relocations
c000000001a41478 R_PPC64_ADDR64    _binary__btf_vmlinux_bin_start
c000000001a41480 R_PPC64_ADDR64    _binary__btf_vmlinux_bin_end"

whereas those relocations are legitimate even for a relocatable kernel
compiled with -pie option.

relocs_check.sh already excluded some weak unresolved symbols explicitly:
remove those hardcoded symbols and add some logic that parses the symbols
using nm, retrieves all the weak unresolved symbols and excludes those from
the list of the potential bad relocations.

Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200118170335.21440-1-alex@ghiti.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/powerpc/Makefile.postlink     |  4 ++--
 arch/powerpc/tools/relocs_check.sh | 20 ++++++++++++--------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink
index 134f12f89b92b..2268396ff4bba 100644
--- a/arch/powerpc/Makefile.postlink
+++ b/arch/powerpc/Makefile.postlink
@@ -17,11 +17,11 @@ quiet_cmd_head_check = CHKHEAD $@
 quiet_cmd_relocs_check = CHKREL  $@
 ifdef CONFIG_PPC_BOOK3S_64
       cmd_relocs_check =						\
-	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \
+	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" ; \
 	$(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@"
 else
       cmd_relocs_check =						\
-	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@"
+	$(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@"
 endif
 
 # `@true` prevents complaint when there is nothing to be done
diff --git a/arch/powerpc/tools/relocs_check.sh b/arch/powerpc/tools/relocs_check.sh
index 7b9fe0a567cf3..014e00e74d2b6 100755
--- a/arch/powerpc/tools/relocs_check.sh
+++ b/arch/powerpc/tools/relocs_check.sh
@@ -10,14 +10,21 @@
 # based on relocs_check.pl
 # Copyright © 2009 IBM Corporation
 
-if [ $# -lt 2 ]; then
-	echo "$0 [path to objdump] [path to vmlinux]" 1>&2
+if [ $# -lt 3 ]; then
+	echo "$0 [path to objdump] [path to nm] [path to vmlinux]" 1>&2
 	exit 1
 fi
 
-# Have Kbuild supply the path to objdump so we handle cross compilation.
+# Have Kbuild supply the path to objdump and nm so we handle cross compilation.
 objdump="$1"
-vmlinux="$2"
+nm="$2"
+vmlinux="$3"
+
+# Remove from the bad relocations those that match an undefined weak symbol
+# which will result in an absolute relocation to 0.
+# Weak unresolved symbols are of that form in nm output:
+# "                  w _binary__btf_vmlinux_bin_end"
+undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }')
 
 bad_relocs=$(
 $objdump -R "$vmlinux" |
@@ -26,8 +33,6 @@ $objdump -R "$vmlinux" |
 	# These relocations are okay
 	# On PPC64:
 	#	R_PPC64_RELATIVE, R_PPC64_NONE
-	#	R_PPC64_ADDR64 mach_<name>
-	#	R_PPC64_ADDR64 __crc_<name>
 	# On PPC:
 	#	R_PPC_RELATIVE, R_PPC_ADDR16_HI,
 	#	R_PPC_ADDR16_HA,R_PPC_ADDR16_LO,
@@ -39,8 +44,7 @@ R_PPC_ADDR16_HI
 R_PPC_ADDR16_HA
 R_PPC_RELATIVE
 R_PPC_NONE' |
-	grep -E -v '\<R_PPC64_ADDR64[[:space:]]+mach_' |
-	grep -E -v '\<R_PPC64_ADDR64[[:space:]]+__crc_'
+	([ "$undef_weak_symbols" ] && grep -F -w -v "$undef_weak_symbols" || cat)
 )
 
 if [ -z "$bad_relocs" ]; then
-- 
2.20.1


^ permalink raw reply related

* [PATCH 4/5] aio-posix: make AioHandler deletion O(1)
From: Stefan Hajnoczi @ 2020-02-14 17:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Fam Zheng, Kevin Wolf, qemu-block, Max Reitz, Stefan Hajnoczi,
	Marc-André Lureau, Paolo Bonzini
In-Reply-To: <20200214171712.541358-1-stefanha@redhat.com>

It is not necessary to scan all AioHandlers for deletion.  Keep a list
of deleted handlers instead of scanning the full list of all handlers.

The AioHandler->deleted field can be dropped.  Let's check if the
handler has been inserted into the deleted list instead.  Add a new
QLIST_IS_INSERTED() API for this check.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 include/block/aio.h  |  6 ++++-
 include/qemu/queue.h |  3 +++
 util/aio-posix.c     | 53 +++++++++++++++++++++++++++++---------------
 3 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/include/block/aio.h b/include/block/aio.h
index 7ba9bd7874..1a0de1508c 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -42,6 +42,7 @@ void qemu_aio_unref(void *p);
 void qemu_aio_ref(void *p);
 
 typedef struct AioHandler AioHandler;
+typedef QLIST_HEAD(, AioHandler) AioHandlerList;
 typedef void QEMUBHFunc(void *opaque);
 typedef bool AioPollFn(void *opaque);
 typedef void IOHandler(void *opaque);
@@ -58,7 +59,10 @@ struct AioContext {
     QemuRecMutex lock;
 
     /* The list of registered AIO handlers.  Protected by ctx->list_lock. */
-    QLIST_HEAD(, AioHandler) aio_handlers;
+    AioHandlerList aio_handlers;
+
+    /* The list of AIO handlers to be deleted.  Protected by ctx->list_lock. */
+    AioHandlerList deleted_aio_handlers;
 
     /* Used to avoid unnecessary event_notifier_set calls in aio_notify;
      * accessed with atomic primitives.  If this field is 0, everything
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index a276363372..699a8a0568 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -158,6 +158,9 @@ struct {                                                                \
         }                                                               \
 } while (/*CONSTCOND*/0)
 
+/* Is elm in a list? */
+#define QLIST_IS_INSERTED(elm, field) ((elm)->field.le_prev != NULL)
+
 #define QLIST_FOREACH(var, head, field)                                 \
         for ((var) = ((head)->lh_first);                                \
                 (var);                                                  \
diff --git a/util/aio-posix.c b/util/aio-posix.c
index b21bcd8e97..3a98a2acb9 100644
--- a/util/aio-posix.c
+++ b/util/aio-posix.c
@@ -31,10 +31,10 @@ struct AioHandler
     AioPollFn *io_poll;
     IOHandler *io_poll_begin;
     IOHandler *io_poll_end;
-    int deleted;
     void *opaque;
     bool is_external;
     QLIST_ENTRY(AioHandler) node;
+    QLIST_ENTRY(AioHandler) node_deleted;
 };
 
 #ifdef CONFIG_EPOLL_CREATE1
@@ -67,7 +67,7 @@ static bool aio_epoll_try_enable(AioContext *ctx)
 
     QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
         int r;
-        if (node->deleted || !node->pfd.events) {
+        if (QLIST_IS_INSERTED(node, node_deleted) || !node->pfd.events) {
             continue;
         }
         event.events = epoll_events_from_pfd(node->pfd.events);
@@ -195,9 +195,11 @@ static AioHandler *find_aio_handler(AioContext *ctx, int fd)
     AioHandler *node;
 
     QLIST_FOREACH(node, &ctx->aio_handlers, node) {
-        if (node->pfd.fd == fd)
-            if (!node->deleted)
+        if (node->pfd.fd == fd) {
+            if (!QLIST_IS_INSERTED(node, node_deleted)) {
                 return node;
+            }
+        }
     }
 
     return NULL;
@@ -216,7 +218,7 @@ static bool aio_remove_fd_handler(AioContext *ctx, AioHandler *node)
 
     /* If a read is in progress, just mark the node as deleted */
     if (qemu_lockcnt_count(&ctx->list_lock)) {
-        node->deleted = 1;
+        QLIST_INSERT_HEAD_RCU(&ctx->deleted_aio_handlers, node, node_deleted);
         node->pfd.revents = 0;
         return false;
     }
@@ -358,7 +360,7 @@ static void poll_set_started(AioContext *ctx, bool started)
     QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
         IOHandler *fn;
 
-        if (node->deleted) {
+        if (QLIST_IS_INSERTED(node, node_deleted)) {
             continue;
         }
 
@@ -415,6 +417,26 @@ bool aio_pending(AioContext *ctx)
     return result;
 }
 
+static void aio_free_deleted_handlers(AioContext *ctx)
+{
+    AioHandler *node;
+
+    if (QLIST_EMPTY_RCU(&ctx->deleted_aio_handlers)) {
+        return;
+    }
+    if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
+        return; /* we are nested, let the parent do the freeing */
+    }
+
+    while ((node = QLIST_FIRST_RCU(&ctx->deleted_aio_handlers))) {
+        QLIST_REMOVE(node, node);
+        QLIST_REMOVE(node, node_deleted);
+        g_free(node);
+    }
+
+    qemu_lockcnt_inc_and_unlock(&ctx->list_lock);
+}
+
 static bool aio_dispatch_handlers(AioContext *ctx)
 {
     AioHandler *node, *tmp;
@@ -426,7 +448,7 @@ static bool aio_dispatch_handlers(AioContext *ctx)
         revents = node->pfd.revents & node->pfd.events;
         node->pfd.revents = 0;
 
-        if (!node->deleted &&
+        if (!QLIST_IS_INSERTED(node, node_deleted) &&
             (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
             aio_node_check(ctx, node->is_external) &&
             node->io_read) {
@@ -437,21 +459,13 @@ static bool aio_dispatch_handlers(AioContext *ctx)
                 progress = true;
             }
         }
-        if (!node->deleted &&
+        if (!QLIST_IS_INSERTED(node, node_deleted) &&
             (revents & (G_IO_OUT | G_IO_ERR)) &&
             aio_node_check(ctx, node->is_external) &&
             node->io_write) {
             node->io_write(node->opaque);
             progress = true;
         }
-
-        if (node->deleted) {
-            if (qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
-                QLIST_REMOVE(node, node);
-                g_free(node);
-                qemu_lockcnt_inc_and_unlock(&ctx->list_lock);
-            }
-        }
     }
 
     return progress;
@@ -462,6 +476,7 @@ void aio_dispatch(AioContext *ctx)
     qemu_lockcnt_inc(&ctx->list_lock);
     aio_bh_poll(ctx);
     aio_dispatch_handlers(ctx);
+    aio_free_deleted_handlers(ctx);
     qemu_lockcnt_dec(&ctx->list_lock);
 
     timerlistgroup_run_timers(&ctx->tlg);
@@ -519,7 +534,7 @@ static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout)
     AioHandler *node;
 
     QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
-        if (!node->deleted && node->io_poll &&
+        if (!QLIST_IS_INSERTED(node, node_deleted) && node->io_poll &&
             aio_node_check(ctx, node->is_external) &&
             node->io_poll(node->opaque)) {
             /*
@@ -653,7 +668,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 
         if (!aio_epoll_enabled(ctx)) {
             QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
-                if (!node->deleted && node->pfd.events
+                if (!QLIST_IS_INSERTED(node, node_deleted) && node->pfd.events
                     && aio_node_check(ctx, node->is_external)) {
                     add_pollfd(node);
                 }
@@ -730,6 +745,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
         progress |= aio_dispatch_handlers(ctx);
     }
 
+    aio_free_deleted_handlers(ctx);
+
     qemu_lockcnt_dec(&ctx->list_lock);
 
     progress |= timerlistgroup_run_timers(&ctx->tlg);
-- 
2.24.1


^ permalink raw reply related

* [PATCH v2 11/12] MIPS: CI20: defconfig: configure for CONFIG_KEYBOARD_GPIO=m
From: H. Nikolaus Schaller @ 2020-02-14 16:10 UTC (permalink / raw)
  To: Paul Boddie, Paul Cercueil, Rob Herring, Mark Rutland,
	Ralf Baechle, Paul Burton, David Airlie, Daniel Vetter,
	H. Nikolaus Schaller, Andi Kleen, Miquel Raynal, Kees Cook
  Cc: devicetree, linux-mips, linux-kernel, dri-devel, letux-kernel,
	kernel
In-Reply-To: <cover.1581696624.git.hns@goldelico.com>

The SW1 button is hooked up to send input events.

Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 arch/mips/configs/ci20_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
index 0458ea4d54e8..0db0088bbc1c 100644
--- a/arch/mips/configs/ci20_defconfig
+++ b/arch/mips/configs/ci20_defconfig
@@ -89,6 +89,7 @@ CONFIG_I2C_JZ4780=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_KEYBOARD_GPIO=m
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_JZ4740_WDT=y
-- 
2.23.0


^ permalink raw reply related

* [PATCH v2 09/12] MIPS: CI20: defconfig: compile gpio-ir driver
From: H. Nikolaus Schaller @ 2020-02-14 16:10 UTC (permalink / raw)
  To: Paul Boddie, Paul Cercueil, Rob Herring, Mark Rutland,
	Ralf Baechle, Paul Burton, David Airlie, Daniel Vetter,
	H. Nikolaus Schaller, Andi Kleen, Miquel Raynal, Kees Cook
  Cc: devicetree, linux-mips, linux-kernel, dri-devel, letux-kernel,
	kernel
In-Reply-To: <cover.1581696624.git.hns@goldelico.com>

The CI20 board has a gpio based IR receiver.

Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 arch/mips/configs/ci20_defconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
index 74e5775b8a05..0458ea4d54e8 100644
--- a/arch/mips/configs/ci20_defconfig
+++ b/arch/mips/configs/ci20_defconfig
@@ -181,3 +181,8 @@ CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_LEDS_TRIGGER_TRANSIENT=y
 CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_LIRC=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_RC_DEVICES=y
+CONFIG_IR_GPIO_CIR=m
+CONFIG_IR_GPIO_TX=m
-- 
2.23.0


^ permalink raw reply related

* [PATCH v2 12/12] MIPS: DTS: CI20: fix interrupt for pcf8563 RTC
From: H. Nikolaus Schaller @ 2020-02-14 16:10 UTC (permalink / raw)
  To: Paul Boddie, Paul Cercueil, Rob Herring, Mark Rutland,
	Ralf Baechle, Paul Burton, David Airlie, Daniel Vetter,
	H. Nikolaus Schaller, Andi Kleen, Miquel Raynal, Kees Cook
  Cc: devicetree, linux-mips, linux-kernel, dri-devel, letux-kernel,
	kernel
In-Reply-To: <cover.1581696624.git.hns@goldelico.com>

Interrupts should not be specified by interrupt line but by
gpio parent and reference.

Fixes: 73f2b940474d ("MIPS: CI20: DTS: Add I2C nodes")
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 arch/mips/boot/dts/ingenic/ci20.dts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 8f9d182566db..4bacefa2cfce 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -298,7 +298,9 @@ Optional input supply properties:
 		rtc@51 {
 			compatible = "nxp,pcf8563";
 			reg = <0x51>;
-			interrupts = <110>;
+
+			interrupt-parent = <&gpf>;
+			interrupts = <30 IRQ_TYPE_LEVEL_LOW>;
 		};
 };
 
-- 
2.23.0


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 422/459] drm/amd/display: do not allocate display_mode_lib unnecessarily
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Dor Askayo, Leo Li, Alex Deucher, Sasha Levin, amd-gfx, dri-devel
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Dor Askayo <dor.askayo@gmail.com>

[ Upstream commit bb67bfd2e7101bf2ac5327b0b7a847cd9fb9723f ]

This allocation isn't required and can fail when resuming from suspend.

Bug: https://gitlab.freedesktop.org/drm/amd/issues/1009
Signed-off-by: Dor Askayo <dor.askayo@gmail.com>
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 4b8819c27fcda..4704aac336c29 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2267,12 +2267,7 @@ void dc_set_power_state(
 	enum dc_acpi_cm_power_state power_state)
 {
 	struct kref refcount;
-	struct display_mode_lib *dml = kzalloc(sizeof(struct display_mode_lib),
-						GFP_KERNEL);
-
-	ASSERT(dml);
-	if (!dml)
-		return;
+	struct display_mode_lib *dml;
 
 	switch (power_state) {
 	case DC_ACPI_CM_POWER_STATE_D0:
@@ -2294,6 +2289,12 @@ void dc_set_power_state(
 		 * clean state, and dc hw programming optimizations will not
 		 * cause any trouble.
 		 */
+		dml = kzalloc(sizeof(struct display_mode_lib),
+				GFP_KERNEL);
+
+		ASSERT(dml);
+		if (!dml)
+			return;
 
 		/* Preserve refcount */
 		refcount = dc->current_state->refcount;
@@ -2307,10 +2308,10 @@ void dc_set_power_state(
 		dc->current_state->refcount = refcount;
 		dc->current_state->bw_ctx.dml = *dml;
 
+		kfree(dml);
+
 		break;
 	}
-
-	kfree(dml);
 }
 
 void dc_resume(struct dc *dc)
-- 
2.20.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 426/459] char: hpet: Fix out-of-bounds read bug
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Gustavo A. R. Silva, Tetsuo Handa, Eric Biggers,
	Greg Kroah-Hartman, Sasha Levin
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>

[ Upstream commit 98c49f1746ac44ccc164e914b9a44183fad09f51 ]

Currently, there is an out-of-bounds read on array hpetp->hp_dev
in the following for loop:

870         for (i = 0; i < hdp->hd_nirqs; i++)
871                 hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i];

This is due to the recent change from one-element array to
flexible-array member in struct hpets:

104 struct hpets {
	...
113         struct hpet_dev hp_dev[];
114 };

This change affected the total size of the dynamic memory
allocation, decreasing it by one time the size of struct hpet_dev.

Fix this by adjusting the allocation size when calling
struct_size().

Fixes: 987f028b8637c ("char: hpet: Use flexible-array member")
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Eric Biggers <ebiggers@kernel.org>
Link: https://lore.kernel.org/r/20200129022613.GA24281@embeddedor.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/char/hpet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index aed2c45f7968c..ed3b7dab678db 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -855,7 +855,7 @@ int hpet_alloc(struct hpet_data *hdp)
 		return 0;
 	}
 
-	hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs - 1),
+	hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs),
 			GFP_KERNEL);
 
 	if (!hpetp)
-- 
2.20.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 424/459] drm/nouveau/disp/nv50-: prevent oops when no channel method map provided
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: Ben Skeggs, Sasha Levin, dri-devel, nouveau
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Ben Skeggs <bskeggs@redhat.com>

[ Upstream commit 0e6176c6d286316e9431b4f695940cfac4ffe6c2 ]

The implementations for most channel types contains a map of methods to
priv registers in order to provide debugging info when a disp exception
has been raised.

This info is missing from the implementation of PIO channels as they're
rather simplistic already, however, if an exception is raised by one of
them, we'd end up triggering a NULL-pointer deref.  Not ideal...

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=206299
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
index bcf32d92ee5a9..50e3539f33d22 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
@@ -74,6 +74,8 @@ nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug)
 
 	if (debug > subdev->debug)
 		return;
+	if (!mthd)
+		return;
 
 	for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) {
 		u32 base = chan->head * mthd->addr;
-- 
2.20.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 423/459] irqchip/gic-v3: Only provision redistributors that are enabled in ACPI
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: Marc Zyngier, Heyi Guo, Sasha Levin
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Marc Zyngier <maz@kernel.org>

[ Upstream commit 926b5dfa6b8dc666ff398044af6906b156e1d949 ]

We currently allocate redistributor region structures for
individual redistributors when ACPI doesn't present us with
compact MMIO regions covering multiple redistributors.

It turns out that we allocate these structures even when
the redistributor is flagged as disabled by ACPI. It works
fine until someone actually tries to tarse one of these
structures, and access the corresponding MMIO region.

Instead, track the number of enabled redistributors, and
only allocate what is required. This makes sure that there
is no invalid data to misuse.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Reported-by: Heyi Guo <guoheyi@huawei.com>
Tested-by: Heyi Guo <guoheyi@huawei.com>
Link: https://lore.kernel.org/r/20191216062745.63397-1-guoheyi@huawei.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 1edc99335a946..446603efbc90b 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1801,6 +1801,7 @@ static struct
 	struct redist_region *redist_regs;
 	u32 nr_redist_regions;
 	bool single_redist;
+	int enabled_rdists;
 	u32 maint_irq;
 	int maint_irq_mode;
 	phys_addr_t vcpu_base;
@@ -1895,8 +1896,10 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
 	 * If GICC is enabled and has valid gicr base address, then it means
 	 * GICR base is presented via GICC
 	 */
-	if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
+	if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
+		acpi_data.enabled_rdists++;
 		return 0;
+	}
 
 	/*
 	 * It's perfectly valid firmware can pass disabled GICC entry, driver
@@ -1926,8 +1929,10 @@ static int __init gic_acpi_count_gicr_regions(void)
 
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
 				      gic_acpi_match_gicc, 0);
-	if (count > 0)
+	if (count > 0) {
 		acpi_data.single_redist = true;
+		count = acpi_data.enabled_rdists;
+	}
 
 	return count;
 }
-- 
2.20.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 427/459] ftrace: fpid_next() should increase position index
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: Vasily Averin, Steven Rostedt, Sasha Levin
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Vasily Averin <vvs@virtuozzo.com>

[ Upstream commit e4075e8bdffd93a9b6d6e1d52fabedceeca5a91b ]

if seq_file .next fuction does not change position index,
read after some lseek can generate unexpected output.

Without patch:
 # dd bs=4 skip=1 if=/sys/kernel/tracing/set_ftrace_pid
 dd: /sys/kernel/tracing/set_ftrace_pid: cannot skip to specified offset
 id
 no pid
 2+1 records in
 2+1 records out
 10 bytes copied, 0.000213285 s, 46.9 kB/s

Notice the "id" followed by "no pid".

With the patch:
 # dd bs=4 skip=1 if=/sys/kernel/tracing/set_ftrace_pid
 dd: /sys/kernel/tracing/set_ftrace_pid: cannot skip to specified offset
 id
 0+1 records in
 0+1 records out
 3 bytes copied, 0.000202112 s, 14.8 kB/s

Notice that it only prints "id" and not the "no pid" afterward.

Link: http://lkml.kernel.org/r/4f87c6ad-f114-30bb-8506-c32274ce2992@virtuozzo.com

https://bugzilla.kernel.org/show_bug.cgi?id=206283
Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/trace/ftrace.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 407d8bf4ed93e..15160d707da45 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6537,9 +6537,10 @@ static void *fpid_next(struct seq_file *m, void *v, loff_t *pos)
 	struct trace_array *tr = m->private;
 	struct trace_pid_list *pid_list = rcu_dereference_sched(tr->function_pids);
 
-	if (v == FTRACE_NO_PIDS)
+	if (v == FTRACE_NO_PIDS) {
+		(*pos)++;
 		return NULL;
-
+	}
 	return trace_pid_next(pid_list, v, pos);
 }
 
-- 
2.20.1


^ permalink raw reply related

* Re: mmotm 2020-02-13-22-26 uploaded (mm/hugetlb.c)
From: Mike Kravetz @ 2020-02-14 17:18 UTC (permalink / raw)
  To: Randy Dunlap, Andrew Morton, broonie, linux-fsdevel, linux-kernel,
	linux-mm, linux-next, mhocko, mm-commits, sfr, Matthew Wilcox,
	Mina Almasry
In-Reply-To: <8e1e8f6e-0da1-e9e0-fa1b-bfd792256604@infradead.org>

+ Mina

Andrew, you might want to remove those hugetlb cgroup patches from mmotm
as they are not yet fully reviewed and have some build issues.

-- 
Mike Kravetz

On 2/14/20 8:29 AM, Randy Dunlap wrote:
> On 2/13/20 10:26 PM, Andrew Morton wrote:
>> The mm-of-the-moment snapshot 2020-02-13-22-26 has been uploaded to
>>
>>    http://www.ozlabs.org/~akpm/mmotm/
>>
>> mmotm-readme.txt says
>>
>> README for mm-of-the-moment:
>>
>> http://www.ozlabs.org/~akpm/mmotm/
>>
>> This is a snapshot of my -mm patch queue.  Uploaded at random hopefully
>> more than once a week.
>>
> 
> on x86_64:
> 
>   CC      mm/hugetlb.o
> In file included from ../include/linux/kernel.h:15:0,
>                  from ../include/linux/list.h:9,
>                  from ../mm/hugetlb.c:6:
> ../mm/hugetlb.c: In function ‘dump_resv_map’:
> ../mm/hugetlb.c:301:30: error: ‘struct file_region’ has no member named ‘reservation_counter’
>           rg->from, rg->to, rg->reservation_counter, rg->css);
>                               ^
> ../include/linux/printk.h:304:33: note: in definition of macro ‘pr_err’
>   printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
>                                  ^~~~~~~~~~~
> ../mm/hugetlb.c:301:55: error: ‘struct file_region’ has no member named ‘css’
>           rg->from, rg->to, rg->reservation_counter, rg->css);
>                                                        ^
> ../include/linux/printk.h:304:33: note: in definition of macro ‘pr_err’
>   printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
>                                  ^~~~~~~~~~~
> ../mm/hugetlb.c: In function ‘check_coalesce_bug’:
> ../mm/hugetlb.c:320:10: error: ‘struct file_region’ has no member named ‘reservation_counter’
>    if (nrg->reservation_counter && nrg->from == rg->to &&
>           ^~
> ../mm/hugetlb.c:321:10: error: ‘struct file_region’ has no member named ‘reservation_counter’
>        nrg->reservation_counter == rg->reservation_counter &&
>           ^~
> ../mm/hugetlb.c:321:37: error: ‘struct file_region’ has no member named ‘reservation_counter’
>        nrg->reservation_counter == rg->reservation_counter &&
>                                      ^~
> ../mm/hugetlb.c:322:10: error: ‘struct file_region’ has no member named ‘css’
>        nrg->css == rg->css) {
>           ^~
> ../mm/hugetlb.c:322:21: error: ‘struct file_region’ has no member named ‘css’
>        nrg->css == rg->css) {
>                      ^~
> 
> 
> Full randconfig file is attached.
> 

^ permalink raw reply

* [PATCH AUTOSEL 5.4 421/459] IB/mlx4: Fix leak in id_map_find_del
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Håkon Bugge, Manjunath Patil, Rama Nichanamatlu,
	Jack Morgenstein, Jason Gunthorpe, Sasha Levin, linux-rdma
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Håkon Bugge <haakon.bugge@oracle.com>

[ Upstream commit ea660ad7c1c476fd6e5e3b17780d47159db71dea ]

Using CX-3 virtual functions, either from a bare-metal machine or
pass-through from a VM, MAD packets are proxied through the PF driver.

Since the VF drivers have separate name spaces for MAD Transaction Ids
(TIDs), the PF driver has to re-map the TIDs and keep the book keeping in
a cache.

Following the RDMA Connection Manager (CM) protocol, it is clear when an
entry has to evicted from the cache. When a DREP is sent from
mlx4_ib_multiplex_cm_handler(), id_map_find_del() is called. Similar when
a REJ is received by the mlx4_ib_demux_cm_handler(), id_map_find_del() is
called.

This function wipes out the TID in use from the IDR or XArray and removes
the id_map_entry from the table.

In short, it does everything except the topping of the cake, which is to
remove the entry from the list and free it. In other words, for the REJ
case enumerated above, one id_map_entry will be leaked.

For the other case above, a DREQ has been received first. The reception of
the DREQ will trigger queuing of a delayed work to delete the
id_map_entry, for the case where the VM doesn't send back a DREP.

In the normal case, the VM _will_ send back a DREP, and id_map_find_del()
will be called.

But this scenario introduces a secondary leak. First, when the DREQ is
received, a delayed work is queued. The VM will then return a DREP, which
will call id_map_find_del(). As stated above, this will free the TID used
from the XArray or IDR. Now, there is window where that particular TID can
be re-allocated, lets say by an outgoing REQ. This TID will later be wiped
out by the delayed work, when the function id_map_ent_timeout() is
called. But the id_map_entry allocated by the outgoing REQ will not be
de-allocated, and we have a leak.

Both leaks are fixed by removing the id_map_find_del() function and only
using schedule_delayed(). Of course, a check in schedule_delayed() to see
if the work already has been queued, has been added.

Another benefit of always using the delayed version for deleting entries,
is that we do get a TimeWait effect; a TID no longer in use, will occupy
the XArray or IDR for CM_CLEANUP_CACHE_TIMEOUT time, without any ability
of being re-used for that time period.

Fixes: 3cf69cc8dbeb ("IB/mlx4: Add CM paravirtualization")
Link: https://lore.kernel.org/r/20200123155521.1212288-1-haakon.bugge@oracle.com
Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
Signed-off-by: Manjunath Patil <manjunath.b.patil@oracle.com>
Reviewed-by: Rama Nichanamatlu <rama.nichanamatlu@oracle.com>
Reviewed-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/hw/mlx4/cm.c | 29 +++--------------------------
 1 file changed, 3 insertions(+), 26 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index ecd6cadd529a5..b591861934b3c 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -186,23 +186,6 @@ static void id_map_ent_timeout(struct work_struct *work)
 	kfree(ent);
 }
 
-static void id_map_find_del(struct ib_device *ibdev, int pv_cm_id)
-{
-	struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov;
-	struct rb_root *sl_id_map = &sriov->sl_id_map;
-	struct id_map_entry *ent, *found_ent;
-
-	spin_lock(&sriov->id_map_lock);
-	ent = xa_erase(&sriov->pv_id_table, pv_cm_id);
-	if (!ent)
-		goto out;
-	found_ent = id_map_find_by_sl_id(ibdev, ent->slave_id, ent->sl_cm_id);
-	if (found_ent && found_ent == ent)
-		rb_erase(&found_ent->node, sl_id_map);
-out:
-	spin_unlock(&sriov->id_map_lock);
-}
-
 static void sl_id_map_add(struct ib_device *ibdev, struct id_map_entry *new)
 {
 	struct rb_root *sl_id_map = &to_mdev(ibdev)->sriov.sl_id_map;
@@ -294,7 +277,7 @@ static void schedule_delayed(struct ib_device *ibdev, struct id_map_entry *id)
 	spin_lock(&sriov->id_map_lock);
 	spin_lock_irqsave(&sriov->going_down_lock, flags);
 	/*make sure that there is no schedule inside the scheduled work.*/
-	if (!sriov->is_going_down) {
+	if (!sriov->is_going_down && !id->scheduled_delete) {
 		id->scheduled_delete = 1;
 		schedule_delayed_work(&id->timeout, CM_CLEANUP_CACHE_TIMEOUT);
 	}
@@ -341,9 +324,6 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id
 
 	if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID)
 		schedule_delayed(ibdev, id);
-	else if (mad->mad_hdr.attr_id == CM_DREP_ATTR_ID)
-		id_map_find_del(ibdev, pv_cm_id);
-
 	return 0;
 }
 
@@ -382,12 +362,9 @@ int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave,
 		*slave = id->slave_id;
 	set_remote_comm_id(mad, id->sl_cm_id);
 
-	if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID)
+	if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID ||
+	    mad->mad_hdr.attr_id == CM_REJ_ATTR_ID)
 		schedule_delayed(ibdev, id);
-	else if (mad->mad_hdr.attr_id == CM_REJ_ATTR_ID ||
-			mad->mad_hdr.attr_id == CM_DREP_ATTR_ID) {
-		id_map_find_del(ibdev, (int) pv_cm_id);
-	}
 
 	return 0;
 }
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH v2 01/30] configure: Allow user to specify sphinx-build binary
From: Markus Armbruster @ 2020-02-14 17:18 UTC (permalink / raw)
  To: Peter Maydell
  Cc: John Snow, Daniel P. Berrangé, QEMU Developers,
	Stefan Hajnoczi, Michael Roth
In-Reply-To: <CAFEAcA9ZQfeKA7Nb4FSmk8G3JmCFQa4VsMYLQmE2-UBj7YVeuA@mail.gmail.com>

Peter Maydell <peter.maydell@linaro.org> writes:

> On Fri, 14 Feb 2020 at 12:20, Markus Armbruster <armbru@redhat.com> wrote:
>>
>> Peter Maydell <peter.maydell@linaro.org> writes:
>> >>  # Default objcc to clang if available, otherwise use CC
>> >> @@ -4803,7 +4816,7 @@ has_sphinx_build() {
>> >>      # sphinx-build doesn't exist at all or if it is too old.
>> >>      mkdir -p "$TMPDIR1/sphinx"
>> >>      touch "$TMPDIR1/sphinx/index.rst"
>> >> -    $sphinx_build -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
>> >> +    "$sphinx_build" -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
>> >>  }
>> >
>> > This change isn't related to trying sphinx-build-3 --
>> > did you actually need it ?
>>
>> If the for loop finds nothing, $sphinx_build remains empty.  Quoting the
>> variable seems cleaner.
>
> Oh, I see. Anyway, yes, happy to have quotes here.

I decided I prefer this as a separate patch, between PATCH 01 and 02.

Hmm, maybe I should squash the last hunk into PATCH 01.


From 10d174a9f811708807fb60a610e88084f282c222 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
Date: Fri, 14 Feb 2020 07:33:43 +0100
Subject: [PATCH] configure: Pick sphinx-build-3 when available

The next commit will require a sphinx-build that uses Python 3.  On
some systems, sphinx-build is fine, on others you need to use
sphinx-build-3.  To keep things working out of the box on both kinds
of systems, try sphinx-build-3, then sphinx-build.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 configure | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 14172909f0..4cbeb06b86 100755
--- a/configure
+++ b/configure
@@ -584,7 +584,6 @@ query_pkg_config() {
 }
 pkg_config=query_pkg_config
 sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
-sphinx_build=sphinx-build
 
 # If the user hasn't specified ARFLAGS, default to 'rv', just as make does.
 ARFLAGS="${ARFLAGS-rv}"
@@ -903,6 +902,7 @@ fi
 
 : ${make=${MAKE-make}}
 : ${install=${INSTALL-install}}
+
 # We prefer python 3.x. A bare 'python' is traditionally
 # python 2.x, but some distros have it as python 3.x, so
 # we check that too
@@ -915,6 +915,17 @@ do
         break
     fi
 done
+
+sphinx_build=
+for binary in sphinx-build-3 sphinx-build
+do
+    if has "$binary"
+    then
+        sphinx_build=$(command -v "$binary")
+        break
+    fi
+done
+
 : ${smbd=${SMBD-/usr/sbin/smbd}}
 
 # Default objcc to clang if available, otherwise use CC
@@ -4803,7 +4814,7 @@ has_sphinx_build() {
     # sphinx-build doesn't exist at all or if it is too old.
     mkdir -p "$TMPDIR1/sphinx"
     touch "$TMPDIR1/sphinx/index.rst"
-    $sphinx_build -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
+    "$sphinx_build" -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1
 }
 
 # Check if tools are available to build documentation.
-- 
2.21.1



^ permalink raw reply related

* [PATCH v2 08/12] MIPS: DTS: CI20: add DT node for IR sensor
From: H. Nikolaus Schaller @ 2020-02-14 16:10 UTC (permalink / raw)
  To: Paul Boddie, Paul Cercueil, Rob Herring, Mark Rutland,
	Ralf Baechle, Paul Burton, David Airlie, Daniel Vetter,
	H. Nikolaus Schaller, Andi Kleen, Miquel Raynal, Kees Cook
  Cc: devicetree, linux-mips, linux-kernel, dri-devel, letux-kernel,
	kernel, Alex Smith
In-Reply-To: <cover.1581696624.git.hns@goldelico.com>

From: Alex Smith <alex.smith@imgtec.com>

The infrared sensor on the CI20 board is connected to a GPIO and can
be operated by using the gpio-ir-recv driver. Add a DT node for the
sensor to allow that driver to be used.

Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 arch/mips/boot/dts/ingenic/ci20.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index e1364f941c7d..b4a820313992 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -62,6 +62,11 @@
 		enable-active-high;
 	};
 
+	ir: ir-receiver {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpe 3 GPIO_ACTIVE_LOW>;
+	};
+
 	wlan0_power: fixedregulator@1 {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan0_power";
-- 
2.23.0


^ permalink raw reply related

* [PATCH v2 06/12] MIPS: CI20: defconfig: configure CONFIG_REGULATOR_ACT8865 for PMU
From: H. Nikolaus Schaller @ 2020-02-14 16:10 UTC (permalink / raw)
  To: Paul Boddie, Paul Cercueil, Rob Herring, Mark Rutland,
	Ralf Baechle, Paul Burton, David Airlie, Daniel Vetter,
	H. Nikolaus Schaller, Andi Kleen, Miquel Raynal, Kees Cook
  Cc: devicetree, linux-mips, linux-kernel, dri-devel, letux-kernel,
	kernel
In-Reply-To: <cover.1581696624.git.hns@goldelico.com>

The PMU on the CI20 board is an ACT8600 using the ACT8865 driver.
Since it is not compiled, the PMU and the CI20 board is running in
power-on reset state of the PMU.

Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 arch/mips/configs/ci20_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
index 30a47a7a2994..74e5775b8a05 100644
--- a/arch/mips/configs/ci20_defconfig
+++ b/arch/mips/configs/ci20_defconfig
@@ -95,6 +95,7 @@ CONFIG_JZ4740_WDT=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_DEBUG=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ACT8865=y
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
-- 
2.23.0


^ permalink raw reply related

* [PATCH v2 05/12] MIPS: DTS: CI20: fix PMU definitions for ACT8600
From: H. Nikolaus Schaller @ 2020-02-14 16:10 UTC (permalink / raw)
  To: Paul Boddie, Paul Cercueil, Rob Herring, Mark Rutland,
	Ralf Baechle, Paul Burton, David Airlie, Daniel Vetter,
	H. Nikolaus Schaller, Andi Kleen, Miquel Raynal, Kees Cook
  Cc: devicetree, linux-mips, linux-kernel, dri-devel, letux-kernel,
	kernel
In-Reply-To: <cover.1581696624.git.hns@goldelico.com>

There is a ACT8600 on the CI20 board and the bindings of the
ACT8865 driver have changed without updating the CI20 device
tree. Therefore the PMU can not be probed successfully and
is running in power-on reset state.

Fix DT to match the latest act8865-regulator bindings.

Fixes: 73f2b940474d ("MIPS: CI20: DTS: Add I2C nodes")
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 arch/mips/boot/dts/ingenic/ci20.dts | 48 ++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 37b93166bf22..e02a19db7ef1 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -148,6 +148,8 @@
 	pinctrl-0 = <&pins_uart4>;
 };
 
+#include <dt-bindings/regulator/active-semi,8865-regulator.h>
+
 &i2c0 {
 	status = "okay";
 
@@ -161,65 +163,81 @@
 		reg = <0x5a>;
 		status = "okay";
 
+/*
+Optional input supply properties:
+- for act8600:
+  - vp1-supply: The input supply for DCDC_REG1
+  - vp2-supply: The input supply for DCDC_REG2
+  - vp3-supply: The input supply for DCDC_REG3
+  - inl-supply: The input supply for LDO_REG5, LDO_REG6, LDO_REG7 and LDO_REG8
+  SUDCDC_REG4, LDO_REG9 and LDO_REG10 do not have separate supplies.
+*/
+
 		regulators {
 			vddcore: SUDCDC1 {
-				regulator-name = "VDDCORE";
+				regulator-name = "DCDC_REG1";
 				regulator-min-microvolt = <1100000>;
 				regulator-max-microvolt = <1100000>;
 				regulator-always-on;
 			};
 			vddmem: SUDCDC2 {
-				regulator-name = "VDDMEM";
+				regulator-name = "DCDC_REG2";
 				regulator-min-microvolt = <1500000>;
 				regulator-max-microvolt = <1500000>;
 				regulator-always-on;
 			};
 			vcc_33: SUDCDC3 {
-				regulator-name = "VCC33";
+				regulator-name = "DCDC_REG3";
 				regulator-min-microvolt = <3300000>;
 				regulator-max-microvolt = <3300000>;
 				regulator-always-on;
 			};
 			vcc_50: SUDCDC4 {
-				regulator-name = "VCC50";
+				regulator-name = "SUDCDC_REG4";
 				regulator-min-microvolt = <5000000>;
 				regulator-max-microvolt = <5000000>;
 				regulator-always-on;
 			};
 			vcc_25: LDO_REG5 {
-				regulator-name = "VCC25";
+				regulator-name = "LDO_REG5";
 				regulator-min-microvolt = <2500000>;
 				regulator-max-microvolt = <2500000>;
 				regulator-always-on;
 			};
 			wifi_io: LDO_REG6 {
-				regulator-name = "WIFIIO";
+				regulator-name = "LDO_REG6";
 				regulator-min-microvolt = <2500000>;
 				regulator-max-microvolt = <2500000>;
 				regulator-always-on;
 			};
 			vcc_28: LDO_REG7 {
-				regulator-name = "VCC28";
+				regulator-name = "LDO_REG7";
 				regulator-min-microvolt = <2800000>;
 				regulator-max-microvolt = <2800000>;
 				regulator-always-on;
 			};
 			vcc_15: LDO_REG8 {
-				regulator-name = "VCC15";
+				regulator-name = "LDO_REG8";
 				regulator-min-microvolt = <1500000>;
 				regulator-max-microvolt = <1500000>;
 				regulator-always-on;
 			};
-			vcc_18: LDO_REG9 {
-				regulator-name = "VCC18";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
+			vrtc_18: LDO_REG9 {
+				regulator-name = "LDO_REG9";
+				/* Despite the datasheet stating 3.3V for REG9 and
+				   driver expecting that, REG9 outputs 1.8V.
+				   Likely the CI20 uses a chip variant.
+				   Since it is a simple on/off LDO the exact values
+				   do not matter.
+				*/
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
 				regulator-always-on;
 			};
 			vcc_11: LDO_REG10 {
-				regulator-name = "VCC11";
-				regulator-min-microvolt = <1100000>;
-				regulator-max-microvolt = <1100000>;
+				regulator-name = "LDO_REG10";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
 				regulator-always-on;
 			};
 		};
-- 
2.23.0


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 417/459] mwifiex: Fix possible buffer overflows in mwifiex_ret_wmm_get_status()
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Qing Xu, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Qing Xu <m1s5p6688@gmail.com>

[ Upstream commit 3a9b153c5591548612c3955c9600a98150c81875 ]

mwifiex_ret_wmm_get_status() calls memcpy() without checking the
destination size.Since the source is given from remote AP which
contains illegal wmm elements , this may trigger a heap buffer
overflow.
Fix it by putting the length check before calling memcpy().

Signed-off-by: Qing Xu <m1s5p6688@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/marvell/mwifiex/wmm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c
index 41f0231376c01..132f9e8ed68c1 100644
--- a/drivers/net/wireless/marvell/mwifiex/wmm.c
+++ b/drivers/net/wireless/marvell/mwifiex/wmm.c
@@ -970,6 +970,10 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
 				    "WMM Parameter Set Count: %d\n",
 				    wmm_param_ie->qos_info_bitmap & mask);
 
+			if (wmm_param_ie->vend_hdr.len + 2 >
+				sizeof(struct ieee_types_wmm_parameter))
+				break;
+
 			memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
 			       wmm_ie, wmm_param_ie,
 			       wmm_param_ie->vend_hdr.len + 2);
-- 
2.20.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 388/459] tty: n_hdlc: Use flexible-array member and struct_size() helper
From: Sasha Levin @ 2020-02-14 16:00 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Gustavo A. R. Silva, Jiri Slaby, Greg Kroah-Hartman, Sasha Levin
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>

[ Upstream commit 85f4c95172d606dd66f7ee1fa50c45a245535ffd ]

Old code in the kernel uses 1-byte and 0-byte arrays to indicate the
presence of a "variable length array":

struct something {
    int length;
    u8 data[1];
};

struct something *instance;

instance = kmalloc(sizeof(*instance) + size, GFP_KERNEL);
instance->length = size;
memcpy(instance->data, source, size);

There is also 0-byte arrays. Both cases pose confusion for things like
sizeof(), CONFIG_FORTIFY_SOURCE, etc.[1] Instead, the preferred mechanism
to declare variable-length types such as the one above is a flexible array
member[2] which need to be the last member of a structure and empty-sized:

struct something {
        int stuff;
        u8 data[];
};

Also, by making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
inadvertenly introduced[3] to the codebase from now on.

Lastly, make use of the struct_size() helper to safely calculate the
allocation size for instances of struct n_hdlc_buf and avoid any potential
type mistakes[4][5].

[1] https://github.com/KSPP/linux/issues/21
[2] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
[4] https://lore.kernel.org/lkml/60e14fb7-8596-e21c-f4be-546ce39e7bdb@embeddedor.com/
[5] commit 553d66cb1e86 ("iommu/vt-d: Use struct_size() helper")

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Reviewed-by: Jiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20200121172138.GA3162@embeddedor
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/tty/n_hdlc.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
index 98361acd3053f..27b506bf03ced 100644
--- a/drivers/tty/n_hdlc.c
+++ b/drivers/tty/n_hdlc.c
@@ -115,11 +115,9 @@
 struct n_hdlc_buf {
 	struct list_head  list_item;
 	int		  count;
-	char		  buf[1];
+	char		  buf[];
 };
 
-#define	N_HDLC_BUF_SIZE	(sizeof(struct n_hdlc_buf) + maxframe)
-
 struct n_hdlc_buf_list {
 	struct list_head  list;
 	int		  count;
@@ -524,7 +522,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
 		/* no buffers in free list, attempt to allocate another rx buffer */
 		/* unless the maximum count has been reached */
 		if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
-			buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
+			buf = kmalloc(struct_size(buf, buf, maxframe),
+				      GFP_ATOMIC);
 	}
 	
 	if (!buf) {
@@ -853,7 +852,7 @@ static struct n_hdlc *n_hdlc_alloc(void)
 
 	/* allocate free rx buffer list */
 	for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
-		buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
+		buf = kmalloc(struct_size(buf, buf, maxframe), GFP_KERNEL);
 		if (buf)
 			n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
 		else if (debuglevel >= DEBUG_LEVEL_INFO)	
@@ -862,7 +861,7 @@ static struct n_hdlc *n_hdlc_alloc(void)
 	
 	/* allocate free tx buffer list */
 	for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
-		buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
+		buf = kmalloc(struct_size(buf, buf, maxframe), GFP_KERNEL);
 		if (buf)
 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
 		else if (debuglevel >= DEBUG_LEVEL_INFO)	
-- 
2.20.1


^ permalink raw reply related

* Re: Re: [RFC PATCH v2 4/6] media: tegra: Add Tegra210 Video input driver
From: Sowjanya Komatineni @ 2020-02-14 17:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: jonathanh, frankc, hverkuil, helen.koike, sboyd, linux-media,
	devicetree, linux-clk, linux-tegra, linux-kernel
In-Reply-To: <20200214164642.GA1310813@ulmo>


On 2/14/20 8:46 AM, Thierry Reding wrote:
> On Wed, Feb 05, 2020 at 01:23:24PM -0800, Sowjanya Komatineni wrote:
> [...]
>> +static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
>> +				       struct tegra_channel_buffer *buf)
>> +{
>> +	int err = 0;
>> +	u32 thresh, value, frame_start;
>> +	int bytes_per_line = chan->format.bytesperline;
>> +
>> +	/* program buffer address by using surface 0 */
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_OFFSET_MSB, 0x0);
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_OFFSET_LSB, buf->addr);
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_STRIDE, bytes_per_line);
>> +
>> +	/* increase syncpoint max */
>> +	thresh = host1x_syncpt_incr_max(chan->sp, 1);
>> +
>> +	/* program syncpoint */
>> +	frame_start = VI_CSI_PP_FRAME_START(chan->portno);
>> +	value = VI_CFG_VI_INCR_SYNCPT_COND(frame_start) |
>> +		host1x_syncpt_id(chan->sp);
>> +	tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
> Okay, so this programs the VI to increment the given syncpoint upon
> frame start? What is that VI_CSI_PP_FRAME_START(chan->portno) exactly?
This programs thresh for FS event. VI_CSI_PP_FRAME_START is frame start 
condition for corresponding port PPA that we program in INVR_SYNCPT to 
raise event for this condition.
>
>> +
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SINGLE_SHOT, SINGLE_SHOT_CAPTURE);
> And now we start capturing in single-shot mode.
We set thres to have it raise event when it sees FS and we issue single 
shot which initiates capture with FS first and at end of frame capture 
we should see MW_ACK which confirms frame buffer memory write done.
>
>> +
>> +	/* move buffer to capture done queue */
>> +	spin_lock(&chan->done_lock);
>> +	list_add_tail(&buf->queue, &chan->done);
>> +	spin_unlock(&chan->done_lock);
>> +
>> +	/* wait up kthread for capture done */
>> +	wake_up_interruptible(&chan->done_wait);
> But this I don't understand. You wake up the kthread...

On issuing single start this wakes up other thread which checks for MW_ACK.

So one thread checks for FS and other checks for MW_ACK.

I do see race condition with this, so I had change in v3 where same 
capture thread sets both FS COND SYncpoint and also MW_aCK and once it 
see FS syncpt then only it wakes up other thread for MW_ACK otherwise it 
just returns buffer with error state.


>
>> +
>> +	/* use syncpoint to wake up */
>> +	err = host1x_syncpt_wait(chan->sp, thresh,
>> +				 TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
> ... and then wait for the syncpoint to reach the given threshold? Isn't
> that the wrong way around? Don't we need to wait for the syncpoint
> increment *before* we wake up the kthread that will return the buffer
> to userspace?
V3 has change to check for MW_ACK only on successful FS. Will send out 
v3 soon.
>> +	if (err) {
>> +		dev_err(&chan->video.dev,
>> +			"frame start syncpt timeout: %d\n", err);
>> +		tegra_channel_capture_error_status(chan);
>> +	}
>> +
>> +	return err;
>> +}
>> +
>> +static int tegra_channel_capture_done(struct tegra_vi_channel *chan,
>> +				      struct tegra_channel_buffer *buf)
>> +{
>> +	struct vb2_v4l2_buffer *vb = &buf->buf;
>> +	u32 thresh, value, mw_ack_done;
>> +	int ret = 0;
>> +
>> +	/* increase syncpoint max */
>> +	thresh = host1x_syncpt_incr_max(chan->sp, 1);
>> +
>> +	/* program syncpoint */
>> +	mw_ack_done = VI_CSI_MW_ACK_DONE(chan->portno);
>> +	value = VI_CFG_VI_INCR_SYNCPT_COND(mw_ack_done) |
>> +		host1x_syncpt_id(chan->sp);
>> +	tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
>> +
>> +	if (!vi_csi_read(chan, TEGRA_VI_CSI_SINGLE_SHOT))
>> +		vi_csi_write(chan, TEGRA_VI_CSI_SINGLE_SHOT,
>> +			     SINGLE_SHOT_CAPTURE);
>> +
>> +	/* use syncpoint to wake up */
>> +	ret = host1x_syncpt_wait(chan->sp, thresh,
>> +				 TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
>> +	if (ret)
>> +		dev_err(&chan->video.dev,
>> +			"MW_ACK_DONE syncpoint timeout: %d\n", ret);
> Actually... there's another syncpoint wait here, so I guess this will
> stall until VI has actually completed writing the captured frame to
> memory.

Yes with v2 it will wait till it sees MW_ACK before returning buffer.

But as mentioned above, to avoid possible race condition moved 
programming both threshold for same frame in capture thread and only on 
receiving FS it wakes other thread to wait for MW_ACK and return buffer.


>> +
>> +	/* captured one frame */
>> +	vb->sequence = chan->sequence++;
>> +	vb->field = V4L2_FIELD_NONE;
>> +	vb->vb2_buf.timestamp = ktime_get_ns();
>> +	vb2_buffer_done(&vb->vb2_buf,
>> +			ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
> So it's really only at this point that we return the buffer to
> userspace, which should be after the hardware is done writing to the
> buffer, so this should be fine.
>
> That said, I'm wondering if host1x_syncpt_wait() is a good interface
> for this use-case. We don't really have anything else right now, but
> I think we may be able to add something to have a function called in
> case the syncpoint reaches a threshold. Having to spawn two separate
> threads with wait queues seems a bit overkill for this.
>
> It's fine to leave this as it is for now, but maybe something to
> consider as improvement in the future.
>
>> +	return ret;
>> +}
>> +
>> +static int chan_capture_kthread_start(void *data)
>> +{
>> +	struct tegra_vi_channel *chan = data;
>> +	struct tegra_channel_buffer *buf;
>> +	int err = 0;
>> +
>> +	set_freezable();
>> +
>> +	while (1) {
>> +		try_to_freeze();
>> +
>> +		wait_event_interruptible(chan->start_wait,
>> +					 !list_empty(&chan->capture) ||
>> +					 kthread_should_stop());
>> +		if (kthread_should_stop())
>> +			break;
>> +
>> +		if (err)
>> +			continue;
>> +
>> +		spin_lock(&chan->start_lock);
>> +		if (list_empty(&chan->capture)) {
>> +			spin_unlock(&chan->start_lock);
>> +			continue;
>> +		}
>> +
>> +		buf = list_entry(chan->capture.next,
>> +				 struct tegra_channel_buffer, queue);
>> +		list_del_init(&buf->queue);
>> +		spin_unlock(&chan->start_lock);
>> +		err = tegra_channel_capture_frame(chan, buf);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int chan_capture_kthread_done(void *data)
>> +{
>> +	struct tegra_vi_channel *chan = data;
>> +	struct tegra_channel_buffer *buf;
>> +	int err = 0;
>> +
>> +	set_freezable();
>> +
>> +	while (1) {
>> +		try_to_freeze();
>> +
>> +		wait_event_interruptible(chan->done_wait,
>> +					 !list_empty(&chan->done) ||
>> +					 kthread_should_stop());
>> +
>> +		if (kthread_should_stop())
>> +			break;
>> +
>> +		spin_lock(&chan->done_lock);
>> +		if (list_empty(&chan->done)) {
>> +			spin_unlock(&chan->done_lock);
>> +			continue;
>> +		}
>> +
>> +		buf = list_entry(chan->done.next, struct tegra_channel_buffer,
>> +				 queue);
>> +		if (!buf)
>> +			continue;
>> +
>> +		list_del_init(&buf->queue);
>> +		spin_unlock(&chan->done_lock);
>> +		err = tegra_channel_capture_done(chan, buf);
> What's with the error here? I think we should either handle it in some
> way, or just avoid even returning an error if we're not going to deal
> with it anyway.
>
> Thierry


v3 has proper implementation where on no frame start which happens when 
source is not streaming, we keep thread in wait till kthread stops and 
we dont dequeue buffers.

Once we see kthread stop then we return all buffers.

^ permalink raw reply

* [PATCH AUTOSEL 5.4 416/459] powerpc/mm: Don't log user reads to 0xffffffff
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Christophe Leroy, Michael Ellerman, Sasha Levin, linuxppc-dev
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Christophe Leroy <christophe.leroy@c-s.fr>

[ Upstream commit 0f9aee0cb9da7db7d96f63cfa2dc5e4f1bffeb87 ]

Running vdsotest leaves many times the following log:

  [   79.629901] vdsotest[396]: User access of kernel address (ffffffff) - exploit attempt? (uid: 0)

A pointer set to (-1) is likely a programming error similar to
a NULL pointer and is not worth logging as an exploit attempt.

Don't log user accesses to 0xffffffff.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/0728849e826ba16f1fbd6fa7f5c6cc87bd64e097.1577087627.git.christophe.leroy@c-s.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/powerpc/mm/fault.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 9298905cfe74f..881a026a603a6 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -354,6 +354,9 @@ static void sanity_check_fault(bool is_write, bool is_user,
 	 * Userspace trying to access kernel address, we get PROTFAULT for that.
 	 */
 	if (is_user && address >= TASK_SIZE) {
+		if ((long)address == -1)
+			return;
+
 		pr_crit_ratelimited("%s[%d]: User access of kernel address (%lx) - exploit attempt? (uid: %d)\n",
 				   current->comm, current->pid, address,
 				   from_kuid(&init_user_ns, current_uid()));
-- 
2.20.1


^ permalink raw reply related

* Re: Re: [RFC PATCH v2 4/6] media: tegra: Add Tegra210 Video input driver
From: Sowjanya Komatineni @ 2020-02-14 17:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: jonathanh, frankc, hverkuil, helen.koike, sboyd, linux-media,
	devicetree, linux-clk, linux-tegra, linux-kernel
In-Reply-To: <20200214164642.GA1310813@ulmo>


On 2/14/20 8:46 AM, Thierry Reding wrote:
> On Wed, Feb 05, 2020 at 01:23:24PM -0800, Sowjanya Komatineni wrote:
> [...]
>> +static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
>> +				       struct tegra_channel_buffer *buf)
>> +{
>> +	int err = 0;
>> +	u32 thresh, value, frame_start;
>> +	int bytes_per_line = chan->format.bytesperline;
>> +
>> +	/* program buffer address by using surface 0 */
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_OFFSET_MSB, 0x0);
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_OFFSET_LSB, buf->addr);
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_STRIDE, bytes_per_line);
>> +
>> +	/* increase syncpoint max */
>> +	thresh = host1x_syncpt_incr_max(chan->sp, 1);
>> +
>> +	/* program syncpoint */
>> +	frame_start = VI_CSI_PP_FRAME_START(chan->portno);
>> +	value = VI_CFG_VI_INCR_SYNCPT_COND(frame_start) |
>> +		host1x_syncpt_id(chan->sp);
>> +	tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
> Okay, so this programs the VI to increment the given syncpoint upon
> frame start? What is that VI_CSI_PP_FRAME_START(chan->portno) exactly?
This programs thresh for FS event. VI_CSI_PP_FRAME_START is frame start 
condition for corresponding port PPA that we program in INVR_SYNCPT to 
raise event for this condition.
>
>> +
>> +	vi_csi_write(chan, TEGRA_VI_CSI_SINGLE_SHOT, SINGLE_SHOT_CAPTURE);
> And now we start capturing in single-shot mode.
We set thres to have it raise event when it sees FS and we issue single 
shot which initiates capture with FS first and at end of frame capture 
we should see MW_ACK which confirms frame buffer memory write done.
>
>> +
>> +	/* move buffer to capture done queue */
>> +	spin_lock(&chan->done_lock);
>> +	list_add_tail(&buf->queue, &chan->done);
>> +	spin_unlock(&chan->done_lock);
>> +
>> +	/* wait up kthread for capture done */
>> +	wake_up_interruptible(&chan->done_wait);
> But this I don't understand. You wake up the kthread...

On issuing single start this wakes up other thread which checks for MW_ACK.

So one thread checks for FS and other checks for MW_ACK.

I do see race condition with this, so I had change in v3 where same 
capture thread sets both FS COND SYncpoint and also MW_aCK and once it 
see FS syncpt then only it wakes up other thread for MW_ACK otherwise it 
just returns buffer with error state.


>
>> +
>> +	/* use syncpoint to wake up */
>> +	err = host1x_syncpt_wait(chan->sp, thresh,
>> +				 TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
> ... and then wait for the syncpoint to reach the given threshold? Isn't
> that the wrong way around? Don't we need to wait for the syncpoint
> increment *before* we wake up the kthread that will return the buffer
> to userspace?
V3 has change to check for MW_ACK only on successful FS. Will send out 
v3 soon.
>> +	if (err) {
>> +		dev_err(&chan->video.dev,
>> +			"frame start syncpt timeout: %d\n", err);
>> +		tegra_channel_capture_error_status(chan);
>> +	}
>> +
>> +	return err;
>> +}
>> +
>> +static int tegra_channel_capture_done(struct tegra_vi_channel *chan,
>> +				      struct tegra_channel_buffer *buf)
>> +{
>> +	struct vb2_v4l2_buffer *vb = &buf->buf;
>> +	u32 thresh, value, mw_ack_done;
>> +	int ret = 0;
>> +
>> +	/* increase syncpoint max */
>> +	thresh = host1x_syncpt_incr_max(chan->sp, 1);
>> +
>> +	/* program syncpoint */
>> +	mw_ack_done = VI_CSI_MW_ACK_DONE(chan->portno);
>> +	value = VI_CFG_VI_INCR_SYNCPT_COND(mw_ack_done) |
>> +		host1x_syncpt_id(chan->sp);
>> +	tegra_vi_write(chan, TEGRA_VI_CFG_VI_INCR_SYNCPT, value);
>> +
>> +	if (!vi_csi_read(chan, TEGRA_VI_CSI_SINGLE_SHOT))
>> +		vi_csi_write(chan, TEGRA_VI_CSI_SINGLE_SHOT,
>> +			     SINGLE_SHOT_CAPTURE);
>> +
>> +	/* use syncpoint to wake up */
>> +	ret = host1x_syncpt_wait(chan->sp, thresh,
>> +				 TEGRA_VI_SYNCPT_WAIT_TIMEOUT, &value);
>> +	if (ret)
>> +		dev_err(&chan->video.dev,
>> +			"MW_ACK_DONE syncpoint timeout: %d\n", ret);
> Actually... there's another syncpoint wait here, so I guess this will
> stall until VI has actually completed writing the captured frame to
> memory.

Yes with v2 it will wait till it sees MW_ACK before returning buffer.

But as mentioned above, to avoid possible race condition moved 
programming both threshold for same frame in capture thread and only on 
receiving FS it wakes other thread to wait for MW_ACK and return buffer.


>> +
>> +	/* captured one frame */
>> +	vb->sequence = chan->sequence++;
>> +	vb->field = V4L2_FIELD_NONE;
>> +	vb->vb2_buf.timestamp = ktime_get_ns();
>> +	vb2_buffer_done(&vb->vb2_buf,
>> +			ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
> So it's really only at this point that we return the buffer to
> userspace, which should be after the hardware is done writing to the
> buffer, so this should be fine.
>
> That said, I'm wondering if host1x_syncpt_wait() is a good interface
> for this use-case. We don't really have anything else right now, but
> I think we may be able to add something to have a function called in
> case the syncpoint reaches a threshold. Having to spawn two separate
> threads with wait queues seems a bit overkill for this.
>
> It's fine to leave this as it is for now, but maybe something to
> consider as improvement in the future.
>
>> +	return ret;
>> +}
>> +
>> +static int chan_capture_kthread_start(void *data)
>> +{
>> +	struct tegra_vi_channel *chan = data;
>> +	struct tegra_channel_buffer *buf;
>> +	int err = 0;
>> +
>> +	set_freezable();
>> +
>> +	while (1) {
>> +		try_to_freeze();
>> +
>> +		wait_event_interruptible(chan->start_wait,
>> +					 !list_empty(&chan->capture) ||
>> +					 kthread_should_stop());
>> +		if (kthread_should_stop())
>> +			break;
>> +
>> +		if (err)
>> +			continue;
>> +
>> +		spin_lock(&chan->start_lock);
>> +		if (list_empty(&chan->capture)) {
>> +			spin_unlock(&chan->start_lock);
>> +			continue;
>> +		}
>> +
>> +		buf = list_entry(chan->capture.next,
>> +				 struct tegra_channel_buffer, queue);
>> +		list_del_init(&buf->queue);
>> +		spin_unlock(&chan->start_lock);
>> +		err = tegra_channel_capture_frame(chan, buf);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int chan_capture_kthread_done(void *data)
>> +{
>> +	struct tegra_vi_channel *chan = data;
>> +	struct tegra_channel_buffer *buf;
>> +	int err = 0;
>> +
>> +	set_freezable();
>> +
>> +	while (1) {
>> +		try_to_freeze();
>> +
>> +		wait_event_interruptible(chan->done_wait,
>> +					 !list_empty(&chan->done) ||
>> +					 kthread_should_stop());
>> +
>> +		if (kthread_should_stop())
>> +			break;
>> +
>> +		spin_lock(&chan->done_lock);
>> +		if (list_empty(&chan->done)) {
>> +			spin_unlock(&chan->done_lock);
>> +			continue;
>> +		}
>> +
>> +		buf = list_entry(chan->done.next, struct tegra_channel_buffer,
>> +				 queue);
>> +		if (!buf)
>> +			continue;
>> +
>> +		list_del_init(&buf->queue);
>> +		spin_unlock(&chan->done_lock);
>> +		err = tegra_channel_capture_done(chan, buf);
> What's with the error here? I think we should either handle it in some
> way, or just avoid even returning an error if we're not going to deal
> with it anyway.
>
> Thierry


v3 has proper implementation where on no frame start which happens when 
source is not streaming, we keep thread in wait till kthread stops and 
we dont dequeue buffers.

Once we see kthread stop then we return all buffers.


^ permalink raw reply

* [PATCH AUTOSEL 5.4 415/459] bpf: map_seq_next should always increase position index
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Vasily Averin, Daniel Borkmann, Sasha Levin, netdev, bpf
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Vasily Averin <vvs@virtuozzo.com>

[ Upstream commit 90435a7891a2259b0f74c5a1bc5600d0d64cba8f ]

If seq_file .next fuction does not change position index,
read after some lseek can generate an unexpected output.

See also: https://bugzilla.kernel.org/show_bug.cgi?id=206283

v1 -> v2: removed missed increment in end of function

Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/eca84fdd-c374-a154-d874-6c7b55fc3bc4@virtuozzo.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/inode.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index a70f7209cda3f..218c09ff6a273 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -196,6 +196,7 @@ static void *map_seq_next(struct seq_file *m, void *v, loff_t *pos)
 	void *key = map_iter(m)->key;
 	void *prev_key;
 
+	(*pos)++;
 	if (map_iter(m)->done)
 		return NULL;
 
@@ -208,8 +209,6 @@ static void *map_seq_next(struct seq_file *m, void *v, loff_t *pos)
 		map_iter(m)->done = true;
 		return NULL;
 	}
-
-	++(*pos);
 	return key;
 }
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH AUTOSEL 5.4 414/459] cifs: fix NULL dereference in match_prepath
From: Sasha Levin @ 2020-02-14 16:01 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Ronnie Sahlberg, Steve French, Sasha Levin, linux-cifs,
	samba-technical
In-Reply-To: <20200214160149.11681-1-sashal@kernel.org>

From: Ronnie Sahlberg <lsahlber@redhat.com>

[ Upstream commit fe1292686333d1dadaf84091f585ee903b9ddb84 ]

RHBZ: 1760879

Fix an oops in match_prepath() by making sure that the prepath string is not
NULL before we pass it into strcmp().

This is similar to other checks we make for example in cifs_root_iget()

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/cifs/connect.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 02451d085ddd0..5d3c867bdc808 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3652,8 +3652,10 @@ match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
 {
 	struct cifs_sb_info *old = CIFS_SB(sb);
 	struct cifs_sb_info *new = mnt_data->cifs_sb;
-	bool old_set = old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
-	bool new_set = new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
+	bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+		old->prepath;
+	bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+		new->prepath;
 
 	if (old_set && new_set && !strcmp(new->prepath, old->prepath))
 		return 1;
-- 
2.20.1


^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.