1
0
Fork 0

NAND core changes:

- Two batchs of cleanups of the NAND API, including:
   * Deprecating a lot of interfaces (now replaced by ->exec_op()).
   * Moving code in separate drivers (JEDEC, ONFI), in private files
     (internals), in platform drivers, etc.
   * Functions/structures reordering.
   * Exclusive use of the nand_chip structure instead of the MTD one
     all across the subsystem.
 - Addition of the nand_wait_readrdy/rdy_op() helpers.
 
 Raw NAND controllers drivers changes:
 - Various coccinelle patches.
 - Marvell:
   * Use regmap_update_bits() for syscon access.
   * More documentation.
   * BCH failure path rework.
   * More layouts to be supported.
   * IRQ handler complete() condition fixed.
 - Fsl_ifc:
   * SRAM initialization fixed for newer controller versions.
 - Denali:
   * Fix licenses mismatch and use a SPDX tag.
   * Set SPARE_AREA_SKIP_BYTES register to 8 if unset.
 - Qualcomm:
   * Do not include dma-direct.h.
 - Docg4:
   * Removed.
 - Ams-delta:
   * Use of a GPIO lookup table
   * Internal machinery changes.
 
 Raw NAND chip drivers changes:
 - Toshiba:
   * Add support for Toshiba memory BENAND
   * Pass a single nand_chip object to the status helper.
 - ESMT:
   * New driver to retrieve the ECC requirements from the 5th ID byte.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAlvDdvgACgkQJWrqGEe9
 VoQ0zQf/QfXYjLDbC/1FXckEkEeVZPRbXQMf+ptdTo0inJefy9LMOvhRKmuABCxn
 wwPa99aqQ+aHESnU/s2d8FUrhNRUf35lmRIAP512lJk79tBfgo73l5WSc6UTg6hO
 w3KbigOvTi7wCKQYGDFOBZuoFFCvpNsIEtWFuodCbYG1GmeAaL7L2fhbri9JbcE2
 zPqmCv0w5BUrPR7i/taI5gD+KDtRdmCEyfb7wQoJy2XZVO0SKqGsBhDhYWqwCpck
 eP2UzQ4cFT8X1S0/AfUpbowc6cftdqIwW9VRY4inx3ALQ+sKxrkJ+0E3gL9lnZ+F
 p/is0gTdvDmnOjXfwGcL7GXGy0nN8Q==
 =EKv1
 -----END PGP SIGNATURE-----

Merge tag 'nand/for-4.20' of git://git.infradead.org/linux-mtd into mtd/next

NAND core changes:
- Two batchs of cleanups of the NAND API, including:
  * Deprecating a lot of interfaces (now replaced by ->exec_op()).
  * Moving code in separate drivers (JEDEC, ONFI), in private files
    (internals), in platform drivers, etc.
  * Functions/structures reordering.
  * Exclusive use of the nand_chip structure instead of the MTD one
    all across the subsystem.
- Addition of the nand_wait_readrdy/rdy_op() helpers.

Raw NAND controllers drivers changes:
- Various coccinelle patches.
- Marvell:
  * Use regmap_update_bits() for syscon access.
  * More documentation.
  * BCH failure path rework.
  * More layouts to be supported.
  * IRQ handler complete() condition fixed.
- Fsl_ifc:
  * SRAM initialization fixed for newer controller versions.
- Denali:
  * Fix licenses mismatch and use a SPDX tag.
  * Set SPARE_AREA_SKIP_BYTES register to 8 if unset.
- Qualcomm:
  * Do not include dma-direct.h.
- Docg4:
  * Removed.
- Ams-delta:
  * Use of a GPIO lookup table
  * Internal machinery changes.

Raw NAND chip drivers changes:
- Toshiba:
  * Add support for Toshiba memory BENAND
  * Pass a single nand_chip object to the status helper.
- ESMT:
  * New driver to retrieve the ECC requirements from the 5th ID byte.
This commit is contained in:
Boris Brezillon 2018-10-19 09:20:09 +02:00
commit 042c1a5a60
346 changed files with 6525 additions and 7435 deletions

View file

@ -73,3 +73,12 @@ KernelVersion: 3.0
Contact: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Description:
Number of sectors written by the frontend.
What: /sys/bus/xen-backend/devices/*/state
Date: August 2018
KernelVersion: 4.19
Contact: Joe Jin <joe.jin@oracle.com>
Description:
The state of the device. One of: 'Unknown',
'Initialising', 'Initialised', 'Connected', 'Closing',
'Closed', 'Reconfiguring', 'Reconfigured'.

View file

@ -15,3 +15,13 @@ Description:
blkback. If the frontend tries to use more than
max_persistent_grants, the LRU kicks in and starts
removing 5% of max_persistent_grants every 100ms.
What: /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds
Date: August 2018
KernelVersion: 4.19
Contact: Roger Pau Monné <roger.pau@citrix.com>
Description:
How long a persistent grant is allowed to remain
allocated without being in use. The time is in
seconds, 0 means indefinitely long.
The default is 60 seconds.

View file

@ -200,7 +200,7 @@ prctl(PR_SVE_SET_VL, unsigned long arg)
thread.
* Changing the vector length causes all of P0..P15, FFR and all bits of
Z0..V31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
unspecified. Calling PR_SVE_SET_VL with vl equal to the thread's current
vector length, or calling PR_SVE_SET_VL with the PR_SVE_SET_VL_ONEXEC
flag, does not constitute a change to the vector length for this purpose.
@ -500,7 +500,7 @@ References
[2] arch/arm64/include/uapi/asm/ptrace.h
AArch64 Linux ptrace ABI definitions
[3] linux/Documentation/arm64/cpu-feature-registers.txt
[3] Documentation/arm64/cpu-feature-registers.txt
[4] ARM IHI0055C
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf

View file

@ -11,7 +11,7 @@ The RISC-V supervisor ISA manual specifies three interrupt sources that are
attached to every HLIC: software interrupts, the timer interrupt, and external
interrupts. Software interrupts are used to send IPIs between cores. The
timer interrupt comes from an architecturally mandated real-time timer that is
controller via Supervisor Binary Interface (SBI) calls and CSR reads. External
controlled via Supervisor Binary Interface (SBI) calls and CSR reads. External
interrupts connect all other device interrupts to the HLIC, which are routed
via the platform-level interrupt controller (PLIC).
@ -25,7 +25,15 @@ in the system.
Required properties:
- compatible : "riscv,cpu-intc"
- #interrupt-cells : should be <1>
- #interrupt-cells : should be <1>. The interrupt sources are defined by the
RISC-V supervisor ISA manual, with only the following three interrupts being
defined for supervisor mode:
- Source 1 is the supervisor software interrupt, which can be sent by an SBI
call and is reserved for use by software.
- Source 5 is the supervisor timer interrupt, which can be configured by
SBI calls and implements a one-shot timer.
- Source 9 is the supervisor external interrupt, which chains to all other
device interrupts.
- interrupt-controller : Identifies the node as an interrupt controller
Furthermore, this interrupt-controller MUST be embedded inside the cpu
@ -38,7 +46,7 @@ An example device tree entry for a HLIC is show below.
...
cpu1-intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc", "sifive,fu540-c000-cpu-intc";
compatible = "sifive,fu540-c000-cpu-intc", "riscv,cpu-intc";
interrupt-controller;
};
};

View file

@ -7,6 +7,7 @@ Required properties:
Examples with soctypes are:
- "renesas,r8a7743-wdt" (RZ/G1M)
- "renesas,r8a7745-wdt" (RZ/G1E)
- "renesas,r8a774a1-wdt" (RZ/G2M)
- "renesas,r8a7790-wdt" (R-Car H2)
- "renesas,r8a7791-wdt" (R-Car M2-W)
- "renesas,r8a7792-wdt" (R-Car V2H)
@ -21,8 +22,8 @@ Required properties:
- "renesas,r7s72100-wdt" (RZ/A1)
The generic compatible string must be:
- "renesas,rza-wdt" for RZ/A
- "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G
- "renesas,rcar-gen3-wdt" for R-Car Gen3
- "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G1
- "renesas,rcar-gen3-wdt" for R-Car Gen3 and RZ/G2
- reg : Should contain WDT registers location and length
- clocks : the clock feeding the watchdog timer.

View file

@ -180,10 +180,10 @@ by a chip select decoder.
{
struct nand_chip *this = mtd_to_nand(mtd);
switch(cmd){
case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break;
case NAND_CTL_CLRCLE: this->IO_ADDR_W &= ~CLE_ADRR_BIT; break;
case NAND_CTL_SETALE: this->IO_ADDR_W |= ALE_ADRR_BIT; break;
case NAND_CTL_CLRALE: this->IO_ADDR_W &= ~ALE_ADRR_BIT; break;
case NAND_CTL_SETCLE: this->legacy.IO_ADDR_W |= CLE_ADRR_BIT; break;
case NAND_CTL_CLRCLE: this->legacy.IO_ADDR_W &= ~CLE_ADRR_BIT; break;
case NAND_CTL_SETALE: this->legacy.IO_ADDR_W |= ALE_ADRR_BIT; break;
case NAND_CTL_CLRALE: this->legacy.IO_ADDR_W &= ~ALE_ADRR_BIT; break;
}
}
@ -197,7 +197,7 @@ to read back the state of the pin. The function has no arguments and
should return 0, if the device is busy (R/B pin is low) and 1, if the
device is ready (R/B pin is high). If the hardware interface does not
give access to the ready busy pin, then the function must not be defined
and the function pointer this->dev_ready is set to NULL.
and the function pointer this->legacy.dev_ready is set to NULL.
Init function
-------------
@ -235,18 +235,18 @@ necessary information about the device.
}
/* Set address of NAND IO lines */
this->IO_ADDR_R = baseaddr;
this->IO_ADDR_W = baseaddr;
this->legacy.IO_ADDR_R = baseaddr;
this->legacy.IO_ADDR_W = baseaddr;
/* Reference hardware control function */
this->hwcontrol = board_hwcontrol;
/* Set command delay time, see datasheet for correct value */
this->chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
this->legacy.chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
/* Assign the device ready function, if available */
this->dev_ready = board_dev_ready;
this->legacy.dev_ready = board_dev_ready;
this->eccmode = NAND_ECC_SOFT;
/* Scan to find existence of the device */
if (nand_scan (board_mtd, 1)) {
if (nand_scan (this, 1)) {
err = -ENXIO;
goto out_ior;
}
@ -277,7 +277,7 @@ unregisters the partitions in the MTD layer.
static void __exit board_cleanup (void)
{
/* Release resources, unregister device */
nand_release (board_mtd);
nand_release (mtd_to_nand(board_mtd));
/* unmap physical address */
iounmap(baseaddr);
@ -336,17 +336,17 @@ connected to an address decoder.
struct nand_chip *this = mtd_to_nand(mtd);
/* Deselect all chips */
this->IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK;
this->IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK;
this->legacy.IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK;
this->legacy.IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK;
switch (chip) {
case 0:
this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
break;
....
case n:
this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
break;
}
}

View file

@ -32,7 +32,7 @@ Supported chips:
Datasheet: Publicly available at the Texas Instruments website
http://www.ti.com/
Author: Lothar Felten <l-felten@ti.com>
Author: Lothar Felten <lothar.felten@gmail.com>
Description
-----------

View file

@ -50,10 +50,14 @@ bounce buffer. But you don't need to care about that detail, just use the
returned buffer. If NULL is returned, the threshold was not met or a bounce
buffer could not be allocated. Fall back to PIO in that case.
In any case, a buffer obtained from above needs to be released. It ensures data
is copied back to the message and a potentially used bounce buffer is freed::
In any case, a buffer obtained from above needs to be released. Another helper
function ensures a potentially used bounce buffer is freed::
i2c_release_dma_safe_msg_buf(msg, dma_buf);
i2c_put_dma_safe_msg_buf(dma_buf, msg, xferred);
The last argument 'xferred' controls if the buffer is synced back to the
message or not. No syncing is needed in cases setting up DMA had an error and
there was no data transferred.
The bounce buffer handling from the core is generic and simple. It will always
allocate a new bounce buffer. If you want a more sophisticated handling (e.g.

View file

@ -1,113 +0,0 @@
About this document
===================
Some notes about Marvell's NAND controller available in PXA and Armada 370/XP
SoC (aka NFCv1 and NFCv2), with an emphasis on the latter.
NFCv2 controller background
===========================
The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
chunked transfers.
For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
we'll have this layout in the pages:
------------------------------------------------------------------------------
| 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
------------------------------------------------------------------------------
The driver reads the data and spare portions independently and builds an internal
buffer with this layout (in the 4 KiB page case):
------------------------------------------
| 4096B data | 64B spare |
------------------------------------------
Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
OOB, one per chunk read.
-------------------------------------------------------------------
| 4096B data | 32B spare | 30B ECC | 32B spare | 30B ECC |
-------------------------------------------------------------------
So, in order to achieve reading (for instance), we issue several READ0 commands
(with some additional controller-specific magic) and read two chunks of 2080B
(2048 data + 32 spare) each.
The driver accommodates this data to expose the NAND core a contiguous buffer
(4096 data + spare) or (4096 + spare + ECC + spare + ECC).
ECC
===
The controller has built-in hardware ECC capabilities. In addition it is
configurable between two modes: 1) Hamming, 2) BCH.
Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
the controller is configured to transfer the data.
In the BCH mode the ECC code will be calculated for each transferred chunk
and expected to be located (when reading/programming) right after the spare
bytes as the figure above shows.
So, repeating the above scheme, a 2048B data chunk will be followed by 32B
spare, and then the ECC controller will read/write the ECC code (30B in
this case):
------------------------------------
| 2048B data | 32B spare | 30B ECC |
------------------------------------
If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
So in Hamming mode, a 2048B page will have a 24B ECC.
Despite all of the above, the controller requires the driver to only read or
write in multiples of 8-bytes, because the data buffer is 64-bits.
OOB
===
Because of the above scheme, and because the "spare" OOB is really located in
the middle of a page, spare OOB cannot be read or write independently of the
data area. In other words, in order to read the OOB (aka READOOB), the entire
page (aka READ0) has to be read.
In the same sense, in order to write to the spare OOB the driver has to write
an *entire* page.
Factory bad blocks handling
===========================
Given the ECC BCH requires to layout the device's pages in a split
data/OOB/data/OOB way, the controller has a view of the flash page that's
different from the specified (aka the manufacturer's) view. In other words,
Factory view:
-----------------------------------------------
| Data |x OOB |
-----------------------------------------------
Driver's view:
-----------------------------------------------
| Data | OOB | Data x | OOB |
-----------------------------------------------
It can be seen from the above, that the factory bad block marker must be
searched within the 'data' region, and not in the usual OOB region.
In addition, this means under regular usage the driver will write such
position (since it belongs to the data region) and every used block is
likely to be marked as bad.
For this reason, marking the block as bad in the OOB is explicitly
disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale
for this is that there's no point in marking a block as bad, because good
blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage.
Instead, the driver relies on the bad block table alone, and should only perform
the bad block scan on the very first time (when the device hasn't been used).

View file

@ -8255,9 +8255,9 @@ F: drivers/ata/pata_arasan_cf.c
LIBATA PATA DRIVERS
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
M: Jens Axboe <kernel.dk>
M: Jens Axboe <axboe@kernel.dk>
L: linux-ide@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
S: Maintained
F: drivers/ata/pata_*.c
F: drivers/ata/ata_generic.c
@ -8275,7 +8275,7 @@ LIBATA SATA AHCI PLATFORM devices support
M: Hans de Goede <hdegoede@redhat.com>
M: Jens Axboe <axboe@kernel.dk>
L: linux-ide@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
S: Maintained
F: drivers/ata/ahci_platform.c
F: drivers/ata/libahci_platform.c
@ -8291,7 +8291,7 @@ F: drivers/ata/sata_promise.*
LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
M: Jens Axboe <axboe@kernel.dk>
L: linux-ide@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
S: Maintained
F: drivers/ata/
F: include/linux/ata.h

View file

@ -2,7 +2,7 @@
VERSION = 4
PATCHLEVEL = 19
SUBLEVEL = 0
EXTRAVERSION = -rc1
EXTRAVERSION = -rc2
NAME = Merciless Moray
# *DOCUMENTATION*
@ -807,6 +807,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
# disable stringop warnings in gcc 8+
KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
# disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)

0
arch/arm/boot/dts/am335x-osd3358-sm-red.dts Executable file → Normal file
View file

View file

@ -469,6 +469,7 @@
ti,hwmods = "rtc";
clocks = <&clk_32768_ck>;
clock-names = "int-clk";
system-power-controller;
status = "disabled";
};

View file

@ -13,6 +13,43 @@
reg = <0x40000000 0x08000000>;
};
reg_vddio_sd0: regulator-vddio-sd0 {
compatible = "regulator-fixed";
regulator-name = "vddio-sd0";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 29 0>;
};
reg_lcd_3v3: regulator-lcd-3v3 {
compatible = "regulator-fixed";
regulator-name = "lcd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 18 0>;
enable-active-high;
};
reg_lcd_5v: regulator-lcd-5v {
compatible = "regulator-fixed";
regulator-name = "lcd-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
panel {
compatible = "sii,43wvf1g";
backlight = <&backlight_display>;
dvdd-supply = <&reg_lcd_3v3>;
avdd-supply = <&reg_lcd_5v>;
port {
panel_in: endpoint {
remote-endpoint = <&display_out>;
};
};
};
apb@80000000 {
apbh@80000000 {
gpmi-nand@8000c000 {
@ -52,31 +89,11 @@
lcdif@80030000 {
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a>;
lcd-supply = <&reg_lcd_3v3>;
display = <&display0>;
status = "okay";
display0: display0 {
bits-per-pixel = <32>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9200000>;
hactive = <480>;
vactive = <272>;
hback-porch = <15>;
hfront-porch = <8>;
vback-porch = <12>;
vfront-porch = <4>;
hsync-len = <1>;
vsync-len = <1>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
port {
display_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};
@ -118,32 +135,7 @@
};
};
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
reg_vddio_sd0: regulator@0 {
compatible = "regulator-fixed";
reg = <0>;
regulator-name = "vddio-sd0";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 29 0>;
};
reg_lcd_3v3: regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
regulator-name = "lcd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 18 0>;
enable-active-high;
};
};
backlight {
backlight_display: backlight {
compatible = "pwm-backlight";
pwms = <&pwm 2 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;

View file

@ -13,6 +13,87 @@
reg = <0x40000000 0x08000000>;
};
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "3P3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
reg_vddio_sd0: regulator-vddio-sd0 {
compatible = "regulator-fixed";
regulator-name = "vddio-sd0";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio3 28 0>;
};
reg_fec_3v3: regulator-fec-3v3 {
compatible = "regulator-fixed";
regulator-name = "fec-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio2 15 0>;
};
reg_usb0_vbus: regulator-usb0-vbus {
compatible = "regulator-fixed";
regulator-name = "usb0_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio3 9 0>;
enable-active-high;
};
reg_usb1_vbus: regulator-usb1-vbus {
compatible = "regulator-fixed";
regulator-name = "usb1_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio3 8 0>;
enable-active-high;
};
reg_lcd_3v3: regulator-lcd-3v3 {
compatible = "regulator-fixed";
regulator-name = "lcd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio3 30 0>;
enable-active-high;
};
reg_can_3v3: regulator-can-3v3 {
compatible = "regulator-fixed";
regulator-name = "can-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio2 13 0>;
enable-active-high;
};
reg_lcd_5v: regulator-lcd-5v {
compatible = "regulator-fixed";
regulator-name = "lcd-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
panel {
compatible = "sii,43wvf1g";
backlight = <&backlight_display>;
dvdd-supply = <&reg_lcd_3v3>;
avdd-supply = <&reg_lcd_5v>;
port {
panel_in: endpoint {
remote-endpoint = <&display_out>;
};
};
};
apb@80000000 {
apbh@80000000 {
gpmi-nand@8000c000 {
@ -116,31 +197,11 @@
pinctrl-names = "default";
pinctrl-0 = <&lcdif_24bit_pins_a
&lcdif_pins_evk>;
lcd-supply = <&reg_lcd_3v3>;
display = <&display0>;
status = "okay";
display0: display0 {
bits-per-pixel = <32>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <33500000>;
hactive = <800>;
vactive = <480>;
hback-porch = <89>;
hfront-porch = <164>;
vback-porch = <23>;
vfront-porch = <10>;
hsync-len = <10>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
port {
display_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};
@ -269,80 +330,6 @@
};
};
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
reg_3p3v: regulator@0 {
compatible = "regulator-fixed";
reg = <0>;
regulator-name = "3P3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
reg_vddio_sd0: regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
regulator-name = "vddio-sd0";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio3 28 0>;
};
reg_fec_3v3: regulator@2 {
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "fec-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio2 15 0>;
};
reg_usb0_vbus: regulator@3 {
compatible = "regulator-fixed";
reg = <3>;
regulator-name = "usb0_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio3 9 0>;
enable-active-high;
};
reg_usb1_vbus: regulator@4 {
compatible = "regulator-fixed";
reg = <4>;
regulator-name = "usb1_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio3 8 0>;
enable-active-high;
};
reg_lcd_3v3: regulator@5 {
compatible = "regulator-fixed";
reg = <5>;
regulator-name = "lcd-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio3 30 0>;
enable-active-high;
};
reg_can_3v3: regulator@6 {
compatible = "regulator-fixed";
reg = <6>;
regulator-name = "can-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio2 13 0>;
enable-active-high;
};
};
sound {
compatible = "fsl,imx28-evk-sgtl5000",
"fsl,mxs-audio-sgtl5000";
@ -363,7 +350,7 @@
};
};
backlight {
backlight_display: backlight {
compatible = "pwm-backlight";
pwms = <&pwm 2 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;

View file

@ -126,10 +126,14 @@
interrupt-names = "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
/*
* Reference manual lists pci irqs incorrectly
* Real hardware ordering is same as imx6: D+MSI, C, B, A
*/
interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
<&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
<&clks IMX7D_PCIE_PHY_ROOT_CLK>;

View file

@ -354,7 +354,7 @@
&mmc2 {
vmmc-supply = <&vsdio>;
bus-width = <8>;
non-removable;
ti,non-removable;
};
&mmc3 {
@ -621,15 +621,6 @@
OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1) /* abe_mcbsp3_fsx */
>;
};
};
&omap4_pmx_wkup {
usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
/* gpio_wk0 */
pinctrl-single,pins = <
OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
>;
};
vibrator_direction_pin: pinmux_vibrator_direction_pin {
pinctrl-single,pins = <
@ -644,6 +635,15 @@
};
};
&omap4_pmx_wkup {
usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
/* gpio_wk0 */
pinctrl-single,pins = <
OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
>;
};
};
/*
* As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
* uart1 wakeirq.

View file

@ -257,6 +257,7 @@ CONFIG_IMX_IPUV3_CORE=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_LVDS=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
CONFIG_DRM_DW_HDMI_CEC=y
CONFIG_DRM_IMX=y

View file

@ -95,6 +95,7 @@ CONFIG_MFD_MXS_LRADC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
CONFIG_DRM_MXSFB=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y

View file

@ -5,19 +5,19 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_VERSATILE=y
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
CONFIG_CMA=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="root=1f03 mem=32M"
CONFIG_FPE_NWFPE=y
CONFIG_VFP=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_CMA=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@ -59,6 +59,7 @@ CONFIG_GPIO_PL061=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_ARM_VERSATILE=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_DUMB_VGA_DAC=y
CONFIG_DRM_PL111=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
@ -89,9 +90,10 @@ CONFIG_NFSD=y
CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_ISO8859_1=m
CONFIG_FONTS=y
CONFIG_FONT_ACORN_8x8=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
CONFIG_FONTS=y
CONFIG_FONT_ACORN_8x8=y

View file

@ -23,8 +23,7 @@
#include <linux/i2c.h>
#include <linux/fb.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/platnand.h>
#include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h>
@ -43,12 +42,11 @@
#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
#define NAND_CTRL_ADDR(chip) (chip->IO_ADDR_W + 0x40)
#define NAND_CTRL_ADDR(chip) (chip->legacy.IO_ADDR_W + 0x40)
static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static void snappercl15_nand_cmd_ctrl(struct nand_chip *chip, int cmd,
unsigned int ctrl)
{
struct nand_chip *chip = mtd_to_nand(mtd);
static u16 nand_state = SNAPPERCL15_NAND_WPN;
u16 set;
@ -70,13 +68,12 @@ static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
}
if (cmd != NAND_CMD_NONE)
__raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
__raw_writew((cmd & 0xff) | nand_state,
chip->legacy.IO_ADDR_W);
}
static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
static int snappercl15_nand_dev_ready(struct nand_chip *chip)
{
struct nand_chip *chip = mtd_to_nand(mtd);
return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
}

View file

@ -16,8 +16,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/spi/mmc_spi.h>
@ -76,13 +75,11 @@ static void __init ts72xx_map_io(void)
#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
static void ts72xx_nand_hwcontrol(struct nand_chip *chip,
int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd_to_nand(mtd);
if (ctrl & NAND_CTRL_CHANGE) {
void __iomem *addr = chip->IO_ADDR_R;
void __iomem *addr = chip->legacy.IO_ADDR_R;
unsigned char bits;
addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
@ -96,13 +93,12 @@ static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
}
if (cmd != NAND_CMD_NONE)
__raw_writeb(cmd, chip->IO_ADDR_W);
__raw_writeb(cmd, chip->legacy.IO_ADDR_W);
}
static int ts72xx_nand_device_ready(struct mtd_info *mtd)
static int ts72xx_nand_device_ready(struct nand_chip *chip)
{
struct nand_chip *chip = mtd_to_nand(mtd);
void __iomem *addr = chip->IO_ADDR_R;
void __iomem *addr = chip->legacy.IO_ADDR_R;
addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);

View file

@ -18,7 +18,7 @@
#include <linux/memory.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/platnand.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
@ -129,30 +129,29 @@ static void qong_init_nor_mtd(void)
/*
* Hardware specific access to control-lines
*/
static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
static void qong_nand_cmd_ctrl(struct nand_chip *nand_chip, int cmd,
unsigned int ctrl)
{
struct nand_chip *nand_chip = mtd_to_nand(mtd);
if (cmd == NAND_CMD_NONE)
return;
if (ctrl & NAND_CLE)
writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
writeb(cmd, nand_chip->legacy.IO_ADDR_W + (1 << 24));
else
writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
writeb(cmd, nand_chip->legacy.IO_ADDR_W + (1 << 23));
}
/*
* Read the Device Ready pin.
*/
static int qong_nand_device_ready(struct mtd_info *mtd)
static int qong_nand_device_ready(struct nand_chip *chip)
{
return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
}
static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
static void qong_nand_select_chip(struct nand_chip *chip, int cs)
{
if (chip >= 0)
if (cs >= 0)
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
else
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);

View file

@ -20,6 +20,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <asm/types.h>
@ -75,9 +76,8 @@ static struct mtd_partition ixdp425_partitions[] = {
};
static void
ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
ixdp425_flash_nand_cmd_ctrl(struct nand_chip *this, int cmd, unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
int offset = (int)nand_get_controller_data(this);
if (ctrl & NAND_CTRL_CHANGE) {
@ -93,7 +93,7 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
}
if (cmd != NAND_CMD_NONE)
writeb(cmd, this->IO_ADDR_W + offset);
writeb(cmd, this->legacy.IO_ADDR_W + offset);
}
static struct platform_nand_data ixdp425_flash_nand_data = {

View file

@ -16,8 +16,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/smc91x.h>
@ -186,7 +185,7 @@ static struct platform_device nor_device = {
#define FSAMPLE_NAND_RB_GPIO_PIN 62
static int nand_dev_ready(struct mtd_info *mtd)
static int nand_dev_ready(struct nand_chip *chip)
{
return gpio_get_value(FSAMPLE_NAND_RB_GPIO_PIN);
}

View file

@ -24,8 +24,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/mfd/tps65010.h>
@ -182,7 +181,7 @@ static struct mtd_partition h2_nand_partitions[] = {
#define H2_NAND_RB_GPIO_PIN 62
static int h2_nand_dev_ready(struct mtd_info *mtd)
static int h2_nand_dev_ready(struct nand_chip *chip)
{
return gpio_get_value(H2_NAND_RB_GPIO_PIN);
}

View file

@ -23,7 +23,7 @@
#include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
@ -185,7 +185,7 @@ static struct mtd_partition nand_partitions[] = {
#define H3_NAND_RB_GPIO_PIN 10
static int nand_dev_ready(struct mtd_info *mtd)
static int nand_dev_ready(struct nand_chip *chip)
{
return gpio_get_value(H3_NAND_RB_GPIO_PIN);
}

View file

@ -20,9 +20,8 @@
#include "common.h"
void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
void omap1_nand_cmd_ctl(struct nand_chip *this, int cmd, unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
unsigned long mask;
if (cmd == NAND_CMD_NONE)
@ -32,6 +31,6 @@ void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
if (ctrl & NAND_ALE)
mask |= 0x04;
writeb(cmd, this->IO_ADDR_W + mask);
writeb(cmd, this->legacy.IO_ADDR_W + mask);
}

View file

@ -16,8 +16,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/smc91x.h>
@ -144,7 +143,7 @@ static struct platform_device nor_device = {
#define P2_NAND_RB_GPIO_PIN 62
static int nand_dev_ready(struct mtd_info *mtd)
static int nand_dev_ready(struct nand_chip *chip)
{
return gpio_get_value(P2_NAND_RB_GPIO_PIN);
}

View file

@ -26,7 +26,6 @@
#ifndef __ARCH_ARM_MACH_OMAP1_COMMON_H
#define __ARCH_ARM_MACH_OMAP1_COMMON_H
#include <linux/mtd/mtd.h>
#include <linux/platform_data/i2c-omap.h>
#include <linux/reboot.h>
@ -82,7 +81,8 @@ void omap1_restart(enum reboot_mode, const char *);
extern void __init omap_check_revision(void);
extern void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
struct nand_chip;
extern void omap1_nand_cmd_ctl(struct nand_chip *this, int cmd,
unsigned int ctrl);
extern void omap1_timer_init(void);

View file

@ -2160,6 +2160,37 @@ static int of_dev_hwmod_lookup(struct device_node *np,
return -ENODEV;
}
/**
* omap_hwmod_fix_mpu_rt_idx - fix up mpu_rt_idx register offsets
*
* @oh: struct omap_hwmod *
* @np: struct device_node *
*
* Fix up module register offsets for modules with mpu_rt_idx.
* Only needed for cpsw with interconnect target module defined
* in device tree while still using legacy hwmod platform data
* for rev, sysc and syss registers.
*
* Can be removed when all cpsw hwmod platform data has been
* dropped.
*/
static void omap_hwmod_fix_mpu_rt_idx(struct omap_hwmod *oh,
struct device_node *np,
struct resource *res)
{
struct device_node *child = NULL;
int error;
child = of_get_next_child(np, child);
if (!child)
return;
error = of_address_to_resource(child, oh->mpu_rt_idx, res);
if (error)
pr_err("%s: error mapping mpu_rt_idx: %i\n",
__func__, error);
}
/**
* omap_hwmod_parse_module_range - map module IO range from device tree
* @oh: struct omap_hwmod *
@ -2220,7 +2251,13 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
size = be32_to_cpup(ranges);
pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n",
oh->name, np->name, base, size);
oh ? oh->name : "", np->name, base, size);
if (oh && oh->mpu_rt_idx) {
omap_hwmod_fix_mpu_rt_idx(oh, np, res);
return 0;
}
res->start = base;
res->end = base + size - 1;

View file

@ -16,8 +16,7 @@
#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/timeriomem-rng.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -131,11 +130,9 @@ static void ts78xx_ts_rtc_unload(void)
* NAND_CLE: bit 1 -> bit 1
* NAND_ALE: bit 2 -> bit 0
*/
static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
static void ts78xx_ts_nand_cmd_ctrl(struct nand_chip *this, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
if (ctrl & NAND_CTRL_CHANGE) {
unsigned char bits;
@ -147,19 +144,18 @@ static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
}
if (cmd != NAND_CMD_NONE)
writeb(cmd, this->IO_ADDR_W);
writeb(cmd, this->legacy.IO_ADDR_W);
}
static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
static int ts78xx_ts_nand_dev_ready(struct nand_chip *chip)
{
return readb(TS_NAND_CTRL) & 0x20;
}
static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
const uint8_t *buf, int len)
static void ts78xx_ts_nand_write_buf(struct nand_chip *chip,
const uint8_t *buf, int len)
{
struct nand_chip *chip = mtd_to_nand(mtd);
void __iomem *io_base = chip->IO_ADDR_W;
void __iomem *io_base = chip->legacy.IO_ADDR_W;
unsigned long off = ((unsigned long)buf & 3);
int sz;
@ -182,11 +178,10 @@ static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
writesb(io_base, buf, len);
}
static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd,
uint8_t *buf, int len)
static void ts78xx_ts_nand_read_buf(struct nand_chip *chip,
uint8_t *buf, int len)
{
struct nand_chip *chip = mtd_to_nand(mtd);
void __iomem *io_base = chip->IO_ADDR_R;
void __iomem *io_base = chip->legacy.IO_ADDR_R;
unsigned long off = ((unsigned long)buf & 3);
int sz;

View file

@ -25,11 +25,10 @@
#include <linux/ioport.h>
#include <linux/ucb1400.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/types.h>
#include <linux/platform_data/pcf857x.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/physmap.h>
#include <linux/regulator/max1586.h>
@ -571,9 +570,9 @@ static inline void balloon3_i2c_init(void) {}
* NAND
******************************************************************************/
#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
static void balloon3_nand_cmd_ctl(struct nand_chip *this, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
if (ctrl & NAND_CTRL_CHANGE) {
@ -597,10 +596,10 @@ static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ct
}
if (cmd != NAND_CMD_NONE)
writeb(cmd, this->IO_ADDR_W);
writeb(cmd, this->legacy.IO_ADDR_W);
}
static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
static void balloon3_nand_select_chip(struct nand_chip *this, int chip)
{
if (chip < 0 || chip > 3)
return;
@ -616,7 +615,7 @@ static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
BALLOON3_NAND_CONTROL_REG);
}
static int balloon3_nand_dev_ready(struct mtd_info *mtd)
static int balloon3_nand_dev_ready(struct nand_chip *this)
{
return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB;
}

View file

@ -15,8 +15,7 @@
#include <linux/dm9000.h>
#include <linux/platform_data/rtc-v3020.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
@ -285,11 +284,10 @@ static void nand_cs_off(void)
}
/* hardware specific access to control-lines */
static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
static void em_x270_nand_cmd_ctl(struct nand_chip *this, int dat,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
unsigned long nandaddr = (unsigned long)this->legacy.IO_ADDR_W;
dsb();
@ -309,15 +307,15 @@ static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
}
dsb();
this->IO_ADDR_W = (void __iomem *)nandaddr;
this->legacy.IO_ADDR_W = (void __iomem *)nandaddr;
if (dat != NAND_CMD_NONE)
writel(dat, this->IO_ADDR_W);
writel(dat, this->legacy.IO_ADDR_W);
dsb();
}
/* read device ready pin */
static int em_x270_nand_device_ready(struct mtd_info *mtd)
static int em_x270_nand_device_ready(struct nand_chip *this)
{
dsb();

View file

@ -403,36 +403,6 @@ static void __init palmtreo_leds_init(void)
platform_device_register(&palmtreo_leds);
}
/******************************************************************************
* diskonchip docg4 flash
******************************************************************************/
#if defined(CONFIG_MACH_TREO680)
/* REVISIT: does the centro have this device also? */
#if IS_ENABLED(CONFIG_MTD_NAND_DOCG4)
static struct resource docg4_resources[] = {
{
.start = 0x00000000,
.end = 0x00001FFF,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device treo680_docg4_flash = {
.name = "docg4",
.id = -1,
.resource = docg4_resources,
.num_resources = ARRAY_SIZE(docg4_resources),
};
static void __init treo680_docg4_flash_init(void)
{
platform_device_register(&treo680_docg4_flash);
}
#else
static inline void treo680_docg4_flash_init(void) {}
#endif
#endif
/******************************************************************************
* Machine init
******************************************************************************/
@ -517,7 +487,6 @@ static void __init treo680_init(void)
treo680_gpio_init();
palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY,
GPIO_NR_TREO680_SD_POWER, 0);
treo680_docg4_flash_init();
}
#endif

View file

@ -28,8 +28,7 @@
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
@ -247,11 +246,10 @@ static inline void palmtx_keys_init(void) {}
******************************************************************************/
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
static void palmtx_nand_cmd_ctl(struct nand_chip *this, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
char __iomem *nandaddr = this->IO_ADDR_W;
char __iomem *nandaddr = this->legacy.IO_ADDR_W;
if (cmd == NAND_CMD_NONE)
return;

View file

@ -763,7 +763,6 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
config HOLES_IN_ZONE
def_bool y
depends on NUMA
source kernel/Kconfig.hz

View file

@ -38,6 +38,7 @@ CONFIG_ARCH_BCM_IPROC=y
CONFIG_ARCH_BERLIN=y
CONFIG_ARCH_BRCMSTB=y
CONFIG_ARCH_EXYNOS=y
CONFIG_ARCH_K3=y
CONFIG_ARCH_LAYERSCAPE=y
CONFIG_ARCH_LG1K=y
CONFIG_ARCH_HISI=y
@ -605,6 +606,8 @@ CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
CONFIG_ARCH_TEGRA_186_SOC=y
CONFIG_ARCH_TEGRA_194_SOC=y
CONFIG_ARCH_K3_AM6_SOC=y
CONFIG_SOC_TI=y
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_EXTCON_USBC_CROS_EC=y

View file

@ -417,7 +417,7 @@ static int gcm_encrypt(struct aead_request *req)
__aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
put_unaligned_be32(2, iv + GCM_IV_SIZE);
while (walk.nbytes >= AES_BLOCK_SIZE) {
while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
int blocks = walk.nbytes / AES_BLOCK_SIZE;
u8 *dst = walk.dst.virt.addr;
u8 *src = walk.src.virt.addr;
@ -437,11 +437,18 @@ static int gcm_encrypt(struct aead_request *req)
NULL);
err = skcipher_walk_done(&walk,
walk.nbytes % AES_BLOCK_SIZE);
walk.nbytes % (2 * AES_BLOCK_SIZE));
}
if (walk.nbytes)
if (walk.nbytes) {
__aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv,
nrounds);
if (walk.nbytes > AES_BLOCK_SIZE) {
crypto_inc(iv, AES_BLOCK_SIZE);
__aes_arm64_encrypt(ctx->aes_key.key_enc,
ks + AES_BLOCK_SIZE, iv,
nrounds);
}
}
}
/* handle the tail */
@ -545,7 +552,7 @@ static int gcm_decrypt(struct aead_request *req)
__aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
put_unaligned_be32(2, iv + GCM_IV_SIZE);
while (walk.nbytes >= AES_BLOCK_SIZE) {
while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
int blocks = walk.nbytes / AES_BLOCK_SIZE;
u8 *dst = walk.dst.virt.addr;
u8 *src = walk.src.virt.addr;
@ -564,11 +571,21 @@ static int gcm_decrypt(struct aead_request *req)
} while (--blocks > 0);
err = skcipher_walk_done(&walk,
walk.nbytes % AES_BLOCK_SIZE);
walk.nbytes % (2 * AES_BLOCK_SIZE));
}
if (walk.nbytes)
if (walk.nbytes) {
if (walk.nbytes > AES_BLOCK_SIZE) {
u8 *iv2 = iv + AES_BLOCK_SIZE;
memcpy(iv2, iv, AES_BLOCK_SIZE);
crypto_inc(iv2, AES_BLOCK_SIZE);
__aes_arm64_encrypt(ctx->aes_key.key_enc, iv2,
iv2, nrounds);
}
__aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv,
nrounds);
}
}
/* handle the tail */

View file

@ -69,5 +69,5 @@ static void __exit sm4_ce_mod_fini(void)
crypto_unregister_alg(&sm4_ce_alg);
}
module_cpu_feature_match(SM3, sm4_ce_mod_init);
module_cpu_feature_match(SM4, sm4_ce_mod_init);
module_exit(sm4_ce_mod_fini);

View file

@ -98,11 +98,10 @@ static time64_t pmu_read_time(void)
if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
return 0;
while (!req.complete)
pmu_poll();
pmu_wait_complete(&req);
time = (u32)((req.reply[1] << 24) | (req.reply[2] << 16) |
(req.reply[3] << 8) | req.reply[4]);
time = (u32)((req.reply[0] << 24) | (req.reply[1] << 16) |
(req.reply[2] << 8) | req.reply[3]);
return time - RTC_OFFSET;
}
@ -116,8 +115,7 @@ static void pmu_write_time(time64_t time)
(data >> 24) & 0xFF, (data >> 16) & 0xFF,
(data >> 8) & 0xFF, data & 0xFF) < 0)
return;
while (!req.complete)
pmu_poll();
pmu_wait_complete(&req);
}
static __u8 pmu_read_pram(int offset)

View file

@ -29,8 +29,7 @@
#include <linux/leds.h>
#include <linux/mmc/host.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/spi/spi.h>
@ -197,11 +196,10 @@ static struct i2c_board_info db1200_i2c_devs[] __initdata = {
/**********************************************************************/
static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static void au1200_nand_cmd_ctrl(struct nand_chip *this, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W;
ioaddr &= 0xffffff00;
@ -213,14 +211,14 @@ static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
/* assume we want to r/w real data by default */
ioaddr += MEM_STNAND_DATA;
}
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr;
if (cmd != NAND_CMD_NONE) {
__raw_writeb(cmd, this->IO_ADDR_W);
__raw_writeb(cmd, this->legacy.IO_ADDR_W);
wmb();
}
}
static int au1200_nand_device_ready(struct mtd_info *mtd)
static int au1200_nand_device_ready(struct nand_chip *this)
{
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
}

View file

@ -19,8 +19,7 @@
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/wm97xx.h>
@ -149,11 +148,10 @@ static void __init db1300_gpio_config(void)
/**********************************************************************/
static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static void au1300_nand_cmd_ctrl(struct nand_chip *this, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W;
ioaddr &= 0xffffff00;
@ -165,14 +163,14 @@ static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
/* assume we want to r/w real data by default */
ioaddr += MEM_STNAND_DATA;
}
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr;
if (cmd != NAND_CMD_NONE) {
__raw_writeb(cmd, this->IO_ADDR_W);
__raw_writeb(cmd, this->legacy.IO_ADDR_W);
wmb();
}
}
static int au1300_nand_device_ready(struct mtd_info *mtd)
static int au1300_nand_device_ready(struct nand_chip *this)
{
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
}

View file

@ -13,8 +13,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
@ -126,11 +125,10 @@ static struct i2c_board_info db1550_i2c_devs[] __initdata = {
/**********************************************************************/
static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
static void au1550_nand_cmd_ctrl(struct nand_chip *this, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W;
ioaddr &= 0xffffff00;
@ -142,14 +140,14 @@ static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
/* assume we want to r/w real data by default */
ioaddr += MEM_STNAND_DATA;
}
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr;
if (cmd != NAND_CMD_NONE) {
__raw_writeb(cmd, this->IO_ADDR_W);
__raw_writeb(cmd, this->legacy.IO_ADDR_W);
wmb();
}
}
static int au1550_nand_device_ready(struct mtd_info *mtd)
static int au1550_nand_device_ready(struct nand_chip *this)
{
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
}

View file

