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:
commit
042c1a5a60
|
@ -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'.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
-----------
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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).
|
|
@ -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
|
||||
|
|
5
Makefile
5
Makefile
|
@ -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
0
arch/arm/boot/dts/am335x-osd3358-sm-red.dts
Executable file → Normal file
|
@ -469,6 +469,7 @@
|
|||
ti,hwmods = "rtc";
|
||||
clocks = <&clk_32768_ck>;
|
||||
clock-names = "int-clk";
|
||||
system-power-controller;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -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 = <®_lcd_3v3>;
|
||||
avdd-supply = <®_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 = <®_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>;
|
||||
|
|
|
@ -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 = <®_lcd_3v3>;
|
||||
avdd-supply = <®_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 = <®_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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue