Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2023-10-11 09:20:52 +08:00
22 changed files with 468 additions and 198 deletions

View File

@@ -1,2 +1,2 @@
LINUX_VERSION-5.15 = .132
LINUX_KERNEL_HASH-5.15.132 = 4177b5c4d6e749bb8339ac4aa68eb0932ead9490b956a80d9a597089959618ac
LINUX_VERSION-5.15 = .134
LINUX_KERNEL_HASH-5.15.134 = f37182aecb57ed6853d01e1074d3a60a653331e35f3115728381e08be050b9d3

View File

@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=bsdiff
PKG_VERSION:=4.3
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.daemonology.net/bsdiff/

View File

@@ -1,6 +1,6 @@
--- a/bsdiff.c 2005-08-17 00:13:52.000000000 +0200
+++ b/bsdiff.c 2016-02-21 01:39:31.157915765 +0100
@@ -101,7 +101,7 @@
--- a/bsdiff.c
+++ b/bsdiff.c
@@ -101,7 +101,7 @@ static void split(off_t *I,off_t *V,off_
if(start+len>kk) split(I,V,kk,start+len-kk,h);
}
@@ -9,7 +9,7 @@
{
off_t buckets[256];
off_t i,h,len;
@@ -139,7 +139,7 @@
@@ -139,7 +139,7 @@ static void qsufsort(off_t *I,off_t *V,u
for(i=0;i<oldsize+1;i++) I[V[i]]=i;
}
@@ -18,7 +18,7 @@
{
off_t i;
@@ -149,8 +149,8 @@
@@ -149,8 +149,8 @@ static off_t matchlen(u_char *old,off_t
return i;
}
@@ -29,7 +29,7 @@
{
off_t x,y;
@@ -175,7 +175,7 @@
@@ -175,7 +175,7 @@ static off_t search(off_t *I,u_char *old
};
}
@@ -38,7 +38,7 @@
{
off_t y;
@@ -196,7 +196,7 @@
@@ -196,7 +196,7 @@ static void offtout(off_t x,u_char *buf)
int main(int argc,char *argv[])
{
int fd;
@@ -47,7 +47,7 @@
off_t oldsize,newsize;
off_t *I,*V;
off_t scan,pos,len;
@@ -206,9 +206,9 @@
@@ -206,9 +206,9 @@ int main(int argc,char *argv[])
off_t overlap,Ss,lens;
off_t i;
off_t dblen,eblen;
@@ -60,9 +60,9 @@
FILE * pf;
BZFILE * pfbz2;
int bz2err;
--- a/bspatch.c 2005-08-17 00:14:00.000000000 +0200
+++ b/bspatch.c 2016-02-21 01:39:29.753859970 +0100
@@ -36,7 +36,7 @@
--- a/bspatch.c
+++ b/bspatch.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/b
#include <unistd.h>
#include <fcntl.h>
@@ -71,7 +71,7 @@
{
off_t y;
@@ -62,8 +62,8 @@
@@ -62,8 +62,8 @@ int main(int argc,char * argv[])
int fd;
ssize_t oldsize,newsize;
ssize_t bzctrllen,bzdatalen;

View File

@@ -0,0 +1,37 @@
From: The FreeBSD Project
Bug: https://security-tracker.debian.org/tracker/CVE-2014-9862
Subject: CVE-2014-9862 - check for a negative value on numbers of bytes
The implementation of bspatch does not check for a negative value on numbers
of bytes read from the diff and extra streams, allowing an attacker who
can control the patch file to write at arbitrary locations in the heap.
.
bspatch's main loop reads three numbers from the "control" stream in
the patch: X, Y and Z. The first two are the number of bytes to read
from "diff" and "extra" (and thus only non-negative), while the
third one could be positive or negative and moves the oldpos pointer
on the source image. These 3 values are 64bits signed ints (encoded
somehow on the file) that are later passed the function that reads
from the streams, but those values are not verified to be
non-negative.
.
Official report https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-9862
The patch was downloaded from a link pointed by
https://security.freebsd.org/advisories/FreeBSD-SA-16:25.bsp
---
bspatch.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/bspatch.c
+++ b/bspatch.c
@@ -152,6 +152,10 @@ int main(int argc,char * argv[])
};
/* Sanity-check */
+ if ((ctrl[0] < 0) || (ctrl[1] < 0))
+ errx(1,"Corrupt patch\n");
+
+ /* Sanity-check */
if(newpos+ctrl[0]>newsize)
errx(1,"Corrupt patch\n");

View File

@@ -0,0 +1,383 @@
Description: patch for CVE-2020-14315
A memory corruption vulnerability is present in bspatch as shipped in
Colin Percivals bsdiff tools version 4.3. Insufficient checks when
handling external inputs allows an attacker to bypass the sanity checks
in place and write out of a dynamically allocated buffer boundaries.
Source: https://svnweb.freebsd.org/base/head/usr.bin/bsdiff/bspatch/bspatch.c?revision=352742&view=co
Author: tony mancill <tmancill@debian.org>
Comment: The patch was created by comparing the Debian sources to the
"Confirmed Patched Version" [1] documented in the
X41 D-SEC GmbH Security Advisory: X41-2020-006 [2].
References to FreeBSD capsicum have been dropped. Definitions for
TYPE_MINIMUM and TYPE_MAXIMUM have been borrowed from the Debian
coreutils package sources but originate in gnulib [3] and are used to
define OFF_MIN and OFF_MAX (limits of off_t). Whitespace changes from
the confirmed patched version are also included and keep the difference
between the Debian sources and the confirmed patched version minimal.
.
[1] https://svnweb.freebsd.org/base/head/usr.bin/bsdiff/bspatch/bspatch.c?revision=352742&view=co
[2] https://www.openwall.com/lists/oss-security/2020/07/09/2
[3] https://www.gnu.org/software/gnulib/
Last-Update: 2021-04-03
Forwarded: not-needed
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=964796
--- a/bspatch.c
+++ b/bspatch.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright 2003-2005 Colin Percival
* All rights reserved
*
@@ -25,55 +27,147 @@
*/
#if 0
-__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $");
+__FBSDID("$FreeBSD$");
#endif
#include <bzlib.h>
-#include <stdlib.h>
+#include <err.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <err.h>
#include <unistd.h>
-#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#define HEADER_SIZE 32
+
+/* TYPE_MINIMUM and TYPE_MAXIMUM taken from coreutils */
+#ifndef TYPE_MINIMUM
+#define TYPE_MINIMUM(t) \
+ ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t)))
+#endif
+#ifndef TYPE_MAXIMUM
+#define TYPE_MAXIMUM(t) \
+ ((t) ((t) 0 < (t) -1 \
+ ? (t) -1 \
+ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+#endif
+
+#ifndef OFF_MAX
+#define OFF_MAX TYPE_MAXIMUM(off_t)
+#endif
+
+#ifndef OFF_MIN
+#define OFF_MIN TYPE_MINIMUM(off_t)
+#endif
+
+static char *newfile;
+static int dirfd = -1;
+
+static void
+exit_cleanup(void)
+{
+
+ if (dirfd != -1 && newfile != NULL)
+ if (unlinkat(dirfd, newfile, 0))
+ warn("unlinkat");
+}
+
+static inline off_t
+add_off_t(off_t a, off_t b)
+{
+ off_t result;
+
+#if __GNUC__ >= 5 || \
+ (defined(__has_builtin) && __has_builtin(__builtin_add_overflow))
+ if (__builtin_add_overflow(a, b, &result))
+ errx(1, "Corrupt patch");
+#else
+ if ((b > 0 && a > OFF_MAX - b) || (b < 0 && a < OFF_MIN - b))
+ errx(1, "Corrupt patch");
+ result = a + b;
+#endif
+ return result;
+}
static off_t offtin(unsigned char *buf)
{
off_t y;
- y=buf[7]&0x7F;
- y=y*256;y+=buf[6];
- y=y*256;y+=buf[5];
- y=y*256;y+=buf[4];
- y=y*256;y+=buf[3];
- y=y*256;y+=buf[2];
- y=y*256;y+=buf[1];
- y=y*256;y+=buf[0];
+ y = buf[7] & 0x7F;
+ y = y * 256; y += buf[6];
+ y = y * 256; y += buf[5];
+ y = y * 256; y += buf[4];
+ y = y * 256; y += buf[3];
+ y = y * 256; y += buf[2];
+ y = y * 256; y += buf[1];
+ y = y * 256; y += buf[0];
- if(buf[7]&0x80) y=-y;
+ if (buf[7] & 0x80)
+ y = -y;
- return y;
+ return (y);
}
-int main(int argc,char * argv[])
+static void
+usage(void)
{
- FILE * f, * cpf, * dpf, * epf;
- BZFILE * cpfbz2, * dpfbz2, * epfbz2;
+
+ fprintf(stderr, "usage: bspatch oldfile newfile patchfile\n");
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *f, *cpf, *dpf, *epf;
+ BZFILE *cpfbz2, *dpfbz2, *epfbz2;
+ char *directory, *namebuf;
int cbz2err, dbz2err, ebz2err;
- int fd;
- ssize_t oldsize,newsize;
- ssize_t bzctrllen,bzdatalen;
- unsigned char header[32],buf[8];
+ int newfd, oldfd;
+ off_t oldsize, newsize;
+ off_t bzctrllen, bzdatalen;
+ unsigned char header[HEADER_SIZE], buf[8];
unsigned char *old, *new;
- off_t oldpos,newpos;
+ off_t oldpos, newpos;
off_t ctrl[3];
- off_t lenread;
- off_t i;
+ off_t i, lenread, offset;
- if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
+ if (argc != 4)
+ usage();
/* Open patch file */
- if ((f = fopen(argv[3], "r")) == NULL)
+ if ((f = fopen(argv[3], "rb")) == NULL)
+ err(1, "fopen(%s)", argv[3]);
+ /* Open patch file for control block */
+ if ((cpf = fopen(argv[3], "rb")) == NULL)
+ err(1, "fopen(%s)", argv[3]);
+ /* open patch file for diff block */
+ if ((dpf = fopen(argv[3], "rb")) == NULL)
err(1, "fopen(%s)", argv[3]);
+ /* open patch file for extra block */
+ if ((epf = fopen(argv[3], "rb")) == NULL)
+ err(1, "fopen(%s)", argv[3]);
+ /* open oldfile */
+ if ((oldfd = open(argv[1], O_RDONLY | O_BINARY, 0)) < 0)
+ err(1, "open(%s)", argv[1]);
+ /* open directory where we'll write newfile */
+ if ((namebuf = strdup(argv[2])) == NULL ||
+ (directory = dirname(namebuf)) == NULL ||
+ (dirfd = open(directory, O_DIRECTORY)) < 0)
+ err(1, "open %s", argv[2]);
+ free(namebuf);
+ if ((newfile = basename(argv[2])) == NULL)
+ err(1, "basename");
+ /* open newfile */
+ if ((newfd = openat(dirfd, newfile,
+ O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0)
+ err(1, "open(%s)", argv[2]);
+ atexit(exit_cleanup);
/*
File format:
@@ -90,104 +184,104 @@ int main(int argc,char * argv[])
*/
/* Read header */
- if (fread(header, 1, 32, f) < 32) {
+ if (fread(header, 1, HEADER_SIZE, f) < HEADER_SIZE) {
if (feof(f))
- errx(1, "Corrupt patch\n");
+ errx(1, "Corrupt patch");
err(1, "fread(%s)", argv[3]);
}
/* Check for appropriate magic */
if (memcmp(header, "BSDIFF40", 8) != 0)
- errx(1, "Corrupt patch\n");
+ errx(1, "Corrupt patch");
/* Read lengths from header */
- bzctrllen=offtin(header+8);
- bzdatalen=offtin(header+16);
- newsize=offtin(header+24);
- if((bzctrllen<0) || (bzdatalen<0) || (newsize<0))
- errx(1,"Corrupt patch\n");
+ bzctrllen = offtin(header + 8);
+ bzdatalen = offtin(header + 16);
+ newsize = offtin(header + 24);
+ if (bzctrllen < 0 || bzctrllen > OFF_MAX - HEADER_SIZE ||
+ bzdatalen < 0 || bzctrllen + HEADER_SIZE > OFF_MAX - bzdatalen ||
+ newsize < 0 || newsize > SSIZE_MAX)
+ errx(1, "Corrupt patch");
/* Close patch file and re-open it via libbzip2 at the right places */
if (fclose(f))
err(1, "fclose(%s)", argv[3]);
- if ((cpf = fopen(argv[3], "r")) == NULL)
- err(1, "fopen(%s)", argv[3]);
- if (fseeko(cpf, 32, SEEK_SET))
- err(1, "fseeko(%s, %lld)", argv[3],
- (long long)32);
+ offset = HEADER_SIZE;
+ if (fseeko(cpf, offset, SEEK_SET))
+ err(1, "fseeko(%s, %jd)", argv[3], (intmax_t)offset);
if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
- if ((dpf = fopen(argv[3], "r")) == NULL)
- err(1, "fopen(%s)", argv[3]);
- if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
- err(1, "fseeko(%s, %lld)", argv[3],
- (long long)(32 + bzctrllen));
+ offset = add_off_t(offset, bzctrllen);
+ if (fseeko(dpf, offset, SEEK_SET))
+ err(1, "fseeko(%s, %jd)", argv[3], (intmax_t)offset);
if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
- if ((epf = fopen(argv[3], "r")) == NULL)
- err(1, "fopen(%s)", argv[3]);
- if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
- err(1, "fseeko(%s, %lld)", argv[3],
- (long long)(32 + bzctrllen + bzdatalen));
+ offset = add_off_t(offset, bzdatalen);
+ if (fseeko(epf, offset, SEEK_SET))
+ err(1, "fseeko(%s, %jd)", argv[3], (intmax_t)offset);
if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
- if(((fd=open(argv[1],O_RDONLY,0))<0) ||
- ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
- ((old=malloc(oldsize+1))==NULL) ||
- (lseek(fd,0,SEEK_SET)!=0) ||
- (read(fd,old,oldsize)!=oldsize) ||
- (close(fd)==-1)) err(1,"%s",argv[1]);
- if((new=malloc(newsize+1))==NULL) err(1,NULL);
-
- oldpos=0;newpos=0;
- while(newpos<newsize) {
+ if ((oldsize = lseek(oldfd, 0, SEEK_END)) == -1 ||
+ oldsize > SSIZE_MAX ||
+ (old = malloc(oldsize)) == NULL ||
+ lseek(oldfd, 0, SEEK_SET) != 0 ||
+ read(oldfd, old, oldsize) != oldsize ||
+ close(oldfd) == -1)
+ err(1, "%s", argv[1]);
+ if ((new = malloc(newsize)) == NULL)
+ err(1, NULL);
+
+ oldpos = 0;
+ newpos = 0;
+ while (newpos < newsize) {
/* Read control data */
- for(i=0;i<=2;i++) {
+ for (i = 0; i <= 2; i++) {
lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
if ((lenread < 8) || ((cbz2err != BZ_OK) &&
(cbz2err != BZ_STREAM_END)))
- errx(1, "Corrupt patch\n");
- ctrl[i]=offtin(buf);
- };
+ errx(1, "Corrupt patch");
+ ctrl[i] = offtin(buf);
+ }
/* Sanity-check */
- if ((ctrl[0] < 0) || (ctrl[1] < 0))
- errx(1,"Corrupt patch\n");
+ if (ctrl[0] < 0 || ctrl[0] > INT_MAX ||
+ ctrl[1] < 0 || ctrl[1] > INT_MAX)
+ errx(1, "Corrupt patch");
/* Sanity-check */
- if(newpos+ctrl[0]>newsize)
- errx(1,"Corrupt patch\n");
+ if (add_off_t(newpos, ctrl[0]) > newsize)
+ errx(1, "Corrupt patch");
/* Read diff string */
lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]);
if ((lenread < ctrl[0]) ||
((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
- errx(1, "Corrupt patch\n");
+ errx(1, "Corrupt patch");
/* Add old data to diff string */
- for(i=0;i<ctrl[0];i++)
- if((oldpos+i>=0) && (oldpos+i<oldsize))
- new[newpos+i]+=old[oldpos+i];
+ for (i = 0; i < ctrl[0]; i++)
+ if (add_off_t(oldpos, i) < oldsize)
+ new[newpos + i] += old[oldpos + i];
/* Adjust pointers */
- newpos+=ctrl[0];
- oldpos+=ctrl[0];
+ newpos = add_off_t(newpos, ctrl[0]);
+ oldpos = add_off_t(oldpos, ctrl[0]);
/* Sanity-check */
- if(newpos+ctrl[1]>newsize)
- errx(1,"Corrupt patch\n");
+ if (add_off_t(newpos, ctrl[1]) > newsize)
+ errx(1, "Corrupt patch");
/* Read extra string */
lenread = BZ2_bzRead(&ebz2err, epfbz2, new + newpos, ctrl[1]);
if ((lenread < ctrl[1]) ||
((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
- errx(1, "Corrupt patch\n");
+ errx(1, "Corrupt patch");
/* Adjust pointers */
- newpos+=ctrl[1];
- oldpos+=ctrl[2];
- };
+ newpos = add_off_t(newpos, ctrl[1]);
+ oldpos = add_off_t(oldpos, ctrl[2]);
+ }
/* Clean up the bzip2 reads */
BZ2_bzReadClose(&cbz2err, cpfbz2);
@@ -197,12 +291,13 @@ int main(int argc,char * argv[])
err(1, "fclose(%s)", argv[3]);
/* Write the new file */
- if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
- (write(fd,new,newsize)!=newsize) || (close(fd)==-1))
- err(1,"%s",argv[2]);
+ if (write(newfd, new, newsize) != newsize || close(newfd) == -1)
+ err(1, "%s", argv[2]);
+ /* Disable atexit cleanup */
+ newfile = NULL;
free(new);
free(old);
- return 0;
+ return (0);
}

View File

@@ -14,15 +14,15 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -3033,6 +3033,7 @@ int brcmnand_probe(struct platform_devic
@@ -3059,6 +3059,7 @@ int brcmnand_probe(struct platform_devic
dev_set_drvdata(dev, ctrl);
ctrl->dev = dev;
+ ctrl->soc = soc;
init_completion(&ctrl->done);
init_completion(&ctrl->dma_done);
@@ -3173,8 +3174,6 @@ int brcmnand_probe(struct platform_devic
/* Enable the static key if the soc provides I/O operations indicating
* that a non-memory mapped IO access path must be used
@@ -3205,8 +3206,6 @@ int brcmnand_probe(struct platform_devic
* interesting ways
*/
if (soc) {

View File

@@ -1,150 +0,0 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
Date: Fri, 07 Jan 2022 10:46:07 -0800
Content-Type: text/plain; charset="utf-8"
Allow a brcmnand_soc instance to provide a custom set of I/O operations
which we will require when using this driver on a BCMA bus which is not
directly memory mapped I/O. Update the nand_{read,write}_reg accordingly
to use the SoC operations if provided.
To minimize the penalty on other SoCs which do support standard MMIO
accesses, we use a static key which is disabled by default and gets
enabled if a soc implementation does provide I/O operations.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 28 +++++++++++++++++++++--
drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 ++++++++++++++++++++++++
2 files changed, 55 insertions(+), 2 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -25,6 +25,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
+#include <linux/static_key.h>
#include <linux/list.h>
#include <linux/log2.h>
@@ -207,6 +208,8 @@ enum {
struct brcmnand_host;
+static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key);
+
struct brcmnand_controller {
struct device *dev;
struct nand_controller controller;
@@ -592,15 +595,25 @@ enum {
INTFC_CTLR_READY = BIT(31),
};
+static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
+{
+ return static_branch_unlikely(&brcmnand_soc_has_ops_key);
+}
+
static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
{
+ if (brcmnand_non_mmio_ops(ctrl))
+ return brcmnand_soc_read(ctrl->soc, offs);
return brcmnand_readl(ctrl->nand_base + offs);
}
static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs,
u32 val)
{
- brcmnand_writel(val, ctrl->nand_base + offs);
+ if (brcmnand_non_mmio_ops(ctrl))
+ brcmnand_soc_write(ctrl->soc, val, offs);
+ else
+ brcmnand_writel(val, ctrl->nand_base + offs);
}
static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
@@ -766,13 +779,18 @@ static inline void brcmnand_rmw_reg(stru
static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word)
{
+ if (brcmnand_non_mmio_ops(ctrl))
+ return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR);
return __raw_readl(ctrl->nand_fc + word * 4);
}
static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl,
int word, u32 val)
{
- __raw_writel(val, ctrl->nand_fc + word * 4);
+ if (brcmnand_non_mmio_ops(ctrl))
+ brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR);
+ else
+ __raw_writel(val, ctrl->nand_fc + word * 4);
}
static inline void edu_writel(struct brcmnand_controller *ctrl,
@@ -3035,6 +3053,12 @@ int brcmnand_probe(struct platform_devic
ctrl->dev = dev;
ctrl->soc = soc;
+ /* Enable the static key if the soc provides I/O operations indicating
+ * that a non-memory mapped IO access path must be used
+ */
+ if (brcmnand_soc_has_ops(ctrl->soc))
+ static_branch_enable(&brcmnand_soc_has_ops_key);
+
init_completion(&ctrl->done);
init_completion(&ctrl->dma_done);
init_completion(&ctrl->edu_done);
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -11,12 +11,25 @@
struct platform_device;
struct dev_pm_ops;
+struct brcmnand_io_ops;
+
+/* Special register offset constant to intercept a non-MMIO access
+ * to the flash cache register space. This is intentionally large
+ * not to overlap with an existing offset.
+ */
+#define BRCMNAND_NON_MMIO_FC_ADDR 0xffffffff
struct brcmnand_soc {
bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
bool is_param);
+ const struct brcmnand_io_ops *ops;
+};
+
+struct brcmnand_io_ops {
+ u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset);
+ void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset);
};
static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
@@ -58,6 +71,22 @@ static inline void brcmnand_writel(u32 v
writel_relaxed(val, addr);
}
+static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc)
+{
+ return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg;
+}
+
+static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset)
+{
+ return soc->ops->read_reg(soc, offset);
+}
+
+static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val,
+ u32 offset)
+{
+ soc->ops->write_reg(soc, val, offset);
+}
+
int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc);
int brcmnand_remove(struct platform_device *pdev);

View File

@@ -16,7 +16,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2806,7 +2806,7 @@ static const struct nand_controller_ops
@@ -2814,7 +2814,7 @@ static const struct nand_controller_ops
static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
{
struct brcmnand_controller *ctrl = host->ctrl;
@@ -25,7 +25,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
struct mtd_info *mtd;
struct nand_chip *chip;
int ret;
@@ -2814,7 +2814,7 @@ static int brcmnand_init_cs(struct brcmn
@@ -2822,7 +2822,7 @@ static int brcmnand_init_cs(struct brcmn
ret = of_property_read_u32(dn, "reg", &host->cs);
if (ret) {
@@ -34,7 +34,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
return -ENXIO;
}
@@ -2823,13 +2823,13 @@ static int brcmnand_init_cs(struct brcmn
@@ -2831,13 +2831,13 @@ static int brcmnand_init_cs(struct brcmn
nand_set_flash_node(chip, dn);
nand_set_controller_data(chip, host);

View File

@@ -17,7 +17,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2803,7 +2803,7 @@ static const struct nand_controller_ops
@@ -2811,7 +2811,7 @@ static const struct nand_controller_ops
.attach_chip = brcmnand_attach_chip,
};
@@ -26,7 +26,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
{
struct brcmnand_controller *ctrl = host->ctrl;
struct device *dev = ctrl->dev;
@@ -2812,16 +2812,9 @@ static int brcmnand_init_cs(struct brcmn
@@ -2820,16 +2820,9 @@ static int brcmnand_init_cs(struct brcmn
int ret;
u16 cfg_offs;
@@ -43,7 +43,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
nand_set_controller_data(chip, host);
mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d",
host->cs);
@@ -3228,7 +3221,16 @@ int brcmnand_probe(struct platform_devic
@@ -3236,7 +3229,16 @@ int brcmnand_probe(struct platform_devic
host->pdev = pdev;
host->ctrl = ctrl;

View File

@@ -23,7 +23,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
unsigned int dma_irq;
int nand_version;
@@ -1642,7 +1642,7 @@ static bool brcmstb_nand_wait_for_comple
@@ -1650,7 +1650,7 @@ static bool brcmstb_nand_wait_for_comple
bool err = false;
int sts;
@@ -32,7 +32,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
/* switch to interrupt polling and PIO mode */
disable_ctrl_irqs(ctrl);
sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY,
@@ -3179,33 +3179,29 @@ int brcmnand_probe(struct platform_devic
@@ -3187,33 +3187,29 @@ int brcmnand_probe(struct platform_devic
}
/* IRQ */

View File

@@ -23,7 +23,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
#include <linux/err.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
@@ -2803,7 +2804,8 @@ static const struct nand_controller_ops
@@ -2811,7 +2812,8 @@ static const struct nand_controller_ops
.attach_chip = brcmnand_attach_chip,
};
@@ -33,7 +33,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
{
struct brcmnand_controller *ctrl = host->ctrl;
struct device *dev = ctrl->dev;
@@ -2856,7 +2858,7 @@ static int brcmnand_init_cs(struct brcmn
@@ -2864,7 +2866,7 @@ static int brcmnand_init_cs(struct brcmn
if (ret)
return ret;
@@ -42,7 +42,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
if (ret)
nand_cleanup(chip);
@@ -3025,17 +3027,15 @@ static int brcmnand_edu_setup(struct pla
@@ -3033,17 +3035,15 @@ static int brcmnand_edu_setup(struct pla
int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
{
@@ -63,7 +63,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
return -ENODEV;
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
@@ -3062,7 +3062,7 @@ int brcmnand_probe(struct platform_devic
@@ -3070,7 +3070,7 @@ int brcmnand_probe(struct platform_devic
/* NAND register range */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ctrl->nand_base = devm_ioremap_resource(dev, res);
@@ -72,7 +72,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
return PTR_ERR(ctrl->nand_base);
/* Enable clock before using NAND registers */
@@ -3206,7 +3206,6 @@ int brcmnand_probe(struct platform_devic
@@ -3214,7 +3214,6 @@ int brcmnand_probe(struct platform_devic
for_each_available_child_of_node(dn, child) {
if (of_device_is_compatible(child, "brcm,nandcs")) {
@@ -80,7 +80,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
if (!host) {
@@ -3226,7 +3225,7 @@ int brcmnand_probe(struct platform_devic
@@ -3234,7 +3233,7 @@ int brcmnand_probe(struct platform_devic
nand_set_flash_node(&host->chip, child);
@@ -89,7 +89,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
if (ret) {
devm_kfree(dev, host);
continue; /* Try all chip-selects */
@@ -3236,6 +3235,32 @@ int brcmnand_probe(struct platform_devic
@@ -3244,6 +3243,32 @@ int brcmnand_probe(struct platform_devic
}
}

View File

@@ -14,7 +14,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -916,6 +916,12 @@ static void brcmnand_wr_corr_thresh(stru
@@ -951,6 +951,12 @@ static void brcmnand_wr_corr_thresh(stru
static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl)
{

View File

@@ -187,7 +187,7 @@ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips");
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -598,7 +598,11 @@ enum {
@@ -627,7 +627,11 @@ enum {
static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
{

View File

@@ -20,7 +20,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -37,7 +37,11 @@
@@ -38,7 +38,11 @@
* 1: NAND_WP is set by default, cleared for erase/write operations
* 2: NAND_WP is always cleared
*/

View File

@@ -382,7 +382,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
}
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1083,6 +1083,7 @@ static struct mm_struct *mm_init(struct
@@ -1091,6 +1091,7 @@ static struct mm_struct *mm_init(struct
goto fail_nocontext;
mm->user_ns = get_user_ns(user_ns);
@@ -390,7 +390,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
return mm;
fail_nocontext:
@@ -1125,6 +1126,7 @@ static inline void __mmput(struct mm_str
@@ -1133,6 +1134,7 @@ static inline void __mmput(struct mm_str
}
if (mm->binfmt)
module_put(mm->binfmt->module);
@@ -398,7 +398,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mmdrop(mm);
}
@@ -2617,6 +2619,13 @@ pid_t kernel_clone(struct kernel_clone_a
@@ -2625,6 +2627,13 @@ pid_t kernel_clone(struct kernel_clone_a
get_task_struct(p);
}

View File

@@ -116,7 +116,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
extern spinlock_t css_set_lock;
#define task_css_set_check(task, __c) \
rcu_dereference_check((task)->cgroups, \
@@ -708,6 +719,8 @@ struct cgroup;
@@ -709,6 +720,8 @@ struct cgroup;
static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; }
static inline void css_get(struct cgroup_subsys_state *css) {}
static inline void css_put(struct cgroup_subsys_state *css) {}

View File

@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -7729,7 +7729,7 @@ static int nft_register_flowtable_net_ho
@@ -7707,7 +7707,7 @@ static int nft_register_flowtable_net_ho
err = flowtable->data.type->setup(&flowtable->data,
hook->ops.dev,
FLOW_BLOCK_BIND);

View File

@@ -51,7 +51,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/arch/arm/mach-mvebu/kirkwood.c
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -14,6 +14,7 @@
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>

View File

@@ -134,7 +134,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* Define if arch has non-standard setup. This is a _PCI_ standard
@@ -894,6 +897,12 @@ struct ata_port {
@@ -898,6 +901,12 @@ struct ata_port {
#ifdef CONFIG_ATA_ACPI
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
#endif

View File

@@ -19,7 +19,7 @@
},
[PORT_NPCM] = {
.name = "Nuvoton 16550",
@@ -2763,6 +2763,11 @@ serial8250_do_set_termios(struct uart_po
@@ -2766,6 +2766,11 @@ serial8250_do_set_termios(struct uart_po
unsigned long flags;
unsigned int baud, quot, frac = 0;

View File

@@ -72,7 +72,7 @@ Signed-off-by: Wolfram Sang <wsa@kernel.org>
idev->adapter.dev.parent = &pdev->dev;
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -1024,7 +1024,7 @@ static int aspeed_i2c_probe_bus(struct p
@@ -1027,7 +1027,7 @@ static int aspeed_i2c_probe_bus(struct p
bus->adap.algo = &aspeed_i2c_algo;
bus->adap.dev.parent = &pdev->dev;
bus->adap.dev.of_node = pdev->dev.of_node;

View File

@@ -36,7 +36,7 @@
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -923,6 +923,8 @@ struct ata_port_operations {
@@ -927,6 +927,8 @@ struct ata_port_operations {
enum ata_completion_errors (*qc_prep)(struct ata_queued_cmd *qc);
unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
@@ -45,7 +45,7 @@
/*
* Configuration and exception handling
@@ -1013,6 +1015,9 @@ struct ata_port_operations {
@@ -1017,6 +1019,9 @@ struct ata_port_operations {
void (*phy_reset)(struct ata_port *ap);
void (*eng_timeout)(struct ata_port *ap);