@ -19,8 +19,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlr/iomap.h>
@ -92,8 +91,8 @@ struct xlr_nand_flash_priv {
static struct xlr_nand_flash_priv nand_priv;
static void xlr_nand_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
static void xlr_nand_ctrl(struct nand_chip *chip, int cmd,
unsigned int ctrl)
{
if (ctrl & NAND_CLE)
nlm_write_reg(nand_priv.flash_mmio,

View file

@ -30,8 +30,7 @@
#include <linux/resource.h>
#include <linux/serial.h>
#include <linux/serial_pnx8xxx.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/platnand.h>
#include <irq.h>
#include <irq-mapping.h>
@ -178,10 +177,9 @@ static struct platform_device pnx833x_sata_device = {
};
static void
pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
pnx833x_flash_nand_cmd_ctrl(struct nand_chip *this, int cmd, unsigned int ctrl)
{
struct nand_chip *this = mtd_to_nand(mtd);
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
unsigned long nandaddr = (unsigned long)this->legacy.IO_ADDR_W;
if (cmd == NAND_CMD_NONE)
return;

View file

@ -20,9 +20,8 @@
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
@ -141,14 +140,13 @@ static struct platform_device cf_slot0 = {
};
/* Resources and device for NAND */
static int rb532_dev_ready(struct mtd_info *mtd)
static int rb532_dev_ready(struct nand_chip *chip)
{
return gpio_get_value(GPIO_RDY);
}
static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
static void rb532_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd_to_nand(mtd);
unsigned char orbits, nandbits;
if (ctrl & NAND_CTRL_CHANGE) {
@ -161,7 +159,7 @@ static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
set_latch_u5(orbits, nandbits);
}
if (cmd != NAND_CMD_NONE)
writeb(cmd, chip->IO_ADDR_W);
writeb(cmd, chip->legacy.IO_ADDR_W);
}
static struct resource nand_slot0_res[] = {

View file

@ -3,15 +3,6 @@
config TRACE_IRQFLAGS_SUPPORT
def_bool y
config DEBUG_STACK_USAGE
bool "Enable stack utilization instrumentation"
depends on DEBUG_KERNEL
help
Enables the display of the minimum amount of free stack which each
task has ever had available in the sysrq-T and sysrq-P debug output.
This option will slow down process creation somewhat.
config EARLY_PRINTK
bool "Activate early kernel debugging"
default y

View file

@ -177,7 +177,6 @@ config PPC
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_PREL32_RELOCATIONS
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_CBPF_JIT if !PPC64

View file

@ -14,6 +14,10 @@
#ifndef _ASM_RISCV_TLB_H
#define _ASM_RISCV_TLB_H
struct mmu_gather;
static void tlb_flush(struct mmu_gather *tlb);
#include <asm-generic/tlb.h>
static inline void tlb_flush(struct mmu_gather *tlb)

View file

@ -65,24 +65,11 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,
uintptr_t, flags)
{
#ifdef CONFIG_SMP
struct mm_struct *mm = current->mm;
bool local = (flags & SYS_RISCV_FLUSH_ICACHE_LOCAL) != 0;
#endif
/* Check the reserved flags. */
if (unlikely(flags & ~SYS_RISCV_FLUSH_ICACHE_ALL))
return -EINVAL;
/*
* Without CONFIG_SMP flush_icache_mm is a just a flush_icache_all(),
* which generates unused variable warnings all over this function.
*/
#ifdef CONFIG_SMP
flush_icache_mm(mm, local);
#else
flush_icache_all();
#endif
flush_icache_mm(current->mm, flags & SYS_RISCV_FLUSH_ICACHE_LOCAL);
return 0;
}

View file

@ -14,7 +14,7 @@
#include <linux/mmc/host.h>
#include <linux/mtd/physmap.h>
#include <linux/mfd/tmio.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/platnand.h>
#include <linux/i2c.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
@ -165,23 +165,21 @@ static struct mtd_partition migor_nand_flash_partitions[] = {
},
};
static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd,
static void migor_nand_flash_cmd_ctl(struct nand_chip *chip, int cmd,
unsigned int ctrl)
{
struct nand_chip *chip = mtd_to_nand(mtd);
if (cmd == NAND_CMD_NONE)
return;
if (ctrl & NAND_CLE)
writeb(cmd, chip->IO_ADDR_W + 0x00400000);
writeb(cmd, chip->legacy.IO_ADDR_W + 0x00400000);
else if (ctrl & NAND_ALE)
writeb(cmd, chip->IO_ADDR_W + 0x00800000);
writeb(cmd, chip->legacy.IO_ADDR_W + 0x00800000);
else
writeb(cmd, chip->IO_ADDR_W);
writeb(cmd, chip->legacy.IO_ADDR_W);
}
static int migor_nand_flash_ready(struct mtd_info *mtd)
static int migor_nand_flash_ready(struct nand_chip *chip)
{
return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
}

View file

@ -2843,7 +2843,7 @@ config X86_SYSFB
This option, if enabled, marks VGA/VBE/EFI framebuffers as generic
framebuffers so the new generic system-framebuffer drivers can be
used on x86. If the framebuffer is not compatible with the generic
modes, it is adverticed as fallback platform framebuffer so legacy
modes, it is advertised as fallback platform framebuffer so legacy
drivers like efifb, vesafb and uvesafb can pick it up.
If this option is not selected, all system framebuffers are always
marked as fallback platform framebuffers as usual.

View file

@ -175,22 +175,6 @@ ifdef CONFIG_FUNCTION_GRAPH_TRACER
endif
endif
ifndef CC_HAVE_ASM_GOTO
$(error Compiler lacks asm-goto support.)
endif
#
# Jump labels need '-maccumulate-outgoing-args' for gcc < 4.5.2 to prevent a
# GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46226). There's no way
# to test for this bug at compile-time because the test case needs to execute,
# which is a no-go for cross compilers. So check the GCC version instead.
#
ifdef CONFIG_JUMP_LABEL
ifneq ($(ACCUMULATE_OUTGOING_ARGS), 1)
ACCUMULATE_OUTGOING_ARGS = $(call cc-if-fullversion, -lt, 040502, 1)
endif
endif
ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
# This compiler flag is not supported by Clang:
KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
@ -312,6 +296,13 @@ PHONY += vdso_install
vdso_install:
$(Q)$(MAKE) $(build)=arch/x86/entry/vdso $@
archprepare: checkbin
checkbin:
ifndef CC_HAVE_ASM_GOTO
@echo Compiler lacks asm-goto support.
@exit 1
endif
archclean:
$(Q)rm -rf $(objtree)/arch/i386
$(Q)rm -rf $(objtree)/arch/x86_64

View file

@ -223,34 +223,34 @@ ALL_F: .octa 0xffffffffffffffffffffffffffffffff
pcmpeqd TWOONE(%rip), \TMP2
pand POLY(%rip), \TMP2
pxor \TMP2, \TMP3
movdqa \TMP3, HashKey(%arg2)
movdqu \TMP3, HashKey(%arg2)
movdqa \TMP3, \TMP5
pshufd $78, \TMP3, \TMP1
pxor \TMP3, \TMP1
movdqa \TMP1, HashKey_k(%arg2)
movdqu \TMP1, HashKey_k(%arg2)
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
# TMP5 = HashKey^2<<1 (mod poly)
movdqa \TMP5, HashKey_2(%arg2)
movdqu \TMP5, HashKey_2(%arg2)
# HashKey_2 = HashKey^2<<1 (mod poly)
pshufd $78, \TMP5, \TMP1
pxor \TMP5, \TMP1
movdqa \TMP1, HashKey_2_k(%arg2)
movdqu \TMP1, HashKey_2_k(%arg2)
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
# TMP5 = HashKey^3<<1 (mod poly)
movdqa \TMP5, HashKey_3(%arg2)
movdqu \TMP5, HashKey_3(%arg2)
pshufd $78, \TMP5, \TMP1
pxor \TMP5, \TMP1
movdqa \TMP1, HashKey_3_k(%arg2)
movdqu \TMP1, HashKey_3_k(%arg2)
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
# TMP5 = HashKey^3<<1 (mod poly)
movdqa \TMP5, HashKey_4(%arg2)
movdqu \TMP5, HashKey_4(%arg2)
pshufd $78, \TMP5, \TMP1
pxor \TMP5, \TMP1
movdqa \TMP1, HashKey_4_k(%arg2)
movdqu \TMP1, HashKey_4_k(%arg2)
.endm
# GCM_INIT initializes a gcm_context struct to prepare for encoding/decoding.
@ -271,7 +271,7 @@ ALL_F: .octa 0xffffffffffffffffffffffffffffffff
movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv
PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
movdqa HashKey(%arg2), %xmm13
movdqu HashKey(%arg2), %xmm13
CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \
%xmm4, %xmm5, %xmm6
@ -997,7 +997,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
pshufd $78, \XMM5, \TMP6
pxor \XMM5, \TMP6
paddd ONE(%rip), \XMM0 # INCR CNT
movdqa HashKey_4(%arg2), \TMP5
movdqu HashKey_4(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
movdqa \XMM0, \XMM1
paddd ONE(%rip), \XMM0 # INCR CNT
@ -1016,7 +1016,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
pxor (%arg1), \XMM2
pxor (%arg1), \XMM3
pxor (%arg1), \XMM4
movdqa HashKey_4_k(%arg2), \TMP5
movdqu HashKey_4_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
movaps 0x10(%arg1), \TMP1
AESENC \TMP1, \XMM1 # Round 1
@ -1031,7 +1031,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
movdqa \XMM6, \TMP1
pshufd $78, \XMM6, \TMP2
pxor \XMM6, \TMP2
movdqa HashKey_3(%arg2), \TMP5
movdqu HashKey_3(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
movaps 0x30(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 3
@ -1044,7 +1044,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
AESENC \TMP3, \XMM2
AESENC \TMP3, \XMM3
AESENC \TMP3, \XMM4
movdqa HashKey_3_k(%arg2), \TMP5
movdqu HashKey_3_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movaps 0x50(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 5
@ -1058,7 +1058,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
movdqa \XMM7, \TMP1
pshufd $78, \XMM7, \TMP2
pxor \XMM7, \TMP2
movdqa HashKey_2(%arg2), \TMP5
movdqu HashKey_2(%arg2), \TMP5
# Multiply TMP5 * HashKey using karatsuba
@ -1074,7 +1074,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
AESENC \TMP3, \XMM2
AESENC \TMP3, \XMM3
AESENC \TMP3, \XMM4
movdqa HashKey_2_k(%arg2), \TMP5
movdqu HashKey_2_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movaps 0x80(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 8
@ -1092,7 +1092,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
movdqa \XMM8, \TMP1
pshufd $78, \XMM8, \TMP2
pxor \XMM8, \TMP2
movdqa HashKey(%arg2), \TMP5
movdqu HashKey(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
movaps 0x90(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 9
@ -1121,7 +1121,7 @@ aes_loop_par_enc_done\@:
AESENCLAST \TMP3, \XMM2
AESENCLAST \TMP3, \XMM3
AESENCLAST \TMP3, \XMM4
movdqa HashKey_k(%arg2), \TMP5
movdqu HashKey_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movdqu (%arg4,%r11,1), \TMP3
pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
@ -1205,7 +1205,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
pshufd $78, \XMM5, \TMP6
pxor \XMM5, \TMP6
paddd ONE(%rip), \XMM0 # INCR CNT
movdqa HashKey_4(%arg2), \TMP5
movdqu HashKey_4(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
movdqa \XMM0, \XMM1
paddd ONE(%rip), \XMM0 # INCR CNT
@ -1224,7 +1224,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
pxor (%arg1), \XMM2
pxor (%arg1), \XMM3
pxor (%arg1), \XMM4
movdqa HashKey_4_k(%arg2), \TMP5
movdqu HashKey_4_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
movaps 0x10(%arg1), \TMP1
AESENC \TMP1, \XMM1 # Round 1
@ -1239,7 +1239,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
movdqa \XMM6, \TMP1
pshufd $78, \XMM6, \TMP2
pxor \XMM6, \TMP2
movdqa HashKey_3(%arg2), \TMP5
movdqu HashKey_3(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
movaps 0x30(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 3
@ -1252,7 +1252,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
AESENC \TMP3, \XMM2
AESENC \TMP3, \XMM3
AESENC \TMP3, \XMM4
movdqa HashKey_3_k(%arg2), \TMP5
movdqu HashKey_3_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movaps 0x50(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 5
@ -1266,7 +1266,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
movdqa \XMM7, \TMP1
pshufd $78, \XMM7, \TMP2
pxor \XMM7, \TMP2
movdqa HashKey_2(%arg2), \TMP5
movdqu HashKey_2(%arg2), \TMP5
# Multiply TMP5 * HashKey using karatsuba
@ -1282,7 +1282,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
AESENC \TMP3, \XMM2
AESENC \TMP3, \XMM3
AESENC \TMP3, \XMM4
movdqa HashKey_2_k(%arg2), \TMP5
movdqu HashKey_2_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movaps 0x80(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 8
@ -1300,7 +1300,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
movdqa \XMM8, \TMP1
pshufd $78, \XMM8, \TMP2
pxor \XMM8, \TMP2
movdqa HashKey(%arg2), \TMP5
movdqu HashKey(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
movaps 0x90(%arg1), \TMP3
AESENC \TMP3, \XMM1 # Round 9
@ -1329,7 +1329,7 @@ aes_loop_par_dec_done\@:
AESENCLAST \TMP3, \XMM2
AESENCLAST \TMP3, \XMM3
AESENCLAST \TMP3, \XMM4
movdqa HashKey_k(%arg2), \TMP5
movdqu HashKey_k(%arg2), \TMP5
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movdqu (%arg4,%r11,1), \TMP3
pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
@ -1405,10 +1405,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
movdqa \XMM1, \TMP6
pshufd $78, \XMM1, \TMP2
pxor \XMM1, \TMP2
movdqa HashKey_4(%arg2), \TMP5
movdqu HashKey_4(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1
PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0
movdqa HashKey_4_k(%arg2), \TMP4
movdqu HashKey_4_k(%arg2), \TMP4
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
movdqa \XMM1, \XMMDst
movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1
@ -1418,10 +1418,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
movdqa \XMM2, \TMP1
pshufd $78, \XMM2, \TMP2
pxor \XMM2, \TMP2
movdqa HashKey_3(%arg2), \TMP5
movdqu HashKey_3(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0
movdqa HashKey_3_k(%arg2), \TMP4
movdqu HashKey_3_k(%arg2), \TMP4
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
pxor \TMP1, \TMP6
pxor \XMM2, \XMMDst
@ -1433,10 +1433,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
movdqa \XMM3, \TMP1
pshufd $78, \XMM3, \TMP2
pxor \XMM3, \TMP2
movdqa HashKey_2(%arg2), \TMP5
movdqu HashKey_2(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0
movdqa HashKey_2_k(%arg2), \TMP4
movdqu HashKey_2_k(%arg2), \TMP4
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
pxor \TMP1, \TMP6
pxor \XMM3, \XMMDst
@ -1446,10 +1446,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
movdqa \XMM4, \TMP1
pshufd $78, \XMM4, \TMP2
pxor \XMM4, \TMP2
movdqa HashKey(%arg2), \TMP5
movdqu HashKey(%arg2), \TMP5
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0
movdqa HashKey_k(%arg2), \TMP4
movdqu HashKey_k(%arg2), \TMP4
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
pxor \TMP1, \TMP6
pxor \XMM4, \XMMDst

View file

@ -2465,7 +2465,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
perf_callchain_store(entry, regs->ip);
if (!current->mm)
if (!nmi_uaccess_okay())
return;
if (perf_callchain_user32(regs, entry))

View file

@ -33,7 +33,8 @@ extern inline unsigned long native_save_fl(void)
return flags;
}
static inline void native_restore_fl(unsigned long flags)
extern inline void native_restore_fl(unsigned long flags);
extern inline void native_restore_fl(unsigned long flags)
{
asm volatile("push %0 ; popf"
: /* no output */

View file

@ -2,6 +2,8 @@
#ifndef _ASM_X86_PGTABLE_3LEVEL_H
#define _ASM_X86_PGTABLE_3LEVEL_H
#include <asm/atomic64_32.h>
/*
* Intel Physical Address Extension (PAE) Mode - three-level page
* tables on PPro+ CPUs.
@ -150,10 +152,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep)
{
pte_t res;
/* xchg acts as a barrier before the setting of the high bits */
res.pte_low = xchg(&ptep->pte_low, 0);
res.pte_high = ptep->pte_high;
ptep->pte_high = 0;
res.pte = (pteval_t)arch_atomic64_xchg((atomic64_t *)ptep, 0);
return res;
}

View file

@ -132,6 +132,8 @@ struct cpuinfo_x86 {
/* Index into per_cpu list: */
u16 cpu_index;
u32 microcode;
/* Address space bits used by the cache internally */
u8 x86_cache_bits;
unsigned initialized : 1;
} __randomize_layout;
@ -183,7 +185,7 @@ extern void cpu_detect(struct cpuinfo_x86 *c);
static inline unsigned long long l1tf_pfn_limit(void)
{
return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT);
return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
}
extern void early_cpu_init(void);

View file

@ -39,6 +39,7 @@ extern void do_signal(struct pt_regs *regs);
#define __ARCH_HAS_SA_RESTORER
#include <asm/asm.h>
#include <uapi/asm/sigcontext.h>
#ifdef __i386__
@ -86,9 +87,9 @@ static inline int __const_sigismember(sigset_t *set, int _sig)
static inline int __gen_sigismember(sigset_t *set, int _sig)
{
unsigned char ret;
asm("btl %2,%1\n\tsetc %0"
: "=qm"(ret) : "m"(*set), "Ir"(_sig-1) : "cc");
bool ret;
asm("btl %2,%1" CC_SET(c)
: CC_OUT(c) (ret) : "m"(*set), "Ir"(_sig-1));
return ret;
}

View file

@ -111,6 +111,6 @@ static inline unsigned long caller_frame_pointer(void)
return (unsigned long)frame;
}
void show_opcodes(u8 *rip, const char *loglvl);
void show_opcodes(struct pt_regs *regs, const char *loglvl);
void show_ip(struct pt_regs *regs, const char *loglvl);
#endif /* _ASM_X86_STACKTRACE_H */

View file

@ -175,8 +175,16 @@ struct tlb_state {
* are on. This means that it may not match current->active_mm,
* which will contain the previous user mm when we're in lazy TLB
* mode even if we've already switched back to swapper_pg_dir.
*
* During switch_mm_irqs_off(), loaded_mm will be set to
* LOADED_MM_SWITCHING during the brief interrupts-off window
* when CR3 and loaded_mm would otherwise be inconsistent. This
* is for nmi_uaccess_okay()'s benefit.
*/
struct mm_struct *loaded_mm;
#define LOADED_MM_SWITCHING ((struct mm_struct *)1)
u16 loaded_mm_asid;
u16 next_asid;
/* last user mm's ctx id */
@ -246,6 +254,38 @@ struct tlb_state {
};
DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
/*
* Blindly accessing user memory from NMI context can be dangerous
* if we're in the middle of switching the current user task or
* switching the loaded mm. It can also be dangerous if we
* interrupted some kernel code that was temporarily using a
* different mm.
*/
static inline bool nmi_uaccess_okay(void)
{
struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
struct mm_struct *current_mm = current->mm;
VM_WARN_ON_ONCE(!loaded_mm);
/*
* The condition we want to check is
* current_mm->pgd == __va(read_cr3_pa()). This may be slow, though,
* if we're running in a VM with shadow paging, and nmi_uaccess_okay()
* is supposed to be reasonably fast.
*
* Instead, we check the almost equivalent but somewhat conservative
* condition below, and we rely on the fact that switch_mm_irqs_off()
* sets loaded_mm to LOADED_MM_SWITCHING before writing to CR3.
*/
if (loaded_mm != current_mm)
return false;
VM_WARN_ON_ONCE(current_mm->pgd != __va(read_cr3_pa()));
return true;
}
/* Initialize cr4 shadow for this CPU. */
static inline void cr4_init_shadow(void)
{

View file

@ -93,7 +93,7 @@ static inline unsigned int __getcpu(void)
*
* If RDPID is available, use it.
*/
alternative_io ("lsl %[p],%[seg]",
alternative_io ("lsl %[seg],%[p]",
".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */
X86_FEATURE_RDPID,
[p] "=a" (p), [seg] "r" (__PER_CPU_SEG));

View file

@ -684,8 +684,6 @@ void *__init_or_module text_poke_early(void *addr, const void *opcode,
* It means the size must be writable atomically and the address must be aligned
* in a way that permits an atomic write. It also makes sure we fit on a single
* page.
*
* Note: Must be called under text_mutex.
*/
void *text_poke(void *addr, const void *opcode, size_t len)
{
@ -700,6 +698,8 @@ void *text_poke(void *addr, const void *opcode, size_t len)
*/
BUG_ON(!after_bootmem);
lockdep_assert_held(&text_mutex);
if (!core_kernel_text((unsigned long)addr)) {
pages[0] = vmalloc_to_page(addr);
pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
@ -782,8 +782,6 @@ int poke_int3_handler(struct pt_regs *regs)
* - replace the first byte (int3) by the first byte of
* replacing opcode
* - sync cores
*
* Note: must be called under text_mutex.
*/
void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
{
@ -792,6 +790,9 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
bp_int3_handler = handler;
bp_int3_addr = (u8 *)addr + sizeof(int3);
bp_patching_in_progress = true;
lockdep_assert_held(&text_mutex);
/*
* Corresponding read barrier in int3 notifier for making sure the
* in_progress and handler are correctly ordered wrt. patching.

View file

@ -668,6 +668,45 @@ EXPORT_SYMBOL_GPL(l1tf_mitigation);
enum vmx_l1d_flush_state l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO;
EXPORT_SYMBOL_GPL(l1tf_vmx_mitigation);
/*
* These CPUs all support 44bits physical address space internally in the
* cache but CPUID can report a smaller number of physical address bits.
*
* The L1TF mitigation uses the top most address bit for the inversion of
* non present PTEs. When the installed memory reaches into the top most
* address bit due to memory holes, which has been observed on machines
* which report 36bits physical address bits and have 32G RAM installed,
* then the mitigation range check in l1tf_select_mitigation() triggers.
* This is a false positive because the mitigation is still possible due to
* the fact that the cache uses 44bit internally. Use the cache bits
* instead of the reported physical bits and adjust them on the affected
* machines to 44bit if the reported bits are less than 44.
*/
static void override_cache_bits(struct cpuinfo_x86 *c)
{
if (c->x86 != 6)
return;
switch (c->x86_model) {
case INTEL_FAM6_NEHALEM:
case INTEL_FAM6_WESTMERE:
case INTEL_FAM6_SANDYBRIDGE:
case INTEL_FAM6_IVYBRIDGE:
case INTEL_FAM6_HASWELL_CORE:
case INTEL_FAM6_HASWELL_ULT:
case INTEL_FAM6_HASWELL_GT3E:
case INTEL_FAM6_BROADWELL_CORE:
case INTEL_FAM6_BROADWELL_GT3E:
case INTEL_FAM6_SKYLAKE_MOBILE:
case INTEL_FAM6_SKYLAKE_DESKTOP:
case INTEL_FAM6_KABYLAKE_MOBILE:
case INTEL_FAM6_KABYLAKE_DESKTOP:
if (c->x86_cache_bits < 44)
c->x86_cache_bits = 44;
break;
}
}
static void __init l1tf_select_mitigation(void)
{
u64 half_pa;
@ -675,6 +714,8 @@ static void __init l1tf_select_mitigation(void)
if (!boot_cpu_has_bug(X86_BUG_L1TF))
return;
override_cache_bits(&boot_cpu_data);
switch (l1tf_mitigation) {
case L1TF_MITIGATION_OFF:
case L1TF_MITIGATION_FLUSH_NOWARN:
@ -694,11 +735,6 @@ static void __init l1tf_select_mitigation(void)
return;
#endif
/*
* This is extremely unlikely to happen because almost all
* systems have far more MAX_PA/2 than RAM can be fit into
* DIMM slots.
*/
half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT;
if (e820__mapped_any(half_pa, ULLONG_MAX - half_pa, E820_TYPE_RAM)) {
pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n");

View file

@ -919,6 +919,7 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
c->x86_phys_bits = 36;
#endif
c->x86_cache_bits = c->x86_phys_bits;
}
static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)

View file

@ -150,6 +150,9 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
return false;
if (c->x86 != 6)
return false;
for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
if (c->x86_model == spectre_bad_microcodes[i].model &&
c->x86_stepping == spectre_bad_microcodes[i].stepping)

View file

@ -17,6 +17,7 @@
#include <linux/bug.h>
#include <linux/nmi.h>
#include <linux/sysfs.h>
#include <linux/kasan.h>
#include <asm/cpu_entry_area.h>
#include <asm/stacktrace.h>
@ -89,14 +90,24 @@ static void printk_stack_address(unsigned long address, int reliable,
* Thus, the 2/3rds prologue and 64 byte OPCODE_BUFSIZE is just a random
* guesstimate in attempt to achieve all of the above.
*/
void show_opcodes(u8 *rip, const char *loglvl)
void show_opcodes(struct pt_regs *regs, const char *loglvl)
{
#define PROLOGUE_SIZE 42
#define EPILOGUE_SIZE 21
#define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)
u8 opcodes[OPCODE_BUFSIZE];
unsigned long prologue = regs->ip - PROLOGUE_SIZE;
bool bad_ip;
if (probe_kernel_read(opcodes, rip - PROLOGUE_SIZE, OPCODE_BUFSIZE)) {
/*
* Make sure userspace isn't trying to trick us into dumping kernel
* memory by pointing the userspace instruction pointer at it.
*/
bad_ip = user_mode(regs) &&
__chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX);
if (bad_ip || probe_kernel_read(opcodes, (u8 *)prologue,
OPCODE_BUFSIZE)) {
printk("%sCode: Bad RIP value.\n", loglvl);
} else {
printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"
@ -112,7 +123,7 @@ void show_ip(struct pt_regs *regs, const char *loglvl)
#else
printk("%sRIP: %04x:%pS\n", loglvl, (int)regs->cs, (void *)regs->ip);
#endif
show_opcodes((u8 *)regs->ip, loglvl);
show_opcodes(regs, loglvl);
}
void show_iret_regs(struct pt_regs *regs)
@ -346,7 +357,10 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
* We're not going to return, but we might be on an IST stack or
* have very little stack space left. Rewind the stack and kill
* the task.
* Before we rewind the stack, we have to tell KASAN that we're going to
* reuse the task stack and that existing poisons are invalid.
*/
kasan_unpoison_task_stack(current);
rewind_stack_do_exit(signr);
}
NOKPROBE_SYMBOL(oops_end);

View file

@ -7,6 +7,8 @@
#include <linux/uaccess.h>
#include <linux/export.h>
#include <asm/tlbflush.h>
/*
* We rely on the nested NMI work to allow atomic faults from the NMI path; the
* nested NMI paths are careful to preserve CR2.
@ -19,6 +21,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
if (__range_not_ok(from, n, TASK_SIZE))
return n;
if (!nmi_uaccess_okay())
return n;
/*
* Even though this function is typically called from NMI/IRQ context
* disable pagefaults so that its behaviour is consistent even when

View file

@ -837,7 +837,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code,
printk(KERN_CONT "\n");
show_opcodes((u8 *)regs->ip, loglvl);
show_opcodes(regs, loglvl);
}
static void

View file

@ -1420,6 +1420,29 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
return 0;
}
/*
* Machine check recovery code needs to change cache mode of poisoned
* pages to UC to avoid speculative access logging another error. But
* passing the address of the 1:1 mapping to set_memory_uc() is a fine
* way to encourage a speculative access. So we cheat and flip the top
* bit of the address. This works fine for the code that updates the
* page tables. But at the end of the process we need to flush the cache
* and the non-canonical address causes a #GP fault when used by the
* CLFLUSH instruction.
*
* But in the common case we already have a canonical address. This code
* will fix the top bit if needed and is a no-op otherwise.
*/
static inline unsigned long make_addr_canonical_again(unsigned long addr)
{
#ifdef CONFIG_X86_64
return (long)(addr << 1) >> 1;
#else
return addr;
#endif
}
static int change_page_attr_set_clr(unsigned long *addr, int numpages,
pgprot_t mask_set, pgprot_t mask_clr,
int force_split, int in_flag,
@ -1465,7 +1488,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
* Save address for cache flush. *addr is modified in the call
* to __change_page_attr_set_clr() below.
*/
baddr = *addr;
baddr = make_addr_canonical_again(*addr);
}
/* Must avoid aliasing mappings in the highmem code */

View file

@ -248,7 +248,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
*
* Returns a pointer to a PTE on success, or NULL on failure.
*/
static __init pte_t *pti_user_pagetable_walk_pte(unsigned long address)
static pte_t *pti_user_pagetable_walk_pte(unsigned long address)
{
gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
pmd_t *pmd;

View file

@ -305,6 +305,10 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
choose_new_asid(next, next_tlb_gen, &new_asid, &need_flush);
/* Let nmi_uaccess_okay() know that we're changing CR3. */
this_cpu_write(cpu_tlbstate.loaded_mm, LOADED_MM_SWITCHING);
barrier();
if (need_flush) {
this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
@ -335,6 +339,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
if (next != &init_mm)
this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id);
/* Make sure we write CR3 before loaded_mm. */
barrier();
this_cpu_write(cpu_tlbstate.loaded_mm, next);
this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
}

View file

@ -85,14 +85,10 @@ pgd_t * __init efi_call_phys_prolog(void)
void __init efi_call_phys_epilog(pgd_t *save_pgd)
{
struct desc_ptr gdt_descr;
gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
gdt_descr.size = GDT_SIZE - 1;
load_gdt(&gdt_descr);
load_cr3(save_pgd);
__flush_tlb_all();
load_fixmap_gdt(0);
}
void __init efi_runtime_update_mappings(void)

View file

@ -435,14 +435,13 @@ static void xen_set_pud(pud_t *ptr, pud_t val)
static void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
{
trace_xen_mmu_set_pte_atomic(ptep, pte);
set_64bit((u64 *)ptep, native_pte_val(pte));
__xen_set_pte(ptep, pte);
}
static void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
trace_xen_mmu_pte_clear(mm, addr, ptep);
if (!xen_batched_set_pte(ptep, native_make_pte(0)))
native_pte_clear(mm, addr, ptep);
__xen_set_pte(ptep, native_make_pte(0));
}
static void xen_pmd_clear(pmd_t *pmdp)
@ -1570,7 +1569,7 @@ static void __init xen_set_pte_init(pte_t *ptep, pte_t pte)
pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
pte_val_ma(pte));
#endif
native_set_pte(ptep, pte);
__xen_set_pte(ptep, pte);
}
/* Early in boot, while setting up the initial pagetable, assume
@ -2061,7 +2060,6 @@ void __init xen_relocate_p2m(void)
pud_t *pud;
pgd_t *pgd;
unsigned long *new_p2m;
int save_pud;
size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
n_pte = roundup(size, PAGE_SIZE) >> PAGE_SHIFT;
@ -2091,7 +2089,6 @@ void __init xen_relocate_p2m(void)
pgd = __va(read_cr3_pa());
new_p2m = (unsigned long *)(2 * PGDIR_SIZE);
save_pud = n_pud;
for (idx_pud = 0; idx_pud < n_pud; idx_pud++) {
pud = early_memremap(pud_phys, PAGE_SIZE);
clear_page(pud);

View file

@ -123,16 +123,11 @@ static void rwb_wake_all(struct rq_wb *rwb)
}
}
static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
static void wbt_rqw_done(struct rq_wb *rwb, struct rq_wait *rqw,
enum wbt_flags wb_acct)
{
struct rq_wb *rwb = RQWB(rqos);
struct rq_wait *rqw;
int inflight, limit;
if (!(wb_acct & WBT_TRACKED))
return;
rqw = get_rq_wait(rwb, wb_acct);
inflight = atomic_dec_return(&rqw->inflight);
/*
@ -166,10 +161,22 @@ static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
int diff = limit - inflight;
if (!inflight || diff >= rwb->wb_background / 2)
wake_up(&rqw->wait);
wake_up_all(&rqw->wait);
}
}
static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
{
struct rq_wb *rwb = RQWB(rqos);
struct rq_wait *rqw;
if (!(wb_acct & WBT_TRACKED))
return;
rqw = get_rq_wait(rwb, wb_acct);
wbt_rqw_done(rwb, rqw, wb_acct);
}
/*
* Called on completion of a request. Note that it's also called when
* a request is merged, when the request gets freed.
@ -481,6 +488,34 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw)
return limit;
}
struct wbt_wait_data {
struct wait_queue_entry wq;
struct task_struct *task;
struct rq_wb *rwb;
struct rq_wait *rqw;
unsigned long rw;
bool got_token;
};
static int wbt_wake_function(struct wait_queue_entry *curr, unsigned int mode,
int wake_flags, void *key)
{
struct wbt_wait_data *data = container_of(curr, struct wbt_wait_data,
wq);
/*
* If we fail to get a budget, return -1 to interrupt the wake up
* loop in __wake_up_common.
*/
if (!rq_wait_inc_below(data->rqw, get_limit(data->rwb, data->rw)))
return -1;
data->got_token = true;
list_del_init(&curr->entry);
wake_up_process(data->task);
return 1;
}
/*
* Block if we will exceed our limit, or if we are currently waiting for
* the timer to kick off queuing again.
@ -491,31 +526,52 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
__acquires(lock)
{
struct rq_wait *rqw = get_rq_wait(rwb, wb_acct);
DECLARE_WAITQUEUE(wait, current);
struct wbt_wait_data data = {
.wq = {
.func = wbt_wake_function,
.entry = LIST_HEAD_INIT(data.wq.entry),
},
.task = current,
.rwb = rwb,
.rqw = rqw,
.rw = rw,
};
bool has_sleeper;
has_sleeper = wq_has_sleeper(&rqw->wait);
if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
return;
add_wait_queue_exclusive(&rqw->wait, &wait);
prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
if (data.got_token)
break;
if (!has_sleeper &&
rq_wait_inc_below(rqw, get_limit(rwb, rw))) {
finish_wait(&rqw->wait, &data.wq);
/*
* We raced with wbt_wake_function() getting a token,
* which means we now have two. Put our local token
* and wake anyone else potentially waiting for one.
*/
if (data.got_token)
wbt_rqw_done(rwb, rqw, wb_acct);
break;
}
if (lock) {
spin_unlock_irq(lock);
io_schedule();
spin_lock_irq(lock);
} else
io_schedule();
has_sleeper = false;
} while (1);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&rqw->wait, &wait);
finish_wait(&rqw->wait, &data.wq);
}
static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
@ -580,11 +636,6 @@ static void wbt_wait(struct rq_qos *rqos, struct bio *bio, spinlock_t *lock)
return;
}
if (current_is_kswapd())
flags |= WBT_KSWAPD;
if (bio_op(bio) == REQ_OP_DISCARD)
flags |= WBT_DISCARD;
__wbt_wait(rwb, flags, bio->bi_opf, lock);
if (!blk_stat_is_active(rwb->cb))

View file

@ -37,7 +37,7 @@ struct bsg_device {
struct request_queue *queue;
spinlock_t lock;
struct hlist_node dev_list;
atomic_t ref_count;
refcount_t ref_count;
char name[20];
int max_queue;
};
@ -252,7 +252,7 @@ static int bsg_put_device(struct bsg_device *bd)
mutex_lock(&bsg_mutex);
if (!atomic_dec_and_test(&bd->ref_count)) {
if (!refcount_dec_and_test(&bd->ref_count)) {
mutex_unlock(&bsg_mutex);
return 0;
}
@ -290,7 +290,7 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
bd->queue = rq;
atomic_set(&bd->ref_count, 1);
refcount_set(&bd->ref_count, 1);
hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
@ -308,7 +308,7 @@ static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
if (bd->queue == q) {
atomic_inc(&bd->ref_count);
refcount_inc(&bd->ref_count);
goto found;
}
}

View file

@ -895,8 +895,7 @@ int elv_register(struct elevator_type *e)
spin_lock(&elv_list_lock);
if (elevator_find(e->elevator_name, e->uses_mq)) {
spin_unlock(&elv_list_lock);
if (e->icq_cache)
kmem_cache_destroy(e->icq_cache);
kmem_cache_destroy(e->icq_cache);
return -EBUSY;
}
list_add_tail(&e->list, &elv_list);

View file

@ -256,14 +256,12 @@ static struct ata_port_operations pata_ftide010_port_ops = {
.qc_issue = ftide010_qc_issue,
};
static struct ata_port_info ftide010_port_info[] = {
{
.flags = ATA_FLAG_SLAVE_POSS,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.pio_mask = ATA_PIO4,
.port_ops = &pata_ftide010_port_ops,
},
static struct ata_port_info ftide010_port_info = {
.flags = ATA_FLAG_SLAVE_POSS,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.pio_mask = ATA_PIO4,
.port_ops = &pata_ftide010_port_ops,
};
#if IS_ENABLED(CONFIG_SATA_GEMINI)
@ -349,6 +347,7 @@ static int pata_ftide010_gemini_cable_detect(struct ata_port *ap)
}
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
struct ata_port_info *pi,
bool is_ata1)
{
struct device *dev = ftide->dev;
@ -373,7 +372,13 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
/* Flag port as SATA-capable */
if (gemini_sata_bridge_enabled(sg, is_ata1))
ftide010_port_info[0].flags |= ATA_FLAG_SATA;
pi->flags |= ATA_FLAG_SATA;
/* This device has broken DMA, only PIO works */
if (of_machine_is_compatible("itian,sq201")) {
pi->mwdma_mask = 0;
pi->udma_mask = 0;
}
/*
* We assume that a simple 40-wire cable is used in the PATA mode.
@ -435,6 +440,7 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
}
#else
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
struct ata_port_info *pi,
bool is_ata1)
{
return -ENOTSUPP;
@ -446,7 +452,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
const struct ata_port_info pi = ftide010_port_info[0];
struct ata_port_info pi = ftide010_port_info;
const struct ata_port_info *ppi[] = { &pi, NULL };
struct ftide010 *ftide;
struct resource *res;
@ -490,6 +496,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
* are ATA0. This will also set up the cable types.
*/
ret = pata_ftide010_gemini_init(ftide,
&pi,
(res->start == 0x63400000));
if (ret)
goto err_dis_clk;

View file

@ -185,7 +185,7 @@ EXPORT_SYMBOL_GPL(of_pm_clk_add_clk);
int of_pm_clk_add_clks(struct device *dev)
{
struct clk **clks;
unsigned int i, count;
int i, count;
int ret;
if (!dev || !dev->of_node)

View file

@ -83,6 +83,18 @@ module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
MODULE_PARM_DESC(max_persistent_grants,
"Maximum number of grants to map persistently");
/*
* How long a persistent grant is allowed to remain allocated without being in
* use. The time is in seconds, 0 means indefinitely long.
*/
static unsigned int xen_blkif_pgrant_timeout = 60;
module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,
uint, 0644);
MODULE_PARM_DESC(persistent_grant_unused_seconds,
"Time in seconds an unused persistent grant is allowed to "
"remain allocated. Default is 60, 0 means unlimited.");
/*
* Maximum number of rings/queues blkback supports, allow as many queues as there
* are CPUs if user has not specified a value.
@ -123,6 +135,13 @@ module_param(log_stats, int, 0644);
/* Number of free pages to remove on each call to gnttab_free_pages */
#define NUM_BATCH_FREE_PAGES 10
static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
{
return xen_blkif_pgrant_timeout &&
(jiffies - persistent_gnt->last_used >=
HZ * xen_blkif_pgrant_timeout);
}
static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
{
unsigned long flags;
@ -236,8 +255,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring,
}
}
bitmap_zero(persistent_gnt->flags, PERSISTENT_GNT_FLAGS_SIZE);
set_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
persistent_gnt->active = true;
/* Add new node and rebalance tree. */
rb_link_node(&(persistent_gnt->node), parent, new);
rb_insert_color(&(persistent_gnt->node), &ring->persistent_gnts);
@ -261,11 +279,11 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
else if (gref > data->gnt)
node = node->rb_right;
else {
if(test_bit(PERSISTENT_GNT_ACTIVE, data->flags)) {
if (data->active) {
pr_alert_ratelimited("requesting a grant already in use\n");
return NULL;
}
set_bit(PERSISTENT_GNT_ACTIVE, data->flags);
data->active = true;
atomic_inc(&ring->persistent_gnt_in_use);
return data;
}
@ -276,10 +294,10 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
static void put_persistent_gnt(struct xen_blkif_ring *ring,
struct persistent_gnt *persistent_gnt)
{
if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
if (!persistent_gnt->active)
pr_alert_ratelimited("freeing a grant already unused\n");
set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
persistent_gnt->last_used = jiffies;
persistent_gnt->active = false;
atomic_dec(&ring->persistent_gnt_in_use);
}
@ -371,26 +389,26 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
struct persistent_gnt *persistent_gnt;
struct rb_node *n;
unsigned int num_clean, total;
bool scan_used = false, clean_used = false;
bool scan_used = false;
struct rb_root *root;
if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
(ring->persistent_gnt_c == xen_blkif_max_pgrants &&
!ring->blkif->vbd.overflow_max_grants)) {
goto out;
}
if (work_busy(&ring->persistent_purge_work)) {
pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
goto out;
}
num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
num_clean = min(ring->persistent_gnt_c, num_clean);
if ((num_clean == 0) ||
(num_clean > (ring->persistent_gnt_c - atomic_read(&ring->persistent_gnt_in_use))))
goto out;
if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
(ring->persistent_gnt_c == xen_blkif_max_pgrants &&
!ring->blkif->vbd.overflow_max_grants)) {
num_clean = 0;
} else {
num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +
num_clean;
num_clean = min(ring->persistent_gnt_c, num_clean);
pr_debug("Going to purge at least %u persistent grants\n",
num_clean);
}
/*
* At this point, we can assure that there will be no calls
@ -401,9 +419,7 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
* number of grants.
*/
total = num_clean;
pr_debug("Going to purge %u persistent grants\n", num_clean);
total = 0;
BUG_ON(!list_empty(&ring->persistent_purge_list));
root = &ring->persistent_gnts;
@ -412,47 +428,38 @@ purge_list:
BUG_ON(persistent_gnt->handle ==
BLKBACK_INVALID_HANDLE);
if (clean_used) {
clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
if (persistent_gnt->active)
continue;
}
if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
if (!scan_used && !persistent_gnt_timeout(persistent_gnt))
continue;
if (!scan_used &&
(test_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags)))
if (scan_used && total >= num_clean)
continue;
rb_erase(&persistent_gnt->node, root);
list_add(&persistent_gnt->remove_node,
&ring->persistent_purge_list);
if (--num_clean == 0)
goto finished;
total++;
}
/*
* If we get here it means we also need to start cleaning
* Check whether we also need to start cleaning
* grants that were used since last purge in order to cope
* with the requested num
*/
if (!scan_used && !clean_used) {
pr_debug("Still missing %u purged frames\n", num_clean);
if (!scan_used && total < num_clean) {
pr_debug("Still missing %u purged frames\n", num_clean - total);
scan_used = true;
goto purge_list;
}
finished:
if (!clean_used) {
pr_debug("Finished scanning for grants to clean, removing used flag\n");
clean_used = true;
goto purge_list;
if (total) {
ring->persistent_gnt_c -= total;
ring->blkif->vbd.overflow_max_grants = 0;
/* We can defer this work */
schedule_work(&ring->persistent_purge_work);
pr_debug("Purged %u/%u\n", num_clean, total);
}
ring->persistent_gnt_c -= (total - num_clean);
ring->blkif->vbd.overflow_max_grants = 0;
/* We can defer this work */
schedule_work(&ring->persistent_purge_work);
pr_debug("Purged %u/%u\n", (total - num_clean), total);
out:
return;
}

View file

@ -233,16 +233,6 @@ struct xen_vbd {
struct backend_info;
/* Number of available flags */
#define PERSISTENT_GNT_FLAGS_SIZE 2
/* This persistent grant is currently in use */
#define PERSISTENT_GNT_ACTIVE 0
/*
* This persistent grant has been used, this flag is set when we remove the
* PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
*/
#define PERSISTENT_GNT_WAS_ACTIVE 1
/* Number of requests that we can fit in a ring */
#define XEN_BLKIF_REQS_PER_PAGE 32
@ -250,7 +240,8 @@ struct persistent_gnt {
struct page *page;
grant_ref_t gnt;
grant_handle_t handle;
DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
unsigned long last_used;
bool active;
struct rb_node node;
struct list_head remove_node;
};
@ -278,7 +269,6 @@ struct xen_blkif_ring {
wait_queue_head_t pending_free_wq;
/* Tree to store persistent grants. */
spinlock_t pers_gnts_lock;
struct rb_root persistent_gnts;
unsigned int persistent_gnt_c;
atomic_t persistent_gnt_in_use;

View file

@ -46,6 +46,7 @@
#include <linux/scatterlist.h>
#include <linux/bitmap.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@ -121,6 +122,8 @@ static inline struct blkif_req *blkif_req(struct request *rq)
static DEFINE_MUTEX(blkfront_mutex);
static const struct block_device_operations xlvbd_block_fops;
static struct delayed_work blkfront_work;
static LIST_HEAD(info_list);
/*
* Maximum number of segments in indirect requests, the actual value used by
@ -216,6 +219,7 @@ struct blkfront_info
/* Save uncomplete reqs and bios for migration. */
struct list_head requests;
struct bio_list bio_list;
struct list_head info_list;
};
static unsigned int nr_minors;
@ -1759,6 +1763,12 @@ abort_transaction:
return err;
}
static void free_info(struct blkfront_info *info)
{
list_del(&info->info_list);
kfree(info);
}
/* Common code used when first setting up, and when resuming. */
static int talk_to_blkback(struct xenbus_device *dev,
struct blkfront_info *info)
@ -1880,7 +1890,10 @@ again:
destroy_blkring:
blkif_free(info, 0);
kfree(info);
mutex_lock(&blkfront_mutex);
free_info(info);
mutex_unlock(&blkfront_mutex);
dev_set_drvdata(&dev->dev, NULL);
return err;
@ -1991,6 +2004,10 @@ static int blkfront_probe(struct xenbus_device *dev,
info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
dev_set_drvdata(&dev->dev, info);
mutex_lock(&blkfront_mutex);
list_add(&info->info_list, &info_list);
mutex_unlock(&blkfront_mutex);
return 0;
}
@ -2301,6 +2318,12 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
if (indirect_segments <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
indirect_segments = 0;
info->max_indirect_segments = indirect_segments;
if (info->feature_persistent) {
mutex_lock(&blkfront_mutex);
schedule_delayed_work(&blkfront_work, HZ * 10);
mutex_unlock(&blkfront_mutex);
}
}
/*
@ -2482,7 +2505,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
mutex_unlock(&info->mutex);
if (!bdev) {
kfree(info);
mutex_lock(&blkfront_mutex);
free_info(info);
mutex_unlock(&blkfront_mutex);
return 0;
}
@ -2502,7 +2527,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
if (info && !bdev->bd_openers) {
xlvbd_release_gendisk(info);
disk->private_data = NULL;
kfree(info);
mutex_lock(&blkfront_mutex);
free_info(info);
mutex_unlock(&blkfront_mutex);
}
mutex_unlock(&bdev->bd_mutex);
@ -2585,7 +2612,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
xlvbd_release_gendisk(info);
disk->private_data = NULL;
kfree(info);
free_info(info);
}
out:
@ -2618,6 +2645,61 @@ static struct xenbus_driver blkfront_driver = {
.is_ready = blkfront_is_ready,
};
static void purge_persistent_grants(struct blkfront_info *info)
{
unsigned int i;
unsigned long flags;
for (i = 0; i < info->nr_rings; i++) {
struct blkfront_ring_info *rinfo = &info->rinfo[i];
struct grant *gnt_list_entry, *tmp;
spin_lock_irqsave(&rinfo->ring_lock, flags);
if (rinfo->persistent_gnts_c == 0) {
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
continue;
}
list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants,
node) {
if (gnt_list_entry->gref == GRANT_INVALID_REF ||
gnttab_query_foreign_access(gnt_list_entry->gref))
continue;
list_del(&gnt_list_entry->node);
gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
rinfo->persistent_gnts_c--;
__free_page(gnt_list_entry->page);
kfree(gnt_list_entry);
}
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
}
}
static void blkfront_delay_work(struct work_struct *work)
{
struct blkfront_info *info;
bool need_schedule_work = false;
mutex_lock(&blkfront_mutex);
list_for_each_entry(info, &info_list, info_list) {
if (info->feature_persistent) {
need_schedule_work = true;
mutex_lock(&info->mutex);
purge_persistent_grants(info);
mutex_unlock(&info->mutex);
}
}
if (need_schedule_work)
schedule_delayed_work(&blkfront_work, HZ * 10);
mutex_unlock(&blkfront_mutex);
}
static int __init xlblk_init(void)
{
int ret;
@ -2626,6 +2708,15 @@ static int __init xlblk_init(void)
if (!xen_domain())
return -ENODEV;
if (!xen_has_pv_disk_devices())
return -ENODEV;
if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
pr_warn("xen_blk: can't get major %d with name %s\n",
XENVBD_MAJOR, DEV_NAME);
return -ENODEV;
}
if (xen_blkif_max_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
xen_blkif_max_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
@ -2641,14 +2732,7 @@ static int __init xlblk_init(void)
xen_blkif_max_queues = nr_cpus;
}
if (!xen_has_pv_disk_devices())
return -ENODEV;
if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
printk(KERN_WARNING "xen_blk: can't get major %d with name %s\n",
XENVBD_MAJOR, DEV_NAME);
return -ENODEV;
}
INIT_DELAYED_WORK(&blkfront_work, blkfront_delay_work);
ret = xenbus_register_frontend(&blkfront_driver);
if (ret) {
@ -2663,6 +2747,8 @@ module_init(xlblk_init);
static void __exit xlblk_exit(void)
{
cancel_delayed_work_sync(&blkfront_work);
xenbus_unregister_driver(&blkfront_driver);
unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
kfree(minors);

View file

@ -200,6 +200,7 @@ config BT_HCIUART_RTL
depends on BT_HCIUART
depends on BT_HCIUART_SERDEV
depends on GPIOLIB
depends on ACPI
select BT_HCIUART_3WIRE
select BT_RTL
help

View file

@ -144,8 +144,10 @@ static int mtk_setup_fw(struct hci_dev *hdev)
fw_size = fw->size;
/* The size of patch header is 30 bytes, should be skip */
if (fw_size < 30)
return -EINVAL;
if (fw_size < 30) {
err = -EINVAL;
goto free_fw;
}
fw_size -= 30;
fw_ptr += 30;
@ -172,8 +174,8 @@ static int mtk_setup_fw(struct hci_dev *hdev)
fw_ptr += dlen;
}
free_fw:
release_firmware(fw);
return err;
}

View file

@ -498,32 +498,29 @@ static int sysc_check_registers(struct sysc *ddata)
/**
* syc_ioremap - ioremap register space for the interconnect target module
* @ddata: deviec driver data
* @ddata: device driver data
*
* Note that the interconnect target module registers can be anywhere
* within the first child device address space. For example, SGX has
* them at offset 0x1fc00 in the 32MB module address space. We just
* what we need around the interconnect target module registers.
* within the interconnect target module range. For example, SGX has
* them at offset 0x1fc00 in the 32MB module address space. And cpsw
* has them at offset 0x1200 in the CPSW_WR child. Usually the
* the interconnect target module registers are at the beginning of
* the module range though.
*/
static int sysc_ioremap(struct sysc *ddata)
{
u32 size = 0;
int size;
if (ddata->offsets[SYSC_SYSSTATUS] >= 0)
size = ddata->offsets[SYSC_SYSSTATUS];
else if (ddata->offsets[SYSC_SYSCONFIG] >= 0)
size = ddata->offsets[SYSC_SYSCONFIG];
else if (ddata->offsets[SYSC_REVISION] >= 0)
size = ddata->offsets[SYSC_REVISION];
else
size = max3(ddata->offsets[SYSC_REVISION],
ddata->offsets[SYSC_SYSCONFIG],
ddata->offsets[SYSC_SYSSTATUS]);
if (size < 0 || (size + sizeof(u32)) > ddata->module_size)
return -EINVAL;
size &= 0xfff00;
size += SZ_256;
ddata->module_va = devm_ioremap(ddata->dev,
ddata->module_pa,
size);
size + sizeof(u32));
if (!ddata->module_va)
return -EIO;
@ -1224,10 +1221,10 @@ static int sysc_child_suspend_noirq(struct device *dev)
if (!pm_runtime_status_suspended(dev)) {
error = pm_generic_runtime_suspend(dev);
if (error) {
dev_err(dev, "%s error at %i: %i\n",
__func__, __LINE__, error);
dev_warn(dev, "%s busy at %i: %i\n",
__func__, __LINE__, error);
return error;
return 0;
}
error = sysc_runtime_suspend(ddata->dev);

View file

@ -2546,7 +2546,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
if (!CDROM_CAN(CDC_SELECT_DISC) ||
(arg == CDSL_CURRENT || arg == CDSL_NONE))
return cdi->ops->drive_status(cdi, CDSL_CURRENT);
if (((int)arg >= cdi->capacity))
if (arg >= cdi->capacity)
return -EINVAL;
return cdrom_slot_status(cdi, arg);
}

View file

@ -558,8 +558,8 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
if (!clk_base)
goto npcm7xx_init_error;
npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) *
NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL);
npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws,
NPCM7XX_NUM_CLOCKS), GFP_KERNEL);
if (!npcm7xx_clk_data)
goto npcm7xx_init_np_err;

View file

@ -46,7 +46,7 @@ static int st_clk_probe(struct platform_device *pdev)
clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL);
clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_25M]->clk);
clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_48M]->clk);
hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux",
0, st_data->base + MISCCLKCNTL1, OSCCLKENB,

View file

@ -379,9 +379,20 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
if (idx == -1)
idx = i; /* first enabled state */
if (s->target_residency > data->predicted_us) {
if (!tick_nohz_tick_stopped())
if (data->predicted_us < TICK_USEC)
break;
if (!tick_nohz_tick_stopped()) {
/*
* If the state selected so far is shallow,
* waking up early won't hurt, so retain the
* tick in that case and let the governor run
* again in the next iteration of the loop.
*/
expected_interval = drv->states[idx].target_residency;
break;
}
/*
* If the state selected so far is shallow and this
* state's target residency matches the time till the

View file

@ -679,10 +679,8 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
int ret = 0;
if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) {
crypto_ablkcipher_set_flags(ablkcipher,
CRYPTO_TFM_RES_BAD_KEY_LEN);
dev_err(jrdev, "key size mismatch\n");
return -EINVAL;
goto badkey;
}
ctx->cdata.keylen = keylen;
@ -715,7 +713,7 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
return ret;
badkey:
crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return 0;
return -EINVAL;
}
/*

View file

@ -71,8 +71,8 @@ static void rsa_priv_f2_unmap(struct device *dev, struct rsa_edesc *edesc,
dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
}
static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
@ -90,8 +90,8 @@ static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
}
/* RSA Job Completion handler */
@ -417,13 +417,13 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
goto unmap_p;
}
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
dev_err(dev, "Unable to map RSA tmp1 memory\n");
goto unmap_q;
}
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, pdb->tmp2_dma)) {
dev_err(dev, "Unable to map RSA tmp2 memory\n");
goto unmap_tmp1;
@ -451,7 +451,7 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
return 0;
unmap_tmp1:
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
unmap_q:
dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
unmap_p:
@ -504,13 +504,13 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
goto unmap_dq;
}
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
dev_err(dev, "Unable to map RSA tmp1 memory\n");
goto unmap_qinv;
}
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, pdb->tmp2_dma)) {
dev_err(dev, "Unable to map RSA tmp2 memory\n");
goto unmap_tmp1;
@ -538,7 +538,7 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
return 0;
unmap_tmp1:
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
unmap_qinv:
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
unmap_dq:

View file

@ -190,7 +190,8 @@ static void caam_jr_dequeue(unsigned long devarg)
BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0);
/* Unmap just-run descriptor so we can post-process */
dma_unmap_single(dev, jrp->outring[hw_idx].desc,
dma_unmap_single(dev,
caam_dma_to_cpu(jrp->outring[hw_idx].desc),
jrp->entinfo[sw_idx].desc_size,
DMA_TO_DEVICE);

View file

@ -35,6 +35,7 @@ struct nitrox_cmdq {
/* requests in backlog queues */
atomic_t backlog_count;
int write_idx;
/* command size 32B/64B */
u8 instr_size;
u8 qno;
@ -87,7 +88,7 @@ struct nitrox_bh {
struct bh_data *slc;
};
/* NITROX-5 driver state */
/* NITROX-V driver state */
#define NITROX_UCODE_LOADED 0
#define NITROX_READY 1

View file

@ -36,6 +36,7 @@ static int cmdq_common_init(struct nitrox_cmdq *cmdq)
cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
cmdq->qsize = (qsize + PKT_IN_ALIGN);
cmdq->write_idx = 0;
spin_lock_init(&cmdq->response_lock);
spin_lock_init(&cmdq->cmdq_lock);

View file

@ -42,6 +42,16 @@
* Invalid flag options in AES-CCM IV.
*/
static inline int incr_index(int index, int count, int max)
{
if ((index + count) >= max)
index = index + count - max;
else
index += count;
return index;
}
/**
* dma_free_sglist - unmap and free the sg lists.
* @ndev: N5 device
@ -426,30 +436,29 @@ static void post_se_instr(struct nitrox_softreq *sr,
struct nitrox_cmdq *cmdq)
{
struct nitrox_device *ndev = sr->ndev;
union nps_pkt_in_instr_baoff_dbell pkt_in_baoff_dbell;
u64 offset;
int idx;
u8 *ent;
spin_lock_bh(&cmdq->cmdq_lock);
/* get the next write offset */
offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(cmdq->qno);
pkt_in_baoff_dbell.value = nitrox_read_csr(ndev, offset);
idx = cmdq->write_idx;
/* copy the instruction */
ent = cmdq->head + pkt_in_baoff_dbell.s.aoff;
ent = cmdq->head + (idx * cmdq->instr_size);
memcpy(ent, &sr->instr, cmdq->instr_size);
/* flush the command queue updates */
dma_wmb();
sr->tstamp = jiffies;
atomic_set(&sr->status, REQ_POSTED);
response_list_add(sr, cmdq);
sr->tstamp = jiffies;
/* flush the command queue updates */
dma_wmb();
/* Ring doorbell with count 1 */
writeq(1, cmdq->dbell_csr_addr);
/* orders the doorbell rings */
mmiowb();
cmdq->write_idx = incr_index(idx, 1, ndev->qlen);
spin_unlock_bh(&cmdq->cmdq_lock);
}
@ -459,6 +468,9 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
struct nitrox_softreq *sr, *tmp;
int ret = 0;
if (!atomic_read(&cmdq->backlog_count))
return 0;
spin_lock_bh(&cmdq->backlog_lock);
list_for_each_entry_safe(sr, tmp, &cmdq->backlog_head, backlog) {
@ -466,7 +478,7 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
/* submit until space available */
if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
ret = -EBUSY;
ret = -ENOSPC;
break;
}
/* delete from backlog list */
@ -491,23 +503,20 @@ static int nitrox_enqueue_request(struct nitrox_softreq *sr)
{
struct nitrox_cmdq *cmdq = sr->cmdq;
struct nitrox_device *ndev = sr->ndev;
int ret = -EBUSY;
/* try to post backlog requests */
post_backlog_cmds(cmdq);
if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
if (!(sr->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
return -EAGAIN;
return -ENOSPC;
/* add to backlog list */
backlog_list_add(sr, cmdq);
} else {
ret = post_backlog_cmds(cmdq);
if (ret) {
backlog_list_add(sr, cmdq);
return ret;
}
post_se_instr(sr, cmdq);
ret = -EINPROGRESS;
return -EBUSY;
}
return ret;
post_se_instr(sr, cmdq);
return -EINPROGRESS;
}
/**
@ -624,11 +633,9 @@ int nitrox_process_se_request(struct nitrox_device *ndev,
*/
sr->instr.fdata[0] = *((u64 *)&req->gph);
sr->instr.fdata[1] = 0;
/* flush the soft_req changes before posting the cmd */
wmb();
ret = nitrox_enqueue_request(sr);
if (ret == -EAGAIN)
if (ret == -ENOSPC)
goto send_fail;
return ret;

View file

@ -96,6 +96,10 @@ enum csk_flags {
CSK_CONN_INLINE, /* Connection on HW */
};
enum chtls_cdev_state {
CHTLS_CDEV_STATE_UP = 1
};
struct listen_ctx {
struct sock *lsk;
struct chtls_dev *cdev;
@ -146,6 +150,7 @@ struct chtls_dev {
unsigned int send_page_order;
int max_host_sndbuf;
struct key_map kmap;
unsigned int cdev_state;
};
struct chtls_hws {

View file

@ -160,6 +160,7 @@ static void chtls_register_dev(struct chtls_dev *cdev)
tlsdev->hash = chtls_create_hash;
tlsdev->unhash = chtls_destroy_hash;
tls_register_device(&cdev->tlsdev);
cdev->cdev_state = CHTLS_CDEV_STATE_UP;
}
static void chtls_unregister_dev(struct chtls_dev *cdev)
@ -281,8 +282,10 @@ static void chtls_free_all_uld(void)
struct chtls_dev *cdev, *tmp;
mutex_lock(&cdev_mutex);
list_for_each_entry_safe(cdev, tmp, &cdev_list, list)
chtls_free_uld(cdev);
list_for_each_entry_safe(cdev, tmp, &cdev_list, list) {
if (cdev->cdev_state == CHTLS_CDEV_STATE_UP)
chtls_free_uld(cdev);
}
mutex_unlock(&cdev_mutex);
}

View file

@ -107,24 +107,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
ret = crypto_skcipher_encrypt(req);
skcipher_request_zero(req);
} else {
preempt_disable();
pagefault_disable();
enable_kernel_vsx();
blkcipher_walk_init(&walk, dst, src, nbytes);
ret = blkcipher_walk_virt(desc, &walk);
while ((nbytes = walk.nbytes)) {
preempt_disable();
pagefault_disable();
enable_kernel_vsx();
aes_p8_cbc_encrypt(walk.src.virt.addr,
walk.dst.virt.addr,
nbytes & AES_BLOCK_MASK,
&ctx->enc_key, walk.iv, 1);
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
nbytes &= AES_BLOCK_SIZE - 1;
ret = blkcipher_walk_done(desc, &walk, nbytes);
}
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
}
return ret;
@ -147,24 +146,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
ret = crypto_skcipher_decrypt(req);
skcipher_request_zero(req);
} else {
preempt_disable();
pagefault_disable();
enable_kernel_vsx();
blkcipher_walk_init(&walk, dst, src, nbytes);
ret = blkcipher_walk_virt(desc, &walk);
while ((nbytes = walk.nbytes)) {
preempt_disable();
pagefault_disable();
enable_kernel_vsx();
aes_p8_cbc_encrypt(walk.src.virt.addr,
walk.dst.virt.addr,
nbytes & AES_BLOCK_MASK,
&ctx->dec_key, walk.iv, 0);
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
nbytes &= AES_BLOCK_SIZE - 1;
ret = blkcipher_walk_done(desc, &walk, nbytes);
}
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
}
return ret;

View file

@ -116,32 +116,39 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
skcipher_request_zero(req);
} else {
blkcipher_walk_init(&walk, dst, src, nbytes);
ret = blkcipher_walk_virt(desc, &walk);
preempt_disable();
pagefault_disable();
enable_kernel_vsx();
blkcipher_walk_init(&walk, dst, src, nbytes);
ret = blkcipher_walk_virt(desc, &walk);
iv = walk.iv;
memset(tweak, 0, AES_BLOCK_SIZE);
aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
while ((nbytes = walk.nbytes)) {
preempt_disable();
pagefault_disable();
enable_kernel_vsx();
if (enc)
aes_p8_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
nbytes & AES_BLOCK_MASK, &ctx->enc_key, NULL, tweak);
else
aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
nbytes &= AES_BLOCK_SIZE - 1;
ret = blkcipher_walk_done(desc, &walk, nbytes);
}
disable_kernel_vsx();
pagefault_enable();
preempt_enable();
}
return ret;
}

Some files were not shown because too many files have changed in this diff Show more