Merge 28e7241cb8 ("Merge tag 'mips_6.11_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux") into android-mainline
Steps on the way to v6.11-rc1 Signed-off-by: Lee Jones <joneslee@google.com> Change-Id: I7e64f7c84ed94fecda8ec270c55d57eb2bc10499
This commit is contained in:
@@ -454,7 +454,7 @@ ignore-unaligned-usertrap
|
||||
|
||||
On architectures where unaligned accesses cause traps, and where this
|
||||
feature is supported (``CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN``;
|
||||
currently, ``arc`` and ``loongarch``), controls whether all
|
||||
currently, ``arc``, ``parisc`` and ``loongarch``), controls whether all
|
||||
unaligned traps are logged.
|
||||
|
||||
= =============================================================
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/fsl,imx-dma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale Direct Memory Access (DMA) Controller for i.MX
|
||||
|
||||
maintainers:
|
||||
- Animesh Agarwal <animeshagarwal28@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: dma-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx1-dma
|
||||
- fsl,imx21-dma
|
||||
- fsl,imx27-dma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: DMA complete interrupt
|
||||
- description: DMA Error interrupt
|
||||
minItems: 1
|
||||
|
||||
"#dma-cells":
|
||||
const: 1
|
||||
|
||||
dma-channels:
|
||||
const: 16
|
||||
|
||||
dma-requests:
|
||||
description: Number of DMA requests supported.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- "#dma-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
dma-controller@10001000 {
|
||||
compatible = "fsl,imx27-dma";
|
||||
reg = <0x10001000 0x1000>;
|
||||
interrupts = <32 33>;
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <16>;
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
* Freescale Direct Memory Access (DMA) Controller for i.MX
|
||||
|
||||
This document will only describe differences to the generic DMA Controller and
|
||||
DMA request bindings as described in dma/dma.txt .
|
||||
|
||||
* DMA controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "fsl,<chip>-dma". chip can be imx1, imx21 or imx27
|
||||
- reg : Should contain DMA registers location and length
|
||||
- interrupts : First item should be DMA interrupt, second one is optional and
|
||||
should contain DMA Error interrupt
|
||||
- #dma-cells : Has to be 1. imx-dma does not support anything else.
|
||||
|
||||
Optional properties:
|
||||
- dma-channels : Number of DMA channels supported. Should be 16.
|
||||
- #dma-channels : deprecated
|
||||
- dma-requests : Number of DMA requests supported.
|
||||
- #dma-requests : deprecated
|
||||
|
||||
Example:
|
||||
|
||||
dma: dma@10001000 {
|
||||
compatible = "fsl,imx27-dma";
|
||||
reg = <0x10001000 0x1000>;
|
||||
interrupts = <32 33>;
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <16>;
|
||||
};
|
||||
|
||||
|
||||
* DMA client
|
||||
|
||||
Clients have to specify the DMA requests with phandles in a list.
|
||||
|
||||
Required properties:
|
||||
- dmas: List of one or more DMA request specifiers. One DMA request specifier
|
||||
consists of a phandle to the DMA controller followed by the integer
|
||||
specifying the request line.
|
||||
- dma-names: List of string identifiers for the DMA requests. For the correct
|
||||
names, have a look at the specific client driver.
|
||||
|
||||
Example:
|
||||
|
||||
sdhci1: sdhci@10013000 {
|
||||
...
|
||||
dmas = <&dma 7>;
|
||||
dma-names = "rx-tx";
|
||||
...
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
NXP Layerscape SoC qDMA Controller
|
||||
==================================
|
||||
|
||||
This device follows the generic DMA bindings defined in dma/dma.txt.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be one of
|
||||
"fsl,ls1021a-qdma": for LS1021A Board
|
||||
"fsl,ls1028a-qdma": for LS1028A Board
|
||||
"fsl,ls1043a-qdma": for ls1043A Board
|
||||
"fsl,ls1046a-qdma": for ls1046A Board
|
||||
- reg: Should contain the register's base address and length.
|
||||
- interrupts: Should contain a reference to the interrupt used by this
|
||||
device.
|
||||
- interrupt-names: Should contain interrupt names:
|
||||
"qdma-queue0": the block0 interrupt
|
||||
"qdma-queue1": the block1 interrupt
|
||||
"qdma-queue2": the block2 interrupt
|
||||
"qdma-queue3": the block3 interrupt
|
||||
"qdma-error": the error interrupt
|
||||
- fsl,dma-queues: Should contain number of queues supported.
|
||||
- dma-channels: Number of DMA channels supported
|
||||
- block-number: the virtual block number
|
||||
- block-offset: the offset of different virtual block
|
||||
- status-sizes: status queue size of per virtual block
|
||||
- queue-sizes: command queue size of per virtual block, the size number
|
||||
based on queues
|
||||
|
||||
Optional properties:
|
||||
|
||||
- dma-channels: Number of DMA channels supported by the controller.
|
||||
- big-endian: If present registers and hardware scatter/gather descriptors
|
||||
of the qDMA are implemented in big endian mode, otherwise in little
|
||||
mode.
|
||||
|
||||
Examples:
|
||||
|
||||
qdma: dma-controller@8390000 {
|
||||
compatible = "fsl,ls1021a-qdma";
|
||||
reg = <0x0 0x8388000 0x0 0x1000>, /* Controller regs */
|
||||
<0x0 0x8389000 0x0 0x1000>, /* Status regs */
|
||||
<0x0 0x838a000 0x0 0x2000>; /* Block regs */
|
||||
interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "qdma-error",
|
||||
"qdma-queue0", "qdma-queue1";
|
||||
dma-channels = <8>;
|
||||
block-number = <2>;
|
||||
block-offset = <0x1000>;
|
||||
fsl,dma-queues = <2>;
|
||||
status-sizes = <64>;
|
||||
queue-sizes = <64 64>;
|
||||
big-endian;
|
||||
};
|
||||
|
||||
DMA clients must use the format described in dma/dma.txt file.
|
||||
@@ -0,0 +1,132 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/fsl-qdma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP Layerscape SoC qDMA Controller
|
||||
|
||||
maintainers:
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,ls1021a-qdma
|
||||
- fsl,ls1028a-qdma
|
||||
- fsl,ls1043a-qdma
|
||||
- fsl,ls1046a-qdma
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Controller regs
|
||||
- description: Status regs
|
||||
- description: Block regs
|
||||
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 5
|
||||
|
||||
interrupt-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: qdma-error
|
||||
- const: qdma-queue0
|
||||
- const: qdma-queue1
|
||||
- const: qdma-queue2
|
||||
- const: qdma-queue3
|
||||
|
||||
dma-channels:
|
||||
minimum: 1
|
||||
maximum: 64
|
||||
|
||||
fsl,dma-queues:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Should contain number of queues supported.
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
|
||||
block-number:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: the virtual block number
|
||||
|
||||
block-offset:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: the offset of different virtual block
|
||||
|
||||
status-sizes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: status queue size of per virtual block
|
||||
|
||||
queue-sizes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
command queue size of per virtual block, the size number
|
||||
based on queues
|
||||
|
||||
big-endian:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
If present registers and hardware scatter/gather descriptors
|
||||
of the qDMA are implemented in big endian mode, otherwise in little
|
||||
mode.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- fsl,dma-queues
|
||||
- block-number
|
||||
- block-offset
|
||||
- status-sizes
|
||||
- queue-sizes
|
||||
|
||||
allOf:
|
||||
- $ref: dma-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,ls1028a-qdma
|
||||
- fsl,ls1043a-qdma
|
||||
- fsl,ls1046a-qdma
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 5
|
||||
interrupt-names:
|
||||
minItems: 5
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
interrupt-names:
|
||||
maxItems: 3
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
dma-controller@8390000 {
|
||||
compatible = "fsl,ls1021a-qdma";
|
||||
reg = <0x8388000 0x1000>, /* Controller regs */
|
||||
<0x8389000 0x1000>, /* Status regs */
|
||||
<0x838a000 0x2000>; /* Block regs */
|
||||
interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "qdma-error", "qdma-queue0", "qdma-queue1";
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <8>;
|
||||
block-number = <2>;
|
||||
block-offset = <0x1000>;
|
||||
status-sizes = <64>;
|
||||
queue-sizes = <64 64>;
|
||||
big-endian;
|
||||
fsl,dma-queues = <2>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/sprd,sc9860-dma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Spreadtrum SC9860 DMA controller
|
||||
|
||||
description: |
|
||||
There are three DMA controllers: AP DMA, AON DMA and AGCP DMA. For AGCP
|
||||
DMA controller, it can or do not request the IRQ, which will save
|
||||
system power without resuming system by DMA interrupts if AGCP DMA
|
||||
does not request the IRQ.
|
||||
|
||||
maintainers:
|
||||
- Orson Zhai <orsonzhai@gmail.com>
|
||||
- Baolin Wang <baolin.wang7@gmail.com>
|
||||
- Chunyan Zhang <zhang.lyra@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sprd,sc9860-dma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: DMA enable clock
|
||||
- description: optional ashb_eb clock, only for the AGCP DMA controller
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: enable
|
||||
- const: ashb_eb
|
||||
|
||||
'#dma-cells':
|
||||
const: 1
|
||||
|
||||
dma-channels:
|
||||
const: 32
|
||||
|
||||
'#dma-channels':
|
||||
const: 32
|
||||
deprecated: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#dma-cells'
|
||||
- dma-channels
|
||||
|
||||
allOf:
|
||||
- $ref: dma-controller.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/sprd,sc9860-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
/* AP DMA controller */
|
||||
dma-controller@20100000 {
|
||||
compatible = "sprd,sc9860-dma";
|
||||
reg = <0x20100000 0x4000>;
|
||||
interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&apahb_gate CLK_DMA_EB>;
|
||||
clock-names = "enable";
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <32>;
|
||||
};
|
||||
|
||||
/* AGCP DMA controller */
|
||||
dma-controller@41580000 {
|
||||
compatible = "sprd,sc9860-dma";
|
||||
reg = <0x41580000 0x4000>;
|
||||
clocks = <&agcp_gate CLK_AGCP_DMAAP_EB>,
|
||||
<&agcp_gate CLK_AGCP_AP_ASHB_EB>;
|
||||
clock-names = "enable", "ashb_eb";
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <32>;
|
||||
};
|
||||
...
|
||||
@@ -1,44 +0,0 @@
|
||||
* Spreadtrum DMA controller
|
||||
|
||||
This binding follows the generic DMA bindings defined in dma.txt.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "sprd,sc9860-dma".
|
||||
- reg: Should contain DMA registers location and length.
|
||||
- interrupts: Should contain one interrupt shared by all channel.
|
||||
- #dma-cells: must be <1>. Used to represent the number of integer
|
||||
cells in the dmas property of client device.
|
||||
- dma-channels : Number of DMA channels supported. Should be 32.
|
||||
- clock-names: Should contain the clock of the DMA controller.
|
||||
- clocks: Should contain a clock specifier for each entry in clock-names.
|
||||
|
||||
Deprecated properties:
|
||||
- #dma-channels : Number of DMA channels supported. Should be 32.
|
||||
|
||||
Example:
|
||||
|
||||
Controller:
|
||||
apdma: dma-controller@20100000 {
|
||||
compatible = "sprd,sc9860-dma";
|
||||
reg = <0x20100000 0x4000>;
|
||||
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <32>;
|
||||
clock-names = "enable";
|
||||
clocks = <&clk_ap_ahb_gates 5>;
|
||||
};
|
||||
|
||||
|
||||
Client:
|
||||
DMA clients connected to the Spreadtrum DMA controller must use the format
|
||||
described in the dma.txt file, using a two-cell specifier for each channel.
|
||||
The two cells in order are:
|
||||
1. A phandle pointing to the DMA controller.
|
||||
2. The slave id.
|
||||
|
||||
spi0: spi@70a00000{
|
||||
...
|
||||
dma-names = "rx_chn", "tx_chn";
|
||||
dmas = <&apdma 11>, <&apdma 12>;
|
||||
...
|
||||
};
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/st,stm32-dma.yaml#
|
||||
$id: http://devicetree.org/schemas/dma/stm32/st,stm32-dma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 DMA Controller
|
||||
@@ -53,7 +53,7 @@ maintainers:
|
||||
- Amelie Delaunay <amelie.delaunay@foss.st.com>
|
||||
|
||||
allOf:
|
||||
- $ref: dma-controller.yaml#
|
||||
- $ref: /schemas/dma/dma-controller.yaml#
|
||||
|
||||
properties:
|
||||
"#dma-cells":
|
||||
@@ -0,0 +1,135 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/stm32/st,stm32-dma3.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 DMA3 Controller
|
||||
|
||||
description: |
|
||||
The STM32 DMA3 is a direct memory access controller with different features
|
||||
depending on its hardware configuration.
|
||||
It is either called LPDMA (Low Power), GPDMA (General Purpose) or HPDMA (High
|
||||
Performance).
|
||||
Its hardware configuration registers allow to dynamically expose its features.
|
||||
|
||||
GPDMA and HPDMA support 16 independent DMA channels, while only 4 for LPDMA.
|
||||
GPDMA and HPDMA support 256 DMA requests from peripherals, 8 for LPDMA.
|
||||
|
||||
Bindings are generic for these 3 STM32 DMA3 configurations.
|
||||
|
||||
DMA clients connected to the STM32 DMA3 controller must use the format
|
||||
described in "#dma-cells" property description below, using a three-cell
|
||||
specifier for each channel.
|
||||
|
||||
maintainers:
|
||||
- Amelie Delaunay <amelie.delaunay@foss.st.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/dma/dma-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32mp25-dma3
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 4
|
||||
maxItems: 16
|
||||
description:
|
||||
Should contain all of the per-channel DMA interrupts in ascending order
|
||||
with respect to the DMA channel index.
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
"#dma-cells":
|
||||
const: 3
|
||||
description: |
|
||||
Specifies the number of cells needed to provide DMA controller specific
|
||||
information.
|
||||
The first cell is the request line number.
|
||||
The second cell is a 32-bit mask specifying the DMA channel requirements:
|
||||
-bit 0-1: The priority level
|
||||
0x0: low priority, low weight
|
||||
0x1: low priority, mid weight
|
||||
0x2: low priority, high weight
|
||||
0x3: high priority
|
||||
-bit 4-7: The FIFO requirement for queuing source/destination transfers
|
||||
0x0: no FIFO requirement/any channel can fit
|
||||
0x2: FIFO of 8 bytes (2^2+1)
|
||||
0x4: FIFO of 32 bytes (2^4+1)
|
||||
0x6: FIFO of 128 bytes (2^6+1)
|
||||
0x7: FIFO of 256 bytes (2^7+1)
|
||||
The third cell is a 32-bit mask specifying the DMA transfer requirements:
|
||||
-bit 0: The source incrementing burst
|
||||
0x0: fixed burst
|
||||
0x1: contiguously incremented burst
|
||||
-bit 1: The source allocated port
|
||||
0x0: port 0 is allocated to the source transfer
|
||||
0x1: port 1 is allocated to the source transfer
|
||||
-bit 4: The destination incrementing burst
|
||||
0x0: fixed burst
|
||||
0x1: contiguously incremented burst
|
||||
-bit 5: The destination allocated port
|
||||
0x0: port 0 is allocated to the destination transfer
|
||||
0x1: port 1 is allocated to the destination transfer
|
||||
-bit 8: The type of hardware request
|
||||
0x0: burst
|
||||
0x1: block
|
||||
-bit 9: The control mode
|
||||
0x0: DMA controller control mode
|
||||
0x1: peripheral control mode
|
||||
-bit 12-13: The transfer complete event mode
|
||||
0x0: at block level, transfer complete event is generated at the end
|
||||
of a block
|
||||
0x2: at LLI level, the transfer complete event is generated at the end
|
||||
of the LLI transfer
|
||||
including the update of the LLI if any
|
||||
0x3: at channel level, the transfer complete event is generated at the
|
||||
end of the last LLI
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- "#dma-cells"
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/st,stm32mp25-rcc.h>
|
||||
dma-controller@40400000 {
|
||||
compatible = "st,stm32mp25-dma3";
|
||||
reg = <0x40400000 0x1000>;
|
||||
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc CK_BUS_HPDMA1>;
|
||||
#dma-cells = <3>;
|
||||
};
|
||||
...
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/st,stm32-dmamux.yaml#
|
||||
$id: http://devicetree.org/schemas/dma/stm32/st,stm32-dmamux.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 DMA MUX (DMA request router)
|
||||
@@ -10,7 +10,7 @@ maintainers:
|
||||
- Amelie Delaunay <amelie.delaunay@foss.st.com>
|
||||
|
||||
allOf:
|
||||
- $ref: dma-router.yaml#
|
||||
- $ref: /schemas/dma/dma-router.yaml#
|
||||
|
||||
properties:
|
||||
"#dma-cells":
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dma/st,stm32-mdma.yaml#
|
||||
$id: http://devicetree.org/schemas/dma/stm32/st,stm32-mdma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 MDMA Controller
|
||||
@@ -53,7 +53,7 @@ maintainers:
|
||||
- Amelie Delaunay <amelie.delaunay@foss.st.com>
|
||||
|
||||
allOf:
|
||||
- $ref: dma-controller.yaml#
|
||||
- $ref: /schemas/dma/dma-controller.yaml#
|
||||
|
||||
properties:
|
||||
"#dma-cells":
|
||||
@@ -0,0 +1,69 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/airoha,en7581-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Airoha EN7581 PCI-Express PHY
|
||||
|
||||
maintainers:
|
||||
- Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
description:
|
||||
The PCIe PHY supports physical layer functionality for PCIe Gen2/Gen3 port.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: airoha,en7581-pcie-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PCIE analog base address
|
||||
- description: PCIE lane0 base address
|
||||
- description: PCIE lane1 base address
|
||||
- description: PCIE lane0 detection time base address
|
||||
- description: PCIE lane1 detection time base address
|
||||
- description: PCIE Rx AEQ base address
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: csr-2l
|
||||
- const: pma0
|
||||
- const: pma1
|
||||
- const: p0-xr-dtime
|
||||
- const: p1-xr-dtime
|
||||
- const: rx-aeq
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
phy@11e80000 {
|
||||
compatible = "airoha,en7581-pcie-phy";
|
||||
#phy-cells = <0>;
|
||||
reg = <0x0 0x1fa5a000 0x0 0xfff>,
|
||||
<0x0 0x1fa5b000 0x0 0xfff>,
|
||||
<0x0 0x1fa5c000 0x0 0xfff>,
|
||||
<0x0 0x1fc10044 0x0 0x4>,
|
||||
<0x0 0x1fc30044 0x0 0x4>,
|
||||
<0x0 0x1fc15030 0x0 0x104>;
|
||||
reg-names = "csr-2l", "pma0", "pma1",
|
||||
"p0-xr-dtime", "p1-xr-dtime",
|
||||
"rx-aeq";
|
||||
};
|
||||
};
|
||||
@@ -41,6 +41,9 @@ properties:
|
||||
Phandle to a regulator that provides power to the PHY. This
|
||||
regulator will be managed during the PHY power on/off sequence.
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/fsl,imx8qm-hsio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8QM SoC series High Speed IO(HSIO) SERDES PHY
|
||||
|
||||
maintainers:
|
||||
- Richard Zhu <hongxing.zhu@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8qm-hsio
|
||||
- fsl,imx8qxp-hsio
|
||||
reg:
|
||||
items:
|
||||
- description: Base address and length of the PHY block
|
||||
- description: HSIO control and status registers(CSR) of the PHY
|
||||
- description: HSIO CSR of the controller bound to the PHY
|
||||
- description: HSIO CSR for MISC
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: reg
|
||||
- const: phy
|
||||
- const: ctrl
|
||||
- const: misc
|
||||
|
||||
"#phy-cells":
|
||||
const: 3
|
||||
description:
|
||||
The first defines lane index.
|
||||
The second defines the type of the PHY refer to the include phy.h.
|
||||
The third defines the controller index, indicated which controller
|
||||
is bound to the lane.
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
maxItems: 14
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
maxItems: 14
|
||||
|
||||
fsl,hsio-cfg:
|
||||
description: |
|
||||
Specifies the use case of the HSIO module in the hardware design.
|
||||
Regarding the design of i.MX8QM HSIO subsystem, HSIO module can be
|
||||
confiured as following three use cases.
|
||||
+---------------------------------------+
|
||||
| | i.MX8QM |
|
||||
|------------------|--------------------|
|
||||
| | Lane0| Lane1| Lane2|
|
||||
|------------------|------|------|------|
|
||||
| pciea-x2-sata | PCIEA| PCIEA| SATA |
|
||||
|------------------|------|------|------|
|
||||
| pciea-x2-pcieb | PCIEA| PCIEA| PCIEB|
|
||||
|------------------|------|------|------|
|
||||
| pciea-pcieb-sata | PCIEA| PCIEB| SATA |
|
||||
+---------------------------------------+
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [ pciea-x2-sata, pciea-x2-pcieb, pciea-pcieb-sata]
|
||||
default: pciea-pcieb-sata
|
||||
|
||||
fsl,refclk-pad-mode:
|
||||
description:
|
||||
Specifies the mode of the refclk pad used. INPUT(PHY refclock is
|
||||
provided externally via the refclk pad) or OUTPUT(PHY refclock is
|
||||
derived from SoC internal source and provided on the refclk pad).
|
||||
This property not exists means unused(PHY refclock is derived from
|
||||
SoC internal source).
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [ input, output, unused ]
|
||||
default: unused
|
||||
|
||||
power-domains:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- "#phy-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- fsl,hsio-cfg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx8qxp-hsio
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk0
|
||||
- const: apb_pclk0
|
||||
- const: phy0_crr
|
||||
- const: ctl0_crr
|
||||
- const: misc_crr
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx8qm-hsio
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk0
|
||||
- const: pclk1
|
||||
- const: apb_pclk0
|
||||
- const: apb_pclk1
|
||||
- const: pclk2
|
||||
- const: epcs_tx
|
||||
- const: epcs_rx
|
||||
- const: apb_pclk2
|
||||
- const: phy0_crr
|
||||
- const: phy1_crr
|
||||
- const: ctl0_crr
|
||||
- const: ctl1_crr
|
||||
- const: ctl2_crr
|
||||
- const: misc_crr
|
||||
power-domains:
|
||||
minItems: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx8-clock.h>
|
||||
#include <dt-bindings/clock/imx8-lpcg.h>
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
#include <dt-bindings/phy/phy-imx8-pcie.h>
|
||||
|
||||
phy@5f1a0000 {
|
||||
compatible = "fsl,imx8qxp-hsio";
|
||||
reg = <0x5f1a0000 0x10000>,
|
||||
<0x5f120000 0x10000>,
|
||||
<0x5f140000 0x10000>,
|
||||
<0x5f160000 0x10000>;
|
||||
reg-names = "reg", "phy", "ctrl", "misc";
|
||||
clocks = <&phyx1_lpcg IMX_LPCG_CLK_0>,
|
||||
<&phyx1_lpcg IMX_LPCG_CLK_4>,
|
||||
<&phyx1_crr1_lpcg IMX_LPCG_CLK_4>,
|
||||
<&pcieb_crr3_lpcg IMX_LPCG_CLK_4>,
|
||||
<&misc_crr5_lpcg IMX_LPCG_CLK_4>;
|
||||
clock-names = "pclk0", "apb_pclk0", "phy0_crr", "ctl0_crr", "misc_crr";
|
||||
power-domains = <&pd IMX_SC_R_SERDES_1>;
|
||||
#phy-cells = <3>;
|
||||
fsl,hsio-cfg = "pciea-pcieb-sata";
|
||||
fsl,refclk-pad-mode = "input";
|
||||
};
|
||||
...
|
||||
@@ -41,6 +41,12 @@ properties:
|
||||
Phandle to the system controller node
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
swap-dx-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: |
|
||||
Specifies the ports which will swap the differential-pair (D+/D-),
|
||||
default is not-swapped.
|
||||
|
||||
# Required child nodes:
|
||||
|
||||
patternProperties:
|
||||
|
||||
@@ -19,6 +19,8 @@ properties:
|
||||
- qcom,ipq6018-qmp-pcie-phy
|
||||
- qcom,ipq8074-qmp-gen3-pcie-phy
|
||||
- qcom,ipq8074-qmp-pcie-phy
|
||||
- qcom,ipq9574-qmp-gen3x1-pcie-phy
|
||||
- qcom,ipq9574-qmp-gen3x2-pcie-phy
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
||||
@@ -91,8 +91,7 @@ properties:
|
||||
"#clock-cells": true
|
||||
|
||||
clock-output-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
@@ -222,14 +221,10 @@ allOf:
|
||||
- qcom,sm8650-qmp-gen4x2-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
clock-output-names:
|
||||
minItems: 2
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
else:
|
||||
properties:
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
|
||||
@@ -20,8 +20,9 @@ properties:
|
||||
- qcom,ipq8074-qmp-usb3-phy
|
||||
- qcom,ipq9574-qmp-usb3-phy
|
||||
- qcom,msm8996-qmp-usb3-phy
|
||||
- com,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sdm845-qmp-usb3-uni-phy
|
||||
- qcom,sdx55-qmp-usb3-uni-phy
|
||||
@@ -112,6 +113,7 @@ allOf:
|
||||
enum:
|
||||
- qcom,qdu1000-qmp-usb3-uni-phy
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sm8150-qmp-usb3-uni-phy
|
||||
- qcom,sm8250-qmp-usb3-uni-phy
|
||||
@@ -152,6 +154,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-qmp-usb3-uni-phy
|
||||
- qcom,sc8180x-qmp-usb3-uni-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,x1e80100-qmp-usb3-uni-phy
|
||||
then:
|
||||
|
||||
@@ -15,6 +15,7 @@ if:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,usb-hs-phy-apq8064
|
||||
- qcom,usb-hs-phy-msm8660
|
||||
- qcom,usb-hs-phy-msm8960
|
||||
then:
|
||||
properties:
|
||||
@@ -41,6 +42,7 @@ properties:
|
||||
- enum:
|
||||
- qcom,usb-hs-phy-apq8064
|
||||
- qcom,usb-hs-phy-msm8226
|
||||
- qcom,usb-hs-phy-msm8660
|
||||
- qcom,usb-hs-phy-msm8916
|
||||
- qcom,usb-hs-phy-msm8960
|
||||
- qcom,usb-hs-phy-msm8974
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/rockchip,rk3399-emmc-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip EMMC PHY
|
||||
|
||||
maintainers:
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: rockchip,rk3399-emmc-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: emmcclk
|
||||
|
||||
drive-impedance-ohm:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Specifies the drive impedance in Ohm.
|
||||
enum: [33, 40, 50, 66, 100]
|
||||
default: 50
|
||||
|
||||
rockchip,enable-strobe-pulldown:
|
||||
type: boolean
|
||||
description: |
|
||||
Enable internal pull-down for the strobe
|
||||
line. If not set, pull-down is not used.
|
||||
|
||||
rockchip,output-tapdelay-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Specifies the phyctrl_otapdlysec register.
|
||||
default: 0x4
|
||||
maximum: 0xf
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@f780 {
|
||||
compatible = "rockchip,rk3399-emmc-phy";
|
||||
reg = <0xf780 0x20>;
|
||||
clocks = <&sdhci>;
|
||||
clock-names = "emmcclk";
|
||||
drive-impedance-ohm = <50>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
Rockchip EMMC PHY
|
||||
-----------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: rockchip,rk3399-emmc-phy
|
||||
- #phy-cells: must be 0
|
||||
- reg: PHY register address offset and length in "general
|
||||
register files"
|
||||
|
||||
Optional properties:
|
||||
- clock-names: Should contain "emmcclk". Although this is listed as optional
|
||||
(because most boards can get basic functionality without having
|
||||
access to it), it is strongly suggested.
|
||||
See ../clock/clock-bindings.txt for details.
|
||||
- clocks: Should have a phandle to the card clock exported by the SDHCI driver.
|
||||
- drive-impedance-ohm: Specifies the drive impedance in Ohm.
|
||||
Possible values are 33, 40, 50, 66 and 100.
|
||||
If not set, the default value of 50 will be applied.
|
||||
- rockchip,enable-strobe-pulldown: Enable internal pull-down for the strobe
|
||||
line. If not set, pull-down is not used.
|
||||
- rockchip,output-tapdelay-select: Specifies the phyctrl_otapdlysec register.
|
||||
If not set, the register defaults to 0x4.
|
||||
Maximum value 0xf.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
grf: syscon@ff770000 {
|
||||
compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
...
|
||||
|
||||
emmcphy: phy@f780 {
|
||||
compatible = "rockchip,rk3399-emmc-phy";
|
||||
reg = <0xf780 0x20>;
|
||||
clocks = <&sdhci>;
|
||||
clock-names = "emmcclk";
|
||||
drive-impedance-ohm = <50>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
@@ -25,6 +25,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- google,gs101-usb31drd-phy
|
||||
- samsung,exynos5250-usbdrd-phy
|
||||
- samsung,exynos5420-usbdrd-phy
|
||||
- samsung,exynos5433-usbdrd-phy
|
||||
@@ -57,7 +58,15 @@ properties:
|
||||
the OF graph bindings specified.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: phy
|
||||
- const: pcs
|
||||
- const: pma
|
||||
|
||||
samsung,pmu-syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
@@ -72,6 +81,19 @@ properties:
|
||||
description:
|
||||
VBUS Boost 5V power source.
|
||||
|
||||
pll-supply:
|
||||
description: Power supply for the USB PLL.
|
||||
dvdd-usb20-supply:
|
||||
description: DVDD power supply for the USB 2.0 phy.
|
||||
vddh-usb20-supply:
|
||||
description: VDDh power supply for the USB 2.0 phy.
|
||||
vdd33-usb20-supply:
|
||||
description: 3.3V power supply for the USB 2.0 phy.
|
||||
vdda-usbdp-supply:
|
||||
description: VDDa power supply for the USB DP phy.
|
||||
vddh-usbdp-supply:
|
||||
description: VDDh power supply for the USB DP phy.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
@@ -81,6 +103,40 @@ required:
|
||||
- samsung,pmu-syscon
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: google,gs101-usb31drd-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Gate of main PHY clock
|
||||
- description: Gate of PHY reference clock
|
||||
- description: Gate of control interface AXI clock
|
||||
- description: Gate of control interface APB clock
|
||||
- description: Gate of SCL APB clock
|
||||
clock-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: ref
|
||||
- const: ctrl_aclk
|
||||
- const: ctrl_pclk
|
||||
- const: scl_pclk
|
||||
reg:
|
||||
minItems: 3
|
||||
reg-names:
|
||||
minItems: 3
|
||||
required:
|
||||
- reg-names
|
||||
- pll-supply
|
||||
- dvdd-usb20-supply
|
||||
- vddh-usb20-supply
|
||||
- vdd33-usb20-supply
|
||||
- vdda-usbdp-supply
|
||||
- vddh-usbdp-supply
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@@ -100,7 +156,20 @@ allOf:
|
||||
- const: phy_utmi
|
||||
- const: phy_pipe
|
||||
- const: itp
|
||||
else:
|
||||
reg:
|
||||
maxItems: 1
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,exynos5250-usbdrd-phy
|
||||
- samsung,exynos5420-usbdrd-phy
|
||||
- samsung,exynos850-usbdrd-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
@@ -109,6 +178,10 @@ allOf:
|
||||
items:
|
||||
- const: phy
|
||||
- const: ref
|
||||
reg:
|
||||
maxItems: 1
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/starfive,jh7110-dphy-tx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Starfive SoC MIPI D-PHY Tx Controller
|
||||
|
||||
maintainers:
|
||||
- Keith Zhao <keith.zhao@starfivetech.com>
|
||||
- Shengyang Chen <shengyang.chen@starfivetech.com>
|
||||
|
||||
description:
|
||||
The Starfive SoC uses the MIPI DSI D-PHY based on M31 IP to transfer
|
||||
DSI data.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: starfive,jh7110-dphy-tx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: txesc
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MIPITX_DPHY_SYS reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: sys
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
phy@295e0000 {
|
||||
compatible = "starfive,jh7110-dphy-tx";
|
||||
reg = <0x295e0000 0x10000>;
|
||||
clocks = <&voutcrg 14>;
|
||||
clock-names = "txesc";
|
||||
resets = <&syscrg 10>;
|
||||
reset-names = "sys";
|
||||
power-domains = <&aon_syscon 0>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
@@ -176,9 +176,10 @@ allOf:
|
||||
Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt
|
||||
|
||||
patternProperties:
|
||||
"phy@[0-9a-f]+$":
|
||||
description:
|
||||
Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/phy/rockchip,rk3399-emmc-phy.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -292,6 +293,15 @@ examples:
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
phy@f780 {
|
||||
compatible = "rockchip,rk3399-emmc-phy";
|
||||
reg = <0xf780 0x20>;
|
||||
clocks = <&sdhci>;
|
||||
clock-names = "emmcclk";
|
||||
drive-impedance-ohm = <50>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
u2phy0: usb2phy@e450 {
|
||||
compatible = "rockchip,rk3399-usb2phy";
|
||||
reg = <0xe450 0x10>;
|
||||
|
||||
@@ -42,7 +42,7 @@ properties:
|
||||
dmas:
|
||||
description: |
|
||||
DMA specifiers for tx and rx dma. DMA fifo mode must be used. See
|
||||
the STM32 DMA bindings Documentation/devicetree/bindings/dma/st,stm32-dma.yaml.
|
||||
the STM32 DMA controllers bindings Documentation/devicetree/bindings/dma/stm32/*.yaml.
|
||||
items:
|
||||
- description: rx DMA channel
|
||||
- description: tx DMA channel
|
||||
|
||||
@@ -28,7 +28,7 @@ properties:
|
||||
Add this property to disable the watchdog during suspend.
|
||||
Only use this option if you can't use the watchdog automatic suspend
|
||||
function during a suspend (see register CONTROL_B).
|
||||
|
||||
|
||||
dlg,wdt-sd:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
|
||||
@@ -29,6 +29,7 @@ properties:
|
||||
- renesas,r9a07g043-wdt # RZ/G2UL and RZ/Five
|
||||
- renesas,r9a07g044-wdt # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-wdt # RZ/V2L
|
||||
- renesas,r9a08g045-wdt # RZ/G3S
|
||||
- const: renesas,rzg2l-wdt
|
||||
|
||||
- items:
|
||||
|
||||
@@ -18,7 +18,7 @@ Architecture Level of support Constraints
|
||||
``arm64`` Maintained Little Endian only.
|
||||
``loongarch`` Maintained \-
|
||||
``riscv`` Maintained ``riscv64`` only.
|
||||
``um`` Maintained ``x86_64`` only.
|
||||
``um`` Maintained \-
|
||||
``x86`` Maintained ``x86_64`` only.
|
||||
============= ================ ==============================================
|
||||
|
||||
|
||||
@@ -223,8 +223,6 @@ remote UML and other VM instances.
|
||||
+-----------+--------+------------------------------------+------------+
|
||||
| socket | legacy | none | ~ 450Mbit |
|
||||
+-----------+--------+------------------------------------+------------+
|
||||
| pcap | legacy | rx only | ~ 450Mbit |
|
||||
+-----------+--------+------------------------------------+------------+
|
||||
| ethertap | legacy | obsolete | ~ 500Mbit |
|
||||
+-----------+--------+------------------------------------+------------+
|
||||
| vde | legacy | obsolete | ~ 500Mbit |
|
||||
|
||||
+33
@@ -702,6 +702,14 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
|
||||
F: drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
|
||||
AIROHA PCIE PHY DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml
|
||||
F: drivers/phy/phy-airoha-pcie-regs.h
|
||||
F: drivers/phy/phy-airoha-pcie.c
|
||||
|
||||
AIROHA SPI SNFI DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
M: Ray Liu <ray.liu@airoha.com>
|
||||
@@ -6842,6 +6850,7 @@ F: include/linux/fwnode.h
|
||||
F: include/linux/kobj*
|
||||
F: include/linux/property.h
|
||||
F: lib/kobj*
|
||||
F: rust/kernel/device.rs
|
||||
|
||||
DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS)
|
||||
M: Nishanth Menon <nm@ti.com>
|
||||
@@ -8708,10 +8717,12 @@ F: include/linux/arm_ffa.h
|
||||
FIRMWARE LOADER (request_firmware)
|
||||
M: Luis Chamberlain <mcgrof@kernel.org>
|
||||
M: Russ Weight <russ.weight@linux.dev>
|
||||
M: Danilo Krummrich <dakr@redhat.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/firmware_class/
|
||||
F: drivers/base/firmware_loader/
|
||||
F: rust/kernel/firmware.rs
|
||||
F: include/linux/firmware.h
|
||||
|
||||
FLEXTIMER FTM-QUADDEC DRIVER
|
||||
@@ -19064,7 +19075,13 @@ S: Maintained
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git
|
||||
F: Documentation/devicetree/bindings/rng/microsoft,vmgenid.yaml
|
||||
F: drivers/char/random.c
|
||||
F: include/linux/random.h
|
||||
F: include/uapi/linux/random.h
|
||||
F: drivers/virt/vmgenid.c
|
||||
F: include/vdso/getrandom.h
|
||||
F: lib/vdso/getrandom.c
|
||||
F: arch/x86/entry/vdso/vgetrandom*
|
||||
F: arch/x86/include/asm/vdso/getrandom*
|
||||
|
||||
RAPIDIO SUBSYSTEM
|
||||
M: Matt Porter <mporter@kernel.crashing.org>
|
||||
@@ -21683,6 +21700,13 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
|
||||
F: drivers/phy/starfive/phy-jh7110-dphy-rx.c
|
||||
|
||||
STARFIVE JH7110 DPHY TX DRIVER
|
||||
M: Keith Zhao <keith.zhao@starfivetech.com>
|
||||
M: Shengyang Chen <shengyang.chen@starfivetech.com>
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-tx.yaml
|
||||
F: drivers/phy/starfive/phy-jh7110-dphy-tx.c
|
||||
|
||||
STARFIVE JH7110 MMC/SD/SDIO DRIVER
|
||||
M: William Qiu <william.qiu@starfivetech.com>
|
||||
S: Supported
|
||||
@@ -21840,6 +21864,15 @@ F: Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml
|
||||
F: Documentation/devicetree/bindings/sound/st,stm32-*.yaml
|
||||
F: sound/soc/stm/
|
||||
|
||||
STM32 DMA DRIVERS
|
||||
M: Amélie Delaunay <amelie.delaunay@foss.st.com>
|
||||
L: dmaengine@vger.kernel.org
|
||||
L: linux-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/arch/arm/stm32/stm32-dma-mdma-chaining.rst
|
||||
F: Documentation/devicetree/bindings/dma/stm32/
|
||||
F: drivers/dma/stm32/
|
||||
|
||||
STM32 TIMER/LPTIMER DRIVERS
|
||||
M: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
|
||||
S: Maintained
|
||||
|
||||
@@ -816,10 +816,10 @@ EXPORT_SYMBOL(locomo_frontlight_set);
|
||||
* We model this as a regular bus type, and hang devices directly
|
||||
* off this.
|
||||
*/
|
||||
static int locomo_match(struct device *_dev, struct device_driver *_drv)
|
||||
static int locomo_match(struct device *_dev, const struct device_driver *_drv)
|
||||
{
|
||||
struct locomo_dev *dev = LOCOMO_DEV(_dev);
|
||||
struct locomo_driver *drv = LOCOMO_DRV(_drv);
|
||||
const struct locomo_driver *drv = LOCOMO_DRV(_drv);
|
||||
|
||||
return dev->devid == drv->devid;
|
||||
}
|
||||
|
||||
@@ -1339,10 +1339,10 @@ EXPORT_SYMBOL_GPL(sa1111_get_irq);
|
||||
* We model this as a regular bus type, and hang devices directly
|
||||
* off this.
|
||||
*/
|
||||
static int sa1111_match(struct device *_dev, struct device_driver *_drv)
|
||||
static int sa1111_match(struct device *_dev, const struct device_driver *_drv)
|
||||
{
|
||||
struct sa1111_dev *dev = to_sa1111_device(_dev);
|
||||
struct sa1111_driver *drv = SA1111_DRV(_drv);
|
||||
const struct sa1111_driver *drv = SA1111_DRV(_drv);
|
||||
|
||||
return !!(dev->devid & drv->devid);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ struct locomo_driver {
|
||||
void (*remove)(struct locomo_dev *);
|
||||
};
|
||||
|
||||
#define LOCOMO_DRV(_d) container_of((_d), struct locomo_driver, drv)
|
||||
#define LOCOMO_DRV(_d) container_of_const((_d), struct locomo_driver, drv)
|
||||
|
||||
#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name)
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ struct sa1111_driver {
|
||||
void (*remove)(struct sa1111_dev *);
|
||||
};
|
||||
|
||||
#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
|
||||
#define SA1111_DRV(_d) container_of_const((_d), struct sa1111_driver, drv)
|
||||
|
||||
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
|
||||
|
||||
|
||||
@@ -478,6 +478,7 @@ config MACH_LOONGSON64
|
||||
select BOARD_SCACHE
|
||||
select CSRC_R4K
|
||||
select CEVT_R4K
|
||||
select SYNC_R4K
|
||||
select FORCE_PCI
|
||||
select ISA
|
||||
select I8259
|
||||
|
||||
@@ -240,6 +240,10 @@ GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
|
||||
GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
|
||||
#define CM_GCR_CPC_STATUS_EX BIT(0)
|
||||
|
||||
/* GCR_ACCESS - Controls core/IOCU access to GCRs */
|
||||
GCR_ACCESSOR_RW(32, 0x120, access_cm3)
|
||||
#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0)
|
||||
|
||||
/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
|
||||
GCR_ACCESSOR_RW(32, 0x130, l2_config)
|
||||
#define CM_GCR_L2_CONFIG_BYPASS BIT(20)
|
||||
|
||||
@@ -50,7 +50,6 @@ extern int __cpu_logical_map[NR_CPUS];
|
||||
#define SMP_CALL_FUNCTION 0x2
|
||||
/* Octeon - Tell another core to flush its icache */
|
||||
#define SMP_ICACHE_FLUSH 0x4
|
||||
#define SMP_ASK_C0COUNT 0x8
|
||||
|
||||
/* Mask of CPUs which are currently definitely operating coherently */
|
||||
extern cpumask_t cpu_coherent_mask;
|
||||
|
||||
@@ -317,7 +317,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
|
||||
write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
|
||||
|
||||
/* Ensure the core can access the GCRs */
|
||||
set_gcr_access(1 << core);
|
||||
if (mips_cm_revision() < CM_REV_CM3)
|
||||
set_gcr_access(1 << core);
|
||||
else
|
||||
set_gcr_access_cm3(1 << core);
|
||||
|
||||
if (mips_cpc_present()) {
|
||||
/* Reset the core */
|
||||
|
||||
@@ -33,7 +33,6 @@ static void __iomem *ipi_clear0_regs[16];
|
||||
static void __iomem *ipi_status0_regs[16];
|
||||
static void __iomem *ipi_en0_regs[16];
|
||||
static void __iomem *ipi_mailbox_buf[16];
|
||||
static uint32_t core0_c0count[NR_CPUS];
|
||||
|
||||
static u32 (*ipi_read_clear)(int cpu);
|
||||
static void (*ipi_write_action)(int cpu, u32 action);
|
||||
@@ -382,11 +381,10 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
|
||||
ipi_write_action(cpu_logical_map(i), (u32)action);
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
int i, cpu = smp_processor_id();
|
||||
unsigned int action, c0count;
|
||||
int cpu = smp_processor_id();
|
||||
unsigned int action;
|
||||
|
||||
action = ipi_read_clear(cpu);
|
||||
|
||||
@@ -399,26 +397,14 @@ static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
if (action & SMP_ASK_C0COUNT) {
|
||||
BUG_ON(cpu != 0);
|
||||
c0count = read_c0_count();
|
||||
c0count = c0count ? c0count : 1;
|
||||
for (i = 1; i < nr_cpu_ids; i++)
|
||||
core0_c0count[i] = c0count;
|
||||
nudge_writes(); /* Let others see the result ASAP */
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#define MAX_LOOPS 800
|
||||
/*
|
||||
* SMP init and finish on secondary CPUs
|
||||
*/
|
||||
static void loongson3_init_secondary(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t initcount;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
unsigned int imask = STATUSF_IP7 | STATUSF_IP6 |
|
||||
STATUSF_IP3 | STATUSF_IP2;
|
||||
@@ -432,23 +418,6 @@ static void loongson3_init_secondary(void)
|
||||
cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
|
||||
cpu_data[cpu].package =
|
||||
cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
|
||||
|
||||
i = 0;
|
||||
core0_c0count[cpu] = 0;
|
||||
loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
|
||||
while (!core0_c0count[cpu]) {
|
||||
i++;
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
if (i > MAX_LOOPS)
|
||||
i = MAX_LOOPS;
|
||||
if (cpu_data[cpu].package)
|
||||
initcount = core0_c0count[cpu] + i;
|
||||
else /* Local access is faster for loops */
|
||||
initcount = core0_c0count[cpu] + i/2;
|
||||
|
||||
write_c0_count(initcount);
|
||||
}
|
||||
|
||||
static void loongson3_smp_finish(void)
|
||||
|
||||
@@ -589,4 +589,5 @@ module_exit(sbprof_tb_cleanup);
|
||||
|
||||
MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR);
|
||||
MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
|
||||
MODULE_DESCRIPTION("Support for ZBbus profiling");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -46,6 +46,7 @@ config PARISC
|
||||
select GENERIC_CPU_DEVICES if !SMP
|
||||
select GENERIC_LIB_DEVMEM_IS_ALLOWED
|
||||
select SYSCTL_ARCH_UNALIGN_ALLOW
|
||||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select MODULES_USE_ELF_RELA
|
||||
@@ -86,6 +87,7 @@ config PARISC
|
||||
select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
select HAVE_FUNCTION_DESCRIPTORS if 64BIT
|
||||
select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
|
||||
|
||||
help
|
||||
The PA-RISC microprocessor is designed by Hewlett-Packard and used
|
||||
|
||||
@@ -41,7 +41,7 @@ struct parisc_driver {
|
||||
|
||||
|
||||
#define to_parisc_device(d) container_of(d, struct parisc_device, dev)
|
||||
#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv)
|
||||
#define to_parisc_driver(d) container_of_const(d, struct parisc_driver, drv)
|
||||
#define parisc_parent(d) to_parisc_device(d->dev.parent)
|
||||
|
||||
static inline const char *parisc_pathname(struct parisc_device *d)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* sysdeps/unix/sysv/linux/hppa/sysdep.h
|
||||
*/
|
||||
|
||||
#ifdef PIC
|
||||
#ifndef DONT_USE_PIC
|
||||
/* WARNING: CANNOT BE USED IN A NOP! */
|
||||
# define K_STW_ASM_PIC " copy %%r19, %%r4\n"
|
||||
# define K_LDW_ASM_PIC " copy %%r4, %%r19\n"
|
||||
@@ -43,7 +43,7 @@
|
||||
across the syscall. */
|
||||
|
||||
#define K_CALL_CLOB_REGS "%r1", "%r2", K_USING_GR4 \
|
||||
"%r20", "%r29", "%r31"
|
||||
"%r20", "%r29", "%r31"
|
||||
|
||||
#undef K_INLINE_SYSCALL
|
||||
#define K_INLINE_SYSCALL(name, nr, args...) ({ \
|
||||
@@ -58,7 +58,7 @@
|
||||
" ldi %1, %%r20\n" \
|
||||
K_LDW_ASM_PIC \
|
||||
: "=r" (__res) \
|
||||
: "i" (SYS_ify(name)) K_ASM_ARGS_##nr \
|
||||
: "i" (name) K_ASM_ARGS_##nr \
|
||||
: "memory", K_CALL_CLOB_REGS K_CLOB_ARGS_##nr \
|
||||
); \
|
||||
__sys_res = (long)__res; \
|
||||
@@ -104,42 +104,18 @@
|
||||
#define K_CLOB_ARGS_1 K_CLOB_ARGS_2, "%r25"
|
||||
#define K_CLOB_ARGS_0 K_CLOB_ARGS_1, "%r26"
|
||||
|
||||
#define _syscall0(type,name) \
|
||||
type name(void) \
|
||||
{ \
|
||||
return K_INLINE_SYSCALL(name, 0); \
|
||||
}
|
||||
|
||||
#define _syscall1(type,name,type1,arg1) \
|
||||
type name(type1 arg1) \
|
||||
{ \
|
||||
return K_INLINE_SYSCALL(name, 1, arg1); \
|
||||
}
|
||||
|
||||
#define _syscall2(type,name,type1,arg1,type2,arg2) \
|
||||
type name(type1 arg1, type2 arg2) \
|
||||
{ \
|
||||
return K_INLINE_SYSCALL(name, 2, arg1, arg2); \
|
||||
}
|
||||
|
||||
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
|
||||
type name(type1 arg1, type2 arg2, type3 arg3) \
|
||||
{ \
|
||||
return K_INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
|
||||
}
|
||||
|
||||
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
|
||||
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
|
||||
{ \
|
||||
return K_INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
|
||||
}
|
||||
|
||||
/* select takes 5 arguments */
|
||||
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
|
||||
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
|
||||
{ \
|
||||
return K_INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
|
||||
}
|
||||
#define syscall0(name) \
|
||||
K_INLINE_SYSCALL(name, 0)
|
||||
#define syscall1(name, arg1) \
|
||||
K_INLINE_SYSCALL(name, 1, arg1)
|
||||
#define syscall2(name, arg1, arg2) \
|
||||
K_INLINE_SYSCALL(name, 2, arg1, arg2)
|
||||
#define syscall3(name, arg1, arg2, arg3) \
|
||||
K_INLINE_SYSCALL(name, 3, arg1, arg2, arg3)
|
||||
#define syscall4(name, arg1, arg2, arg3, arg4) \
|
||||
K_INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)
|
||||
#define syscall5(name, arg1, arg2, arg3, arg4, arg5) \
|
||||
K_INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)
|
||||
|
||||
#define __ARCH_WANT_NEW_STAT
|
||||
#define __ARCH_WANT_STAT64
|
||||
|
||||
@@ -19,6 +19,6 @@ extern struct vdso_data *vdso_data;
|
||||
/* Default link addresses for the vDSOs */
|
||||
#define VDSO_LBASE 0
|
||||
|
||||
#define VDSO_VERSION_STRING LINUX_5.18
|
||||
#define VDSO_VERSION_STRING LINUX_6.11
|
||||
|
||||
#endif /* __PARISC_VDSO_H__ */
|
||||
|
||||
@@ -611,11 +611,7 @@ void __init parisc_setup_cache_timing(void)
|
||||
threshold/1024);
|
||||
|
||||
set_tlb_threshold:
|
||||
if (threshold > FLUSH_TLB_THRESHOLD)
|
||||
parisc_tlb_flush_threshold = threshold;
|
||||
else
|
||||
parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD;
|
||||
|
||||
parisc_tlb_flush_threshold = max(threshold, FLUSH_TLB_THRESHOLD);
|
||||
printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
|
||||
parisc_tlb_flush_threshold/1024);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ static int for_each_padev(int (*fn)(struct device *, void *), void * data)
|
||||
* @driver: the PA-RISC driver to try
|
||||
* @dev: the PA-RISC device to try
|
||||
*/
|
||||
static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
|
||||
static int match_device(const struct parisc_driver *driver, struct parisc_device *dev)
|
||||
{
|
||||
const struct parisc_device_id *ids;
|
||||
|
||||
@@ -548,7 +548,7 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
|
||||
return dev;
|
||||
}
|
||||
|
||||
static int parisc_generic_match(struct device *dev, struct device_driver *drv)
|
||||
static int parisc_generic_match(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
return match_device(to_parisc_driver(drv), to_parisc_device(dev));
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
#define ERR_NOTHANDLED -1
|
||||
|
||||
int unaligned_enabled __read_mostly = 1;
|
||||
int no_unaligned_warning __read_mostly;
|
||||
|
||||
static int emulate_ldh(struct pt_regs *regs, int toreg)
|
||||
{
|
||||
@@ -399,6 +400,7 @@ void handle_unaligned(struct pt_regs *regs)
|
||||
} else {
|
||||
static DEFINE_RATELIMIT_STATE(kernel_ratelimit, 5 * HZ, 5);
|
||||
if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
|
||||
!no_unaligned_warning &&
|
||||
__ratelimit(&kernel_ratelimit))
|
||||
pr_warn("Kernel: unaligned access to " RFMT " in %pS "
|
||||
"(iir " RFMT ")\n",
|
||||
|
||||
@@ -1,11 +1,25 @@
|
||||
# List of files in the vdso, has to be asm only for now
|
||||
# Include the generic Makefile to check the built vdso.
|
||||
include $(srctree)/lib/vdso/Makefile
|
||||
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
# Disable gcov profiling, ubsan and kasan for VDSO code
|
||||
GCOV_PROFILE := n
|
||||
UBSAN_SANITIZE := n
|
||||
KASAN_SANITIZE := n
|
||||
KCSAN_SANITIZE := n
|
||||
|
||||
obj-vdso32 = note.o sigtramp.o restart_syscall.o
|
||||
obj-cvdso32 = vdso32_generic.o
|
||||
|
||||
# Build rules
|
||||
|
||||
targets := $(obj-vdso32) vdso32.so
|
||||
targets := $(obj-vdso32) $(obj-cvdso32) vdso32.so
|
||||
obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
|
||||
obj-cvdso32 := $(addprefix $(obj)/, $(obj-cvdso32))
|
||||
|
||||
VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_vdso32_generic.o = $(VDSO_CFLAGS_REMOVE)
|
||||
|
||||
ccflags-y := -shared -fno-common -fbuiltin -mno-fast-indirect-calls -O2 -mno-long-calls
|
||||
# -march=1.1 -mschedule=7100LC
|
||||
@@ -26,18 +40,22 @@ $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so FORCE
|
||||
|
||||
# Force dependency (incbin is bad)
|
||||
# link rule for the .so file, .lds has to be first
|
||||
$(obj)/vdso32.so: $(obj)/vdso32.lds $(obj-vdso32) $(VDSO_LIBGCC) FORCE
|
||||
$(obj)/vdso32.so: $(obj)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) FORCE
|
||||
$(call if_changed,vdso32ld)
|
||||
|
||||
# assembly rules for the .S files
|
||||
$(obj-vdso32): %.o: %.S FORCE
|
||||
$(call if_changed_dep,vdso32as)
|
||||
$(obj-cvdso32): %.o: %.c FORCE
|
||||
$(call if_changed_dep,vdso32cc)
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso32ld = VDSO32L $@
|
||||
cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
|
||||
quiet_cmd_vdso32as = VDSO32A $@
|
||||
cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
|
||||
quiet_cmd_vdso32cc = VDSO32C $@
|
||||
cmd_vdso32cc = $(CROSS32CC) $(c_flags) -c -o $@ $<
|
||||
|
||||
# Generate VDSO offsets using helper script
|
||||
gen-vdsosym := $(src)/gen_vdso_offsets.sh
|
||||
|
||||
@@ -106,6 +106,9 @@ VERSION
|
||||
global:
|
||||
__kernel_sigtramp_rt32;
|
||||
__kernel_restart_syscall32;
|
||||
__vdso_gettimeofday;
|
||||
__vdso_clock_gettime;
|
||||
__vdso_clock_gettime64;
|
||||
local: *;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include "asm/unistd.h"
|
||||
#include <linux/types.h>
|
||||
#include <uapi/asm/unistd_32.h>
|
||||
|
||||
struct timezone;
|
||||
struct old_timespec32;
|
||||
struct __kernel_timespec;
|
||||
struct __kernel_old_timeval;
|
||||
|
||||
/* forward declarations */
|
||||
int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
|
||||
int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts);
|
||||
int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts);
|
||||
|
||||
|
||||
int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
|
||||
struct timezone *tz)
|
||||
{
|
||||
return syscall2(__NR_gettimeofday, (long)tv, (long)tz);
|
||||
}
|
||||
|
||||
int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
|
||||
{
|
||||
return syscall2(__NR_clock_gettime, (long)clock, (long)ts);
|
||||
}
|
||||
|
||||
int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts)
|
||||
{
|
||||
return syscall2(__NR_clock_gettime64, (long)clock, (long)ts);
|
||||
}
|
||||
@@ -1,12 +1,25 @@
|
||||
# List of files in the vdso, has to be asm only for now
|
||||
# Include the generic Makefile to check the built vdso.
|
||||
include $(srctree)/lib/vdso/Makefile
|
||||
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
# Disable gcov profiling, ubsan and kasan for VDSO code
|
||||
GCOV_PROFILE := n
|
||||
UBSAN_SANITIZE := n
|
||||
KASAN_SANITIZE := n
|
||||
KCSAN_SANITIZE := n
|
||||
|
||||
obj-vdso64 = note.o sigtramp.o restart_syscall.o
|
||||
obj-cvdso64 = vdso64_generic.o
|
||||
|
||||
# Build rules
|
||||
|
||||
targets := $(obj-vdso64) vdso64.so
|
||||
obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
|
||||
targets := $(obj-vdso64) $(obj-cvdso64) vdso64.so
|
||||
obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
|
||||
obj-cvdso64 := $(addprefix $(obj)/, $(obj-cvdso64))
|
||||
|
||||
VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE)
|
||||
|
||||
ccflags-y := -shared -fno-common -fno-builtin
|
||||
ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
|
||||
@@ -26,18 +39,22 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so FORCE
|
||||
|
||||
# Force dependency (incbin is bad)
|
||||
# link rule for the .so file, .lds has to be first
|
||||
$(obj)/vdso64.so: $(obj)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC) FORCE
|
||||
$(obj)/vdso64.so: $(obj)/vdso64.lds $(obj-vdso64) $(obj-cvdso64) $(VDSO_LIBGCC) FORCE
|
||||
$(call if_changed,vdso64ld)
|
||||
|
||||
# assembly rules for the .S files
|
||||
$(obj-vdso64): %.o: %.S FORCE
|
||||
$(call if_changed_dep,vdso64as)
|
||||
$(obj-cvdso64): %.o: %.c FORCE
|
||||
$(call if_changed_dep,vdso64cc)
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso64ld = VDSO64L $@
|
||||
cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
|
||||
quiet_cmd_vdso64as = VDSO64A $@
|
||||
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
|
||||
quiet_cmd_vdso64cc = VDSO64C $@
|
||||
cmd_vdso64cc = $(CC) $(c_flags) -c -o $@ $<
|
||||
|
||||
# Generate VDSO offsets using helper script
|
||||
gen-vdsosym := $(src)/gen_vdso_offsets.sh
|
||||
|
||||
@@ -104,6 +104,8 @@ VERSION
|
||||
global:
|
||||
__kernel_sigtramp_rt64;
|
||||
__kernel_restart_syscall64;
|
||||
__vdso_gettimeofday;
|
||||
__vdso_clock_gettime;
|
||||
local: *;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include "asm/unistd.h"
|
||||
#include <linux/types.h>
|
||||
|
||||
struct timezone;
|
||||
struct __kernel_timespec;
|
||||
struct __kernel_old_timeval;
|
||||
|
||||
/* forward declarations */
|
||||
int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
|
||||
int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
|
||||
|
||||
|
||||
int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
|
||||
struct timezone *tz)
|
||||
{
|
||||
return syscall2(__NR_gettimeofday, (long)tv, (long)tz);
|
||||
}
|
||||
|
||||
int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
|
||||
{
|
||||
return syscall2(__NR_clock_gettime, (long)clock, (long)ts);
|
||||
}
|
||||
@@ -390,11 +390,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev);
|
||||
int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv);
|
||||
void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv);
|
||||
|
||||
static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv(
|
||||
struct device_driver *_drv)
|
||||
{
|
||||
return container_of(_drv, struct ps3_system_bus_driver, core);
|
||||
}
|
||||
#define ps3_drv_to_system_bus_drv(_drv) container_of_const(_drv, struct ps3_system_bus_driver, core)
|
||||
static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev(
|
||||
const struct device *_dev)
|
||||
{
|
||||
|
||||
@@ -156,11 +156,7 @@ static inline int vio_enable_interrupts(struct vio_dev *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
|
||||
{
|
||||
return container_of(drv, struct vio_driver, driver);
|
||||
}
|
||||
|
||||
#define to_vio_driver(__drv) container_of_const(__drv, struct vio_driver, driver)
|
||||
#define to_vio_dev(__dev) container_of_const(__dev, struct vio_dev, dev)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
@@ -333,10 +333,10 @@ int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
|
||||
EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
|
||||
|
||||
static int ps3_system_bus_match(struct device *_dev,
|
||||
struct device_driver *_drv)
|
||||
const struct device_driver *_drv)
|
||||
{
|
||||
int result;
|
||||
struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
|
||||
const struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
|
||||
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
|
||||
|
||||
if (!dev->match_sub_id)
|
||||
|
||||
@@ -339,7 +339,7 @@ static struct attribute *ibmbus_bus_attrs[] = {
|
||||
};
|
||||
ATTRIBUTE_GROUPS(ibmbus_bus);
|
||||
|
||||
static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv)
|
||||
static int ibmebus_bus_bus_match(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
const struct of_device_id *matches = drv->of_match_table;
|
||||
|
||||
|
||||
@@ -1576,10 +1576,10 @@ void vio_unregister_device(struct vio_dev *viodev)
|
||||
}
|
||||
EXPORT_SYMBOL(vio_unregister_device);
|
||||
|
||||
static int vio_bus_match(struct device *dev, struct device_driver *drv)
|
||||
static int vio_bus_match(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
const struct vio_dev *vio_dev = to_vio_dev(dev);
|
||||
struct vio_driver *vio_drv = to_vio_driver(drv);
|
||||
const struct vio_driver *vio_drv = to_vio_driver(drv);
|
||||
const struct vio_device_id *ids = vio_drv->id_table;
|
||||
|
||||
return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
|
||||
@@ -1689,7 +1689,7 @@ struct vio_dev *vio_find_node(struct device_node *vnode)
|
||||
/* construct the kobject name from the device node */
|
||||
if (of_node_is_type(vnode_parent, "vdevice")) {
|
||||
const __be32 *prop;
|
||||
|
||||
|
||||
prop = of_get_property(vnode, "reg", NULL);
|
||||
if (!prop)
|
||||
goto out;
|
||||
|
||||
@@ -210,7 +210,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
|
||||
#define get_ccwdev_lock(x) (x)->ccwlock
|
||||
|
||||
#define to_ccwdev(n) container_of(n, struct ccw_device, dev)
|
||||
#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
|
||||
#define to_ccwdrv(n) container_of_const(n, struct ccw_driver, driver)
|
||||
|
||||
extern struct ccw_device *ccw_device_create_console(struct ccw_driver *);
|
||||
extern void ccw_device_destroy_console(struct ccw_device *);
|
||||
|
||||
@@ -483,11 +483,7 @@ int __vio_register_driver(struct vio_driver *drv, struct module *owner,
|
||||
__vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
|
||||
void vio_unregister_driver(struct vio_driver *drv);
|
||||
|
||||
static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
|
||||
{
|
||||
return container_of(drv, struct vio_driver, driver);
|
||||
}
|
||||
|
||||
#define to_vio_driver(__drv) container_of_const(__drv, struct vio_driver, driver)
|
||||
#define to_vio_dev(__dev) container_of_const(__dev, struct vio_dev, dev)
|
||||
|
||||
int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
|
||||
|
||||
@@ -54,10 +54,10 @@ static int vio_hotplug(const struct device *dev, struct kobj_uevent_env *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vio_bus_match(struct device *dev, struct device_driver *drv)
|
||||
static int vio_bus_match(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
struct vio_dev *vio_dev = to_vio_dev(dev);
|
||||
struct vio_driver *vio_drv = to_vio_driver(drv);
|
||||
const struct vio_driver *vio_drv = to_vio_driver(drv);
|
||||
const struct vio_device_id *matches = vio_drv->id_table;
|
||||
|
||||
if (!matches)
|
||||
|
||||
+5
-3
@@ -11,7 +11,7 @@ config UML
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_STRNCPY_FROM_USER
|
||||
select ARCH_HAS_STRNLEN_USER
|
||||
select ARCH_NO_PREEMPT
|
||||
select ARCH_NO_PREEMPT_DYNAMIC
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_KASAN if X86_64
|
||||
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
|
||||
@@ -31,7 +31,8 @@ config UML
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
select TTY # Needed for line.c
|
||||
select HAVE_ARCH_VMAP_STACK
|
||||
select HAVE_RUST if X86_64
|
||||
select HAVE_RUST
|
||||
select ARCH_HAS_UBSAN
|
||||
|
||||
config MMU
|
||||
bool
|
||||
@@ -48,12 +49,13 @@ config NO_IOMEM
|
||||
config UML_IOMEM_EMULATION
|
||||
bool
|
||||
select INDIRECT_IOMEM
|
||||
select HAS_IOPORT
|
||||
select GENERIC_PCI_IOMAP
|
||||
select GENERIC_IOMAP
|
||||
select NO_GENERIC_PCI_IOPORT_MAP
|
||||
|
||||
config NO_IOPORT_MAP
|
||||
def_bool y
|
||||
def_bool !UML_IOMEM_EMULATION
|
||||
|
||||
config ISA
|
||||
bool
|
||||
|
||||
@@ -297,26 +297,6 @@ config UML_NET_MCAST
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config UML_NET_PCAP
|
||||
bool "pcap transport (obsolete)"
|
||||
depends on UML_NET
|
||||
depends on !MODVERSIONS
|
||||
select MAY_HAVE_RUNTIME_DEPS
|
||||
help
|
||||
The pcap transport makes a pcap packet stream on the host look
|
||||
like an ethernet device inside UML. This is useful for making
|
||||
UML act as a network monitor for the host. You must have libcap
|
||||
installed in order to build the pcap transport into UML.
|
||||
|
||||
For more information, see
|
||||
<http://user-mode-linux.sourceforge.net/old/networking.html> That site
|
||||
has examples of the UML command line to use to enable this option.
|
||||
|
||||
NOTE: THIS TRANSPORT IS DEPRECATED AND WILL BE REMOVED SOON!!! Please
|
||||
migrate to UML_NET_VECTOR.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config UML_NET_SLIRP
|
||||
bool "SLiRP transport (obsolete)"
|
||||
depends on UML_NET
|
||||
|
||||
@@ -20,14 +20,9 @@ harddog-objs := harddog_kern.o
|
||||
harddog-builtin-$(CONFIG_UML_WATCHDOG) := harddog_user.o harddog_user_exp.o
|
||||
rtc-objs := rtc_kern.o rtc_user.o
|
||||
|
||||
LDFLAGS_pcap.o = $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libpcap.a)
|
||||
|
||||
LDFLAGS_vde.o = $(shell $(CC) $(CFLAGS) -print-file-name=libvdeplug.a)
|
||||
|
||||
targets := pcap_kern.o pcap_user.o vde_kern.o vde_user.o
|
||||
|
||||
$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
|
||||
$(LD) -r -dp -o $@ $^ $(ld_flags)
|
||||
targets := vde_kern.o vde_user.o
|
||||
|
||||
$(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o
|
||||
$(LD) -r -dp -o $@ $^ $(ld_flags)
|
||||
@@ -49,7 +44,6 @@ obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
|
||||
obj-$(CONFIG_UML_NET_VECTOR) += vector.o
|
||||
obj-$(CONFIG_UML_NET_VDE) += vde.o
|
||||
obj-$(CONFIG_UML_NET_MCAST) += umcast.o
|
||||
obj-$(CONFIG_UML_NET_PCAP) += pcap.o
|
||||
obj-$(CONFIG_UML_NET) += net.o
|
||||
obj-$(CONFIG_MCONSOLE) += mconsole.o
|
||||
obj-$(CONFIG_MMAPPER) += mmapper_kern.o
|
||||
@@ -69,7 +63,7 @@ obj-$(CONFIG_UML_RTC) += rtc.o
|
||||
obj-$(CONFIG_UML_PCI_OVER_VIRTIO) += virt-pci.o
|
||||
|
||||
# pcap_user.o must be added explicitly.
|
||||
USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o vector_user.o
|
||||
USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o vde_user.o vector_user.o
|
||||
CFLAGS_null.o = -DDEV_NULL=$(DEV_NULL_PATH)
|
||||
|
||||
CFLAGS_xterm.o += '-DCONFIG_XTERM_CHAN_DEFAULT_EMULATOR="$(CONFIG_XTERM_CHAN_DEFAULT_EMULATOR)"'
|
||||
|
||||
@@ -22,7 +22,8 @@ struct chan {
|
||||
unsigned int output:1;
|
||||
unsigned int opened:1;
|
||||
unsigned int enabled:1;
|
||||
int fd;
|
||||
int fd_in;
|
||||
int fd_out; /* only different to fd_in if blocking output is needed */
|
||||
const struct chan_ops *ops;
|
||||
void *data;
|
||||
};
|
||||
|
||||
+61
-20
@@ -81,6 +81,12 @@ static const struct chan_ops not_configged_ops = {
|
||||
};
|
||||
#endif /* CONFIG_NOCONFIG_CHAN */
|
||||
|
||||
static inline bool need_output_blocking(void)
|
||||
{
|
||||
return time_travel_mode == TT_MODE_INFCPU ||
|
||||
time_travel_mode == TT_MODE_EXTERNAL;
|
||||
}
|
||||
|
||||
static int open_one_chan(struct chan *chan)
|
||||
{
|
||||
int fd, err;
|
||||
@@ -96,15 +102,43 @@ static int open_one_chan(struct chan *chan)
|
||||
return fd;
|
||||
|
||||
err = os_set_fd_block(fd, 0);
|
||||
if (err) {
|
||||
(*chan->ops->close)(fd, chan->data);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto out_close;
|
||||
|
||||
chan->fd = fd;
|
||||
chan->fd_in = fd;
|
||||
chan->fd_out = fd;
|
||||
|
||||
/*
|
||||
* In time-travel modes infinite-CPU and external we need to guarantee
|
||||
* that any writes to the output succeed immdiately from the point of
|
||||
* the VM. The best way to do this is to put the FD in blocking mode
|
||||
* and simply wait/retry until everything is written.
|
||||
* As every write is guaranteed to complete, we also do not need to
|
||||
* request an IRQ for the output.
|
||||
*
|
||||
* Note that input cannot happen in a time synchronized way. We permit
|
||||
* it, but time passes very quickly if anything waits for a read.
|
||||
*/
|
||||
if (chan->output && need_output_blocking()) {
|
||||
err = os_dup_file(chan->fd_out);
|
||||
if (err < 0)
|
||||
goto out_close;
|
||||
|
||||
chan->fd_out = err;
|
||||
|
||||
err = os_set_fd_block(chan->fd_out, 1);
|
||||
if (err) {
|
||||
os_close_file(chan->fd_out);
|
||||
goto out_close;
|
||||
}
|
||||
}
|
||||
|
||||
chan->opened = 1;
|
||||
return 0;
|
||||
|
||||
out_close:
|
||||
(*chan->ops->close)(fd, chan->data);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int open_chan(struct list_head *chans)
|
||||
@@ -125,7 +159,7 @@ static int open_chan(struct list_head *chans)
|
||||
void chan_enable_winch(struct chan *chan, struct tty_port *port)
|
||||
{
|
||||
if (chan && chan->primary && chan->ops->winch)
|
||||
register_winch(chan->fd, port);
|
||||
register_winch(chan->fd_in, port);
|
||||
}
|
||||
|
||||
static void line_timer_cb(struct work_struct *work)
|
||||
@@ -156,8 +190,9 @@ int enable_chan(struct line *line)
|
||||
|
||||
if (chan->enabled)
|
||||
continue;
|
||||
err = line_setup_irq(chan->fd, chan->input, chan->output, line,
|
||||
chan);
|
||||
err = line_setup_irq(chan->fd_in, chan->input,
|
||||
chan->output && !need_output_blocking(),
|
||||
line, chan);
|
||||
if (err)
|
||||
goto out_close;
|
||||
|
||||
@@ -196,7 +231,8 @@ void free_irqs(void)
|
||||
|
||||
if (chan->input && chan->enabled)
|
||||
um_free_irq(chan->line->read_irq, chan);
|
||||
if (chan->output && chan->enabled)
|
||||
if (chan->output && chan->enabled &&
|
||||
!need_output_blocking())
|
||||
um_free_irq(chan->line->write_irq, chan);
|
||||
chan->enabled = 0;
|
||||
}
|
||||
@@ -216,15 +252,19 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
|
||||
} else {
|
||||
if (chan->input && chan->enabled)
|
||||
um_free_irq(chan->line->read_irq, chan);
|
||||
if (chan->output && chan->enabled)
|
||||
if (chan->output && chan->enabled &&
|
||||
!need_output_blocking())
|
||||
um_free_irq(chan->line->write_irq, chan);
|
||||
chan->enabled = 0;
|
||||
}
|
||||
if (chan->fd_out != chan->fd_in)
|
||||
os_close_file(chan->fd_out);
|
||||
if (chan->ops->close != NULL)
|
||||
(*chan->ops->close)(chan->fd, chan->data);
|
||||
(*chan->ops->close)(chan->fd_in, chan->data);
|
||||
|
||||
chan->opened = 0;
|
||||
chan->fd = -1;
|
||||
chan->fd_in = -1;
|
||||
chan->fd_out = -1;
|
||||
}
|
||||
|
||||
void close_chan(struct line *line)
|
||||
@@ -244,7 +284,7 @@ void close_chan(struct line *line)
|
||||
void deactivate_chan(struct chan *chan, int irq)
|
||||
{
|
||||
if (chan && chan->enabled)
|
||||
deactivate_fd(chan->fd, irq);
|
||||
deactivate_fd(chan->fd_in, irq);
|
||||
}
|
||||
|
||||
int write_chan(struct chan *chan, const u8 *buf, size_t len, int write_irq)
|
||||
@@ -254,7 +294,7 @@ int write_chan(struct chan *chan, const u8 *buf, size_t len, int write_irq)
|
||||
if (len == 0 || !chan || !chan->ops->write)
|
||||
return 0;
|
||||
|
||||
n = chan->ops->write(chan->fd, buf, len, chan->data);
|
||||
n = chan->ops->write(chan->fd_out, buf, len, chan->data);
|
||||
if (chan->primary) {
|
||||
ret = n;
|
||||
}
|
||||
@@ -268,7 +308,7 @@ int console_write_chan(struct chan *chan, const char *buf, int len)
|
||||
if (!chan || !chan->ops->console_write)
|
||||
return 0;
|
||||
|
||||
n = chan->ops->console_write(chan->fd, buf, len);
|
||||
n = chan->ops->console_write(chan->fd_out, buf, len);
|
||||
if (chan->primary)
|
||||
ret = n;
|
||||
return ret;
|
||||
@@ -296,14 +336,14 @@ int chan_window_size(struct line *line, unsigned short *rows_out,
|
||||
if (chan && chan->primary) {
|
||||
if (chan->ops->window_size == NULL)
|
||||
return 0;
|
||||
return chan->ops->window_size(chan->fd, chan->data,
|
||||
return chan->ops->window_size(chan->fd_in, chan->data,
|
||||
rows_out, cols_out);
|
||||
}
|
||||
chan = line->chan_out;
|
||||
if (chan && chan->primary) {
|
||||
if (chan->ops->window_size == NULL)
|
||||
return 0;
|
||||
return chan->ops->window_size(chan->fd, chan->data,
|
||||
return chan->ops->window_size(chan->fd_in, chan->data,
|
||||
rows_out, cols_out);
|
||||
}
|
||||
return 0;
|
||||
@@ -319,7 +359,7 @@ static void free_one_chan(struct chan *chan)
|
||||
(*chan->ops->free)(chan->data);
|
||||
|
||||
if (chan->primary && chan->output)
|
||||
ignore_sigio_fd(chan->fd);
|
||||
ignore_sigio_fd(chan->fd_in);
|
||||
kfree(chan);
|
||||
}
|
||||
|
||||
@@ -478,7 +518,8 @@ static struct chan *parse_chan(struct line *line, char *str, int device,
|
||||
.output = 0,
|
||||
.opened = 0,
|
||||
.enabled = 0,
|
||||
.fd = -1,
|
||||
.fd_in = -1,
|
||||
.fd_out = -1,
|
||||
.ops = ops,
|
||||
.data = data });
|
||||
return chan;
|
||||
@@ -549,7 +590,7 @@ void chan_interrupt(struct line *line, int irq)
|
||||
schedule_delayed_work(&line->task, 1);
|
||||
goto out;
|
||||
}
|
||||
err = chan->ops->read(chan->fd, &c, chan->data);
|
||||
err = chan->ops->read(chan->fd_in, &c, chan->data);
|
||||
if (err > 0)
|
||||
tty_insert_flip_char(port, c, TTY_NORMAL);
|
||||
} while (err > 0);
|
||||
|
||||
@@ -23,7 +23,7 @@ int generic_read(int fd, __u8 *c_out, void *unused)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = read(fd, c_out, sizeof(*c_out));
|
||||
CATCH_EINTR(n = read(fd, c_out, sizeof(*c_out)));
|
||||
if (n > 0)
|
||||
return n;
|
||||
else if (n == 0)
|
||||
@@ -37,11 +37,23 @@ int generic_read(int fd, __u8 *c_out, void *unused)
|
||||
|
||||
int generic_write(int fd, const __u8 *buf, size_t n, void *unused)
|
||||
{
|
||||
int written = 0;
|
||||
int err;
|
||||
|
||||
err = write(fd, buf, n);
|
||||
if (err > 0)
|
||||
return err;
|
||||
/* The FD may be in blocking mode, as such, need to retry short writes,
|
||||
* they may have been interrupted by a signal.
|
||||
*/
|
||||
do {
|
||||
errno = 0;
|
||||
err = write(fd, buf + written, n - written);
|
||||
if (err > 0) {
|
||||
written += err;
|
||||
continue;
|
||||
}
|
||||
} while (err < 0 && errno == EINTR);
|
||||
|
||||
if (written > 0)
|
||||
return written;
|
||||
else if (errno == EAGAIN)
|
||||
return 0;
|
||||
else if (err == 0)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "mconsole.h"
|
||||
#include "harddog.h"
|
||||
|
||||
MODULE_DESCRIPTION("UML hardware watchdog");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static DEFINE_MUTEX(harddog_mutex);
|
||||
|
||||
@@ -383,6 +383,7 @@ int setup_one_line(struct line *lines, int n, char *init,
|
||||
parse_chan_pair(NULL, line, n, opts, error_out);
|
||||
err = 0;
|
||||
}
|
||||
*error_out = "configured as 'none'";
|
||||
} else {
|
||||
char *new = kstrdup(init, GFP_KERNEL);
|
||||
if (!new) {
|
||||
@@ -406,6 +407,7 @@ int setup_one_line(struct line *lines, int n, char *init,
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
*error_out = "failed to parse channel pair";
|
||||
line->init_str = NULL;
|
||||
line->valid = 0;
|
||||
kfree(new);
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net_kern.h>
|
||||
#include "pcap_user.h"
|
||||
|
||||
struct pcap_init {
|
||||
char *host_if;
|
||||
int promisc;
|
||||
int optimize;
|
||||
char *filter;
|
||||
};
|
||||
|
||||
static void pcap_init_kern(struct net_device *dev, void *data)
|
||||
{
|
||||
struct uml_net_private *pri;
|
||||
struct pcap_data *ppri;
|
||||
struct pcap_init *init = data;
|
||||
|
||||
pri = netdev_priv(dev);
|
||||
ppri = (struct pcap_data *) pri->user;
|
||||
ppri->host_if = init->host_if;
|
||||
ppri->promisc = init->promisc;
|
||||
ppri->optimize = init->optimize;
|
||||
ppri->filter = init->filter;
|
||||
|
||||
printk("pcap backend, host interface %s\n", ppri->host_if);
|
||||
}
|
||||
|
||||
static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||
{
|
||||
return pcap_user_read(fd, skb_mac_header(skb),
|
||||
skb->dev->mtu + ETH_HEADER_OTHER,
|
||||
(struct pcap_data *) &lp->user);
|
||||
}
|
||||
|
||||
static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static const struct net_kern_info pcap_kern_info = {
|
||||
.init = pcap_init_kern,
|
||||
.protocol = eth_protocol,
|
||||
.read = pcap_read,
|
||||
.write = pcap_write,
|
||||
};
|
||||
|
||||
static int pcap_setup(char *str, char **mac_out, void *data)
|
||||
{
|
||||
struct pcap_init *init = data;
|
||||
char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
|
||||
int i;
|
||||
|
||||
*init = ((struct pcap_init)
|
||||
{ .host_if = "eth0",
|
||||
.promisc = 1,
|
||||
.optimize = 0,
|
||||
.filter = NULL });
|
||||
|
||||
remain = split_if_spec(str, &host_if, &init->filter,
|
||||
&options[0], &options[1], mac_out, NULL);
|
||||
if (remain != NULL) {
|
||||
printk(KERN_ERR "pcap_setup - Extra garbage on "
|
||||
"specification : '%s'\n", remain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (host_if != NULL)
|
||||
init->host_if = host_if;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(options); i++) {
|
||||
if (options[i] == NULL)
|
||||
continue;
|
||||
if (!strcmp(options[i], "promisc"))
|
||||
init->promisc = 1;
|
||||
else if (!strcmp(options[i], "nopromisc"))
|
||||
init->promisc = 0;
|
||||
else if (!strcmp(options[i], "optimize"))
|
||||
init->optimize = 1;
|
||||
else if (!strcmp(options[i], "nooptimize"))
|
||||
init->optimize = 0;
|
||||
else {
|
||||
printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
|
||||
options[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct transport pcap_transport = {
|
||||
.list = LIST_HEAD_INIT(pcap_transport.list),
|
||||
.name = "pcap",
|
||||
.setup = pcap_setup,
|
||||
.user = &pcap_user_info,
|
||||
.kern = &pcap_kern_info,
|
||||
.private_size = sizeof(struct pcap_data),
|
||||
.setup_size = sizeof(struct pcap_init),
|
||||
};
|
||||
|
||||
static int register_pcap(void)
|
||||
{
|
||||
register_transport(&pcap_transport);
|
||||
return 0;
|
||||
}
|
||||
|
||||
late_initcall(register_pcap);
|
||||
@@ -1,137 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pcap.h>
|
||||
#include <string.h>
|
||||
#include <asm/types.h>
|
||||
#include <net_user.h>
|
||||
#include "pcap_user.h"
|
||||
#include <um_malloc.h>
|
||||
|
||||
#define PCAP_FD(p) (*(int *)(p))
|
||||
|
||||
static int pcap_user_init(void *data, void *dev)
|
||||
{
|
||||
struct pcap_data *pri = data;
|
||||
pcap_t *p;
|
||||
char errors[PCAP_ERRBUF_SIZE];
|
||||
|
||||
p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
|
||||
pri->promisc, 0, errors);
|
||||
if (p == NULL) {
|
||||
printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
|
||||
"'%s'\n", errors);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pri->dev = dev;
|
||||
pri->pcap = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcap_user_open(void *data)
|
||||
{
|
||||
struct pcap_data *pri = data;
|
||||
__u32 netmask;
|
||||
int err;
|
||||
|
||||
if (pri->pcap == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
if (pri->filter != NULL) {
|
||||
err = dev_netmask(pri->dev, &netmask);
|
||||
if (err < 0) {
|
||||
printk(UM_KERN_ERR "pcap_user_open : dev_netmask failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pri->compiled = uml_kmalloc(sizeof(struct bpf_program),
|
||||
UM_GFP_KERNEL);
|
||||
if (pri->compiled == NULL) {
|
||||
printk(UM_KERN_ERR "pcap_user_open : kmalloc failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = pcap_compile(pri->pcap,
|
||||
(struct bpf_program *) pri->compiled,
|
||||
pri->filter, pri->optimize, netmask);
|
||||
if (err < 0) {
|
||||
printk(UM_KERN_ERR "pcap_user_open : pcap_compile failed - "
|
||||
"'%s'\n", pcap_geterr(pri->pcap));
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = pcap_setfilter(pri->pcap, pri->compiled);
|
||||
if (err < 0) {
|
||||
printk(UM_KERN_ERR "pcap_user_open : pcap_setfilter "
|
||||
"failed - '%s'\n", pcap_geterr(pri->pcap));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return PCAP_FD(pri->pcap);
|
||||
|
||||
out:
|
||||
kfree(pri->compiled);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void pcap_remove(void *data)
|
||||
{
|
||||
struct pcap_data *pri = data;
|
||||
|
||||
if (pri->compiled != NULL)
|
||||
pcap_freecode(pri->compiled);
|
||||
|
||||
if (pri->pcap != NULL)
|
||||
pcap_close(pri->pcap);
|
||||
}
|
||||
|
||||
struct pcap_handler_data {
|
||||
char *buffer;
|
||||
int len;
|
||||
};
|
||||
|
||||
static void handler(u_char *data, const struct pcap_pkthdr *header,
|
||||
const u_char *packet)
|
||||
{
|
||||
int len;
|
||||
|
||||
struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
|
||||
|
||||
len = hdata->len < header->caplen ? hdata->len : header->caplen;
|
||||
memcpy(hdata->buffer, packet, len);
|
||||
hdata->len = len;
|
||||
}
|
||||
|
||||
int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
|
||||
{
|
||||
struct pcap_handler_data hdata = ((struct pcap_handler_data)
|
||||
{ .buffer = buffer,
|
||||
.len = len });
|
||||
int n;
|
||||
|
||||
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
|
||||
if (n < 0) {
|
||||
printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
|
||||
pcap_geterr(pri->pcap));
|
||||
return -EIO;
|
||||
}
|
||||
else if (n == 0)
|
||||
return 0;
|
||||
return hdata.len;
|
||||
}
|
||||
|
||||
const struct net_user_info pcap_user_info = {
|
||||
.init = pcap_user_init,
|
||||
.open = pcap_user_open,
|
||||
.close = NULL,
|
||||
.remove = pcap_remove,
|
||||
.add_address = NULL,
|
||||
.delete_address = NULL,
|
||||
.mtu = ETH_MAX_PACKET,
|
||||
.max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
*/
|
||||
|
||||
#include <net_user.h>
|
||||
|
||||
struct pcap_data {
|
||||
char *host_if;
|
||||
int promisc;
|
||||
int optimize;
|
||||
char *filter;
|
||||
void *compiled;
|
||||
void *pcap;
|
||||
void *dev;
|
||||
};
|
||||
|
||||
extern const struct net_user_info pcap_user_info;
|
||||
|
||||
extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
|
||||
|
||||
@@ -45,15 +45,17 @@ struct connection {
|
||||
static irqreturn_t pipe_interrupt(int irq, void *data)
|
||||
{
|
||||
struct connection *conn = data;
|
||||
int fd;
|
||||
int n_fds = 1, fd = -1;
|
||||
ssize_t ret;
|
||||
|
||||
fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
|
||||
if (fd < 0) {
|
||||
if (fd == -EAGAIN)
|
||||
ret = os_rcv_fd_msg(conn->socket[0], &fd, n_fds, &conn->helper_pid,
|
||||
sizeof(conn->helper_pid));
|
||||
if (ret != sizeof(conn->helper_pid)) {
|
||||
if (ret == -EAGAIN)
|
||||
return IRQ_NONE;
|
||||
|
||||
printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
|
||||
-fd);
|
||||
printk(KERN_ERR "pipe_interrupt : os_rcv_fd_msg returned %zd\n",
|
||||
ret);
|
||||
os_close_file(conn->fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <kern_util.h>
|
||||
#include "mconsole_kern.h"
|
||||
#include <init.h>
|
||||
@@ -106,7 +105,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
|
||||
#define DRIVER_NAME "uml-blkdev"
|
||||
|
||||
static DEFINE_MUTEX(ubd_lock);
|
||||
static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */
|
||||
|
||||
static int ubd_ioctl(struct block_device *bdev, blk_mode_t mode,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
@@ -759,7 +757,6 @@ static int ubd_open_dev(struct ubd *ubd_dev)
|
||||
printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
|
||||
goto error;
|
||||
}
|
||||
flush_tlb_kernel_vm();
|
||||
|
||||
err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
|
||||
ubd_dev->cow.bitmap_offset,
|
||||
|
||||
@@ -1115,11 +1115,12 @@ static int irq_rr;
|
||||
static int vector_net_close(struct net_device *dev)
|
||||
{
|
||||
struct vector_private *vp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
|
||||
netif_stop_queue(dev);
|
||||
del_timer(&vp->tl);
|
||||
|
||||
vp->opened = false;
|
||||
|
||||
if (vp->fds == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -1158,10 +1159,7 @@ static int vector_net_close(struct net_device *dev)
|
||||
destroy_queue(vp->tx_queue);
|
||||
kfree(vp->fds);
|
||||
vp->fds = NULL;
|
||||
spin_lock_irqsave(&vp->lock, flags);
|
||||
vp->opened = false;
|
||||
vp->in_error = false;
|
||||
spin_unlock_irqrestore(&vp->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1203,17 +1201,12 @@ static void vector_reset_tx(struct work_struct *work)
|
||||
static int vector_net_open(struct net_device *dev)
|
||||
{
|
||||
struct vector_private *vp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
int err = -EINVAL;
|
||||
struct vector_device *vdevice;
|
||||
|
||||
spin_lock_irqsave(&vp->lock, flags);
|
||||
if (vp->opened) {
|
||||
spin_unlock_irqrestore(&vp->lock, flags);
|
||||
if (vp->opened)
|
||||
return -ENXIO;
|
||||
}
|
||||
vp->opened = true;
|
||||
spin_unlock_irqrestore(&vp->lock, flags);
|
||||
|
||||
vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));
|
||||
|
||||
@@ -1387,8 +1380,6 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
|
||||
return -1;
|
||||
}
|
||||
|
||||
spin_lock(&vp->lock);
|
||||
|
||||
if (vp->bpf != NULL) {
|
||||
if (vp->opened)
|
||||
uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
|
||||
@@ -1417,15 +1408,12 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
|
||||
if (vp->opened)
|
||||
result = uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
|
||||
|
||||
spin_unlock(&vp->lock);
|
||||
|
||||
return result;
|
||||
|
||||
free_buffer:
|
||||
release_firmware(fw);
|
||||
|
||||
flash_fail:
|
||||
spin_unlock(&vp->lock);
|
||||
if (vp->bpf != NULL)
|
||||
kfree(vp->bpf->filter);
|
||||
kfree(vp->bpf);
|
||||
@@ -1631,7 +1619,6 @@ static void vector_eth_configure(
|
||||
INIT_WORK(&vp->reset_tx, vector_reset_tx);
|
||||
|
||||
timer_setup(&vp->tl, vector_timer_expire, 0);
|
||||
spin_lock_init(&vp->lock);
|
||||
|
||||
/* FIXME */
|
||||
dev->netdev_ops = &vector_netdev_ops;
|
||||
|
||||
@@ -71,7 +71,6 @@ struct vector_estats {
|
||||
|
||||
struct vector_private {
|
||||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
struct net_device *dev;
|
||||
struct napi_struct napi ____cacheline_aligned;
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ static int xterm_open(int input, int output, int primary, void *d,
|
||||
new = xterm_fd(fd, &data->helper_pid);
|
||||
if (new < 0) {
|
||||
err = new;
|
||||
printk(UM_KERN_ERR "xterm_open : os_rcv_fd failed, err = %d\n",
|
||||
printk(UM_KERN_ERR "xterm_open : xterm_fd failed, err = %d\n",
|
||||
-err);
|
||||
goto out_kill;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,19 @@ struct xterm_wait {
|
||||
static irqreturn_t xterm_interrupt(int irq, void *data)
|
||||
{
|
||||
struct xterm_wait *xterm = data;
|
||||
int fd;
|
||||
int fd = -1, n_fds = 1;
|
||||
ssize_t ret;
|
||||
|
||||
fd = os_rcv_fd(xterm->fd, &xterm->pid);
|
||||
if (fd == -EAGAIN)
|
||||
ret = os_rcv_fd_msg(xterm->fd, &fd, n_fds,
|
||||
&xterm->pid, sizeof(xterm->pid));
|
||||
if (ret == -EAGAIN)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (ret < 0)
|
||||
fd = ret;
|
||||
else if (ret != sizeof(xterm->pid))
|
||||
fd = -EMSGSIZE;
|
||||
|
||||
xterm->new_fd = fd;
|
||||
complete(&xterm->ready);
|
||||
|
||||
|
||||
@@ -7,15 +7,13 @@
|
||||
#define __ARCH_UM_MMU_H
|
||||
|
||||
#include <mm_id.h>
|
||||
#include <asm/mm_context.h>
|
||||
|
||||
typedef struct mm_context {
|
||||
struct mm_id id;
|
||||
struct uml_arch_mm_context arch;
|
||||
|
||||
/* Address range in need of a TLB sync */
|
||||
unsigned long sync_tlb_range_from;
|
||||
unsigned long sync_tlb_range_to;
|
||||
} mm_context_t;
|
||||
|
||||
/* Avoid tangled inclusion with asm/ldt.h */
|
||||
extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm);
|
||||
extern void free_ldt(struct mm_context *mm);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <asm/mm_hooks.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
extern void force_flush_all(void);
|
||||
|
||||
#define activate_mm activate_mm
|
||||
static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
|
||||
{
|
||||
|
||||
@@ -244,6 +244,38 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
|
||||
|
||||
#define PFN_PTE_SHIFT PAGE_SHIFT
|
||||
|
||||
static inline void um_tlb_mark_sync(struct mm_struct *mm, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
if (!mm->context.sync_tlb_range_to) {
|
||||
mm->context.sync_tlb_range_from = start;
|
||||
mm->context.sync_tlb_range_to = end;
|
||||
} else {
|
||||
if (start < mm->context.sync_tlb_range_from)
|
||||
mm->context.sync_tlb_range_from = start;
|
||||
if (end > mm->context.sync_tlb_range_to)
|
||||
mm->context.sync_tlb_range_to = end;
|
||||
}
|
||||
}
|
||||
|
||||
#define set_ptes set_ptes
|
||||
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t pte, int nr)
|
||||
{
|
||||
/* Basically the default implementation */
|
||||
size_t length = nr * PAGE_SIZE;
|
||||
|
||||
for (;;) {
|
||||
set_pte(ptep, pte);
|
||||
if (--nr == 0)
|
||||
break;
|
||||
ptep++;
|
||||
pte = __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
|
||||
}
|
||||
|
||||
um_tlb_mark_sync(mm, addr, addr + length);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTE_SAME
|
||||
static inline int pte_same(pte_t pte_a, pte_t pte_b)
|
||||
{
|
||||
|
||||
@@ -9,23 +9,51 @@
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* TLB flushing:
|
||||
* In UML, we need to sync the TLB over by using mmap/munmap/mprotect syscalls
|
||||
* from the process handling the MM (which can be the kernel itself).
|
||||
*
|
||||
* To track updates, we can hook into set_ptes and flush_tlb_*. With set_ptes
|
||||
* we catch all PTE transitions where memory that was unusable becomes usable.
|
||||
* While with flush_tlb_* we can track any memory that becomes unusable and
|
||||
* even if a higher layer of the page table was modified.
|
||||
*
|
||||
* So, we simply track updates using both methods and mark the memory area to
|
||||
* be synced later on. The only special case is that flush_tlb_kern_* needs to
|
||||
* be executed immediately as there is no good synchronization point in that
|
||||
* case. In contrast, in the set_ptes case we can wait for the next kernel
|
||||
* segfault before we do the synchornization.
|
||||
*
|
||||
* - flush_tlb() flushes the current mm struct TLBs
|
||||
* - flush_tlb_all() flushes all processes TLBs
|
||||
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
|
||||
* - flush_tlb_page(vma, vmaddr) flushes one page
|
||||
* - flush_tlb_kernel_vm() flushes the kernel vm area
|
||||
* - flush_tlb_range(vma, start, end) flushes a range of pages
|
||||
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
|
||||
*/
|
||||
|
||||
extern int um_tlb_sync(struct mm_struct *mm);
|
||||
|
||||
extern void flush_tlb_all(void);
|
||||
extern void flush_tlb_mm(struct mm_struct *mm);
|
||||
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||
unsigned long end);
|
||||
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long address);
|
||||
extern void flush_tlb_kernel_vm(void);
|
||||
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
extern void __flush_tlb_one(unsigned long addr);
|
||||
|
||||
static inline void flush_tlb_page(struct vm_area_struct *vma,
|
||||
unsigned long address)
|
||||
{
|
||||
um_tlb_mark_sync(vma->vm_mm, address, address + PAGE_SIZE);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
um_tlb_mark_sync(vma->vm_mm, start, end);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_kernel_range(unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
um_tlb_mark_sync(&init_mm, start, end);
|
||||
|
||||
/* Kernel needs to be synced immediately */
|
||||
um_tlb_sync(&init_mm);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define STUB_START stub_start
|
||||
#define STUB_CODE STUB_START
|
||||
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
|
||||
#define STUB_DATA_PAGES 1 /* must be a power of two */
|
||||
#define STUB_DATA_PAGES 2 /* must be a power of two */
|
||||
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* for use by sys-$SUBARCH/kernel-offsets.c */
|
||||
#include <stub-data.h>
|
||||
|
||||
DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
|
||||
|
||||
@@ -30,7 +29,3 @@ DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT);
|
||||
DEFINE(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT, CONFIG_UML_TIME_TRAVEL_SUPPORT);
|
||||
#endif
|
||||
|
||||
/* for stub */
|
||||
DEFINE(UML_STUB_FIELD_OFFSET, offsetof(struct stub_data, offset));
|
||||
DEFINE(UML_STUB_FIELD_CHILD_ERR, offsetof(struct stub_data, child_err));
|
||||
DEFINE(UML_STUB_FIELD_FD, offsetof(struct stub_data, fd));
|
||||
|
||||
@@ -13,7 +13,6 @@ struct siginfo;
|
||||
|
||||
extern int uml_exitcode;
|
||||
|
||||
extern int ncpus;
|
||||
extern int kmalloc_ok;
|
||||
|
||||
#define UML_ROUND_UP(addr) \
|
||||
|
||||
+18
-15
@@ -163,8 +163,10 @@ extern int os_set_fd_block(int fd, int blocking);
|
||||
extern int os_accept_connection(int fd);
|
||||
extern int os_create_unix_socket(const char *file, int len, int close_on_exec);
|
||||
extern int os_shutdown_socket(int fd, int r, int w);
|
||||
extern int os_dup_file(int fd);
|
||||
extern void os_close_file(int fd);
|
||||
extern int os_rcv_fd(int fd, int *helper_pid_out);
|
||||
ssize_t os_rcv_fd_msg(int fd, int *fds, unsigned int n_fds,
|
||||
void *data, size_t data_len);
|
||||
extern int os_connect_socket(const char *name);
|
||||
extern int os_file_type(char *file);
|
||||
extern int os_file_mode(const char *file, struct openflags *mode_out);
|
||||
@@ -179,6 +181,8 @@ extern int os_eventfd(unsigned int initval, int flags);
|
||||
extern int os_sendmsg_fds(int fd, const void *buf, unsigned int len,
|
||||
const int *fds, unsigned int fds_num);
|
||||
int os_poll(unsigned int n, const int *fds);
|
||||
void *os_mmap_rw_shared(int fd, size_t size);
|
||||
void *os_mremap_rw_shared(void *old_addr, size_t old_size, size_t new_size);
|
||||
|
||||
/* start_up.c */
|
||||
extern void os_early_checks(void);
|
||||
@@ -191,6 +195,9 @@ extern void get_host_cpu_features(
|
||||
/* mem.c */
|
||||
extern int create_mem_file(unsigned long long len);
|
||||
|
||||
/* tlb.c */
|
||||
extern void report_enomem(void);
|
||||
|
||||
/* process.c */
|
||||
extern unsigned long os_process_pc(int pid);
|
||||
extern int os_process_parent(int pid);
|
||||
@@ -268,24 +275,20 @@ extern long long os_persistent_clock_emulation(void);
|
||||
extern long long os_nsecs(void);
|
||||
|
||||
/* skas/mem.c */
|
||||
extern long run_syscall_stub(struct mm_id * mm_idp,
|
||||
int syscall, unsigned long *args, long expected,
|
||||
void **addr, int done);
|
||||
extern long syscall_stub_data(struct mm_id * mm_idp,
|
||||
unsigned long *data, int data_count,
|
||||
void **addr, void **stub_addr);
|
||||
extern int map(struct mm_id * mm_idp, unsigned long virt,
|
||||
unsigned long len, int prot, int phys_fd,
|
||||
unsigned long long offset, int done, void **data);
|
||||
extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
||||
int done, void **data);
|
||||
extern int protect(struct mm_id * mm_idp, unsigned long addr,
|
||||
unsigned long len, unsigned int prot, int done, void **data);
|
||||
int syscall_stub_flush(struct mm_id *mm_idp);
|
||||
struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp);
|
||||
void syscall_stub_dump_error(struct mm_id *mm_idp);
|
||||
|
||||
int map(struct mm_id *mm_idp, unsigned long virt,
|
||||
unsigned long len, int prot, int phys_fd,
|
||||
unsigned long long offset);
|
||||
int unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len);
|
||||
int protect(struct mm_id *mm_idp, unsigned long addr,
|
||||
unsigned long len, unsigned int prot);
|
||||
|
||||
/* skas/process.c */
|
||||
extern int is_skas_winch(int pid, int fd, void *data);
|
||||
extern int start_userspace(unsigned long stub_stack);
|
||||
extern int copy_context_skas0(unsigned long stack, int pid);
|
||||
extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs);
|
||||
extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
|
||||
extern void switch_threads(jmp_buf *me, jmp_buf *you);
|
||||
|
||||
@@ -12,7 +12,7 @@ struct mm_id {
|
||||
int pid;
|
||||
} u;
|
||||
unsigned long stack;
|
||||
int kill;
|
||||
int syscall_data_len;
|
||||
};
|
||||
|
||||
void __switch_mm(struct mm_id *mm_idp);
|
||||
|
||||
@@ -15,5 +15,7 @@ extern void new_thread_handler(void);
|
||||
extern void handle_syscall(struct uml_pt_regs *regs);
|
||||
extern long execute_syscall_skas(void *r);
|
||||
extern unsigned long current_stub_stack(void);
|
||||
extern struct mm_id *current_mm_id(void);
|
||||
extern void current_mm_sync(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,10 +8,42 @@
|
||||
#ifndef __STUB_DATA_H
|
||||
#define __STUB_DATA_H
|
||||
|
||||
#include <linux/compiler_types.h>
|
||||
#include <as-layout.h>
|
||||
#include <sysdep/tls.h>
|
||||
|
||||
#define STUB_NEXT_SYSCALL(s) \
|
||||
((struct stub_syscall *) (((unsigned long) s) + (s)->cmd_len))
|
||||
|
||||
enum stub_syscall_type {
|
||||
STUB_SYSCALL_UNSET = 0,
|
||||
STUB_SYSCALL_MMAP,
|
||||
STUB_SYSCALL_MUNMAP,
|
||||
STUB_SYSCALL_MPROTECT,
|
||||
};
|
||||
|
||||
struct stub_syscall {
|
||||
struct {
|
||||
unsigned long addr;
|
||||
unsigned long length;
|
||||
unsigned long offset;
|
||||
int fd;
|
||||
int prot;
|
||||
} mem;
|
||||
|
||||
enum stub_syscall_type syscall;
|
||||
};
|
||||
|
||||
struct stub_data {
|
||||
unsigned long offset;
|
||||
int fd;
|
||||
long parent_err, child_err;
|
||||
long err, child_err;
|
||||
|
||||
int syscall_data_len;
|
||||
/* 128 leaves enough room for additional fields in the struct */
|
||||
struct stub_syscall syscall_data[(UM_KERN_PAGE_SIZE - 128) / sizeof(struct stub_syscall)] __aligned(16);
|
||||
|
||||
/* Stack for our signal handlers and for calling into . */
|
||||
unsigned char sigstack[UM_KERN_PAGE_SIZE] __aligned(UM_KERN_PAGE_SIZE);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,8 +15,17 @@ enum time_travel_mode {
|
||||
#if defined(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT) || \
|
||||
defined(CONFIG_UML_TIME_TRAVEL_SUPPORT)
|
||||
extern enum time_travel_mode time_travel_mode;
|
||||
extern int time_travel_should_print_bc_msg;
|
||||
#else
|
||||
#define time_travel_mode TT_MODE_OFF
|
||||
#define time_travel_should_print_bc_msg 0
|
||||
#endif /* (UML_)CONFIG_UML_TIME_TRAVEL_SUPPORT */
|
||||
|
||||
void _time_travel_print_bc_msg(void);
|
||||
static inline void time_travel_print_bc_msg(void)
|
||||
{
|
||||
if (time_travel_should_print_bc_msg)
|
||||
_time_travel_print_bc_msg();
|
||||
}
|
||||
|
||||
#endif /* _UM_TIME_TRAVEL_H_ */
|
||||
|
||||
@@ -42,11 +42,19 @@ extern void panic(const char *fmt, ...)
|
||||
#define printk(...) _printk(__VA_ARGS__)
|
||||
extern int _printk(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
extern void print_hex_dump(const char *level, const char *prefix_str,
|
||||
int prefix_type, int rowsize, int groupsize,
|
||||
const void *buf, size_t len, _Bool ascii);
|
||||
#else
|
||||
static inline int printk(const char *fmt, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void print_hex_dump(const char *level, const char *prefix_str,
|
||||
int prefix_type, int rowsize, int groupsize,
|
||||
const void *buf, size_t len, _Bool ascii)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int in_aton(char *str);
|
||||
|
||||
@@ -22,17 +22,8 @@
|
||||
|
||||
void flush_thread(void)
|
||||
{
|
||||
void *data = NULL;
|
||||
int ret;
|
||||
|
||||
arch_flush_thread(¤t->thread.arch);
|
||||
|
||||
ret = unmap(¤t->mm->context.id, 0, TASK_SIZE, 1, &data);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s - clearing address space failed, err = %d\n",
|
||||
__func__, ret);
|
||||
force_sig(SIGKILL);
|
||||
}
|
||||
get_safe_registers(current_pt_regs()->regs.gp,
|
||||
current_pt_regs()->regs.fp);
|
||||
|
||||
|
||||
+51
-29
@@ -37,7 +37,7 @@ struct irq_reg {
|
||||
bool pending;
|
||||
bool wakeup;
|
||||
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
|
||||
bool pending_on_resume;
|
||||
bool pending_event;
|
||||
void (*timetravel_handler)(int, int, void *,
|
||||
struct time_travel_event *);
|
||||
struct time_travel_event event;
|
||||
@@ -56,6 +56,9 @@ static DEFINE_SPINLOCK(irq_lock);
|
||||
static LIST_HEAD(active_fds);
|
||||
static DECLARE_BITMAP(irqs_allocated, UM_LAST_SIGNAL_IRQ);
|
||||
static bool irqs_suspended;
|
||||
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
|
||||
static bool irqs_pending;
|
||||
#endif
|
||||
|
||||
static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs)
|
||||
{
|
||||
@@ -84,9 +87,12 @@ static void irq_event_handler(struct time_travel_event *ev)
|
||||
{
|
||||
struct irq_reg *reg = container_of(ev, struct irq_reg, event);
|
||||
|
||||
/* do nothing if suspended - just to cause a wakeup */
|
||||
if (irqs_suspended)
|
||||
/* do nothing if suspended; just cause a wakeup and mark as pending */
|
||||
if (irqs_suspended) {
|
||||
irqs_pending = true;
|
||||
reg->pending_event = true;
|
||||
return;
|
||||
}
|
||||
|
||||
generic_handle_irq(reg->irq);
|
||||
}
|
||||
@@ -110,16 +116,47 @@ static bool irq_do_timetravel_handler(struct irq_entry *entry,
|
||||
if (!reg->event.pending)
|
||||
return false;
|
||||
|
||||
if (irqs_suspended)
|
||||
reg->pending_on_resume = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void irq_do_pending_events(bool timetravel_handlers_only)
|
||||
{
|
||||
struct irq_entry *entry;
|
||||
|
||||
if (!irqs_pending || timetravel_handlers_only)
|
||||
return;
|
||||
|
||||
irqs_pending = false;
|
||||
|
||||
list_for_each_entry(entry, &active_fds, list) {
|
||||
enum um_irq_type t;
|
||||
|
||||
for (t = 0; t < NUM_IRQ_TYPES; t++) {
|
||||
struct irq_reg *reg = &entry->reg[t];
|
||||
|
||||
/*
|
||||
* Any timetravel_handler was invoked already, just
|
||||
* directly run the IRQ.
|
||||
*/
|
||||
if (reg->pending_event) {
|
||||
irq_enter();
|
||||
generic_handle_irq(reg->irq);
|
||||
irq_exit();
|
||||
reg->pending_event = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static bool irq_do_timetravel_handler(struct irq_entry *entry,
|
||||
enum um_irq_type t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void irq_do_pending_events(bool timetravel_handlers_only)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sigio_reg_handler(int idx, struct irq_entry *entry, enum um_irq_type t,
|
||||
@@ -145,6 +182,8 @@ static void sigio_reg_handler(int idx, struct irq_entry *entry, enum um_irq_type
|
||||
*/
|
||||
if (timetravel_handlers_only) {
|
||||
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
|
||||
reg->pending_event = true;
|
||||
irqs_pending = true;
|
||||
mark_sigio_pending();
|
||||
#endif
|
||||
return;
|
||||
@@ -162,6 +201,10 @@ static void _sigio_handler(struct uml_pt_regs *regs,
|
||||
if (timetravel_handlers_only && !um_irq_timetravel_handler_used())
|
||||
return;
|
||||
|
||||
/* Flush out pending events that were ignored due to time-travel. */
|
||||
if (!irqs_suspended)
|
||||
irq_do_pending_events(timetravel_handlers_only);
|
||||
|
||||
while (1) {
|
||||
/* This is now lockless - epoll keeps back-referencesto the irqs
|
||||
* which have trigger it so there is no need to walk the irq
|
||||
@@ -195,7 +238,9 @@ static void _sigio_handler(struct uml_pt_regs *regs,
|
||||
|
||||
void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
|
||||
{
|
||||
preempt_disable();
|
||||
_sigio_handler(regs, irqs_suspended);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static struct irq_entry *get_irq_entry_by_fd(int fd)
|
||||
@@ -543,30 +588,7 @@ void um_irqs_resume(void)
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
local_irq_save(flags);
|
||||
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
|
||||
/*
|
||||
* We don't need to lock anything here since we're in resume
|
||||
* and nothing else is running, but have disabled IRQs so we
|
||||
* don't try anything else with the interrupt list from there.
|
||||
*/
|
||||
list_for_each_entry(entry, &active_fds, list) {
|
||||
enum um_irq_type t;
|
||||
|
||||
for (t = 0; t < NUM_IRQ_TYPES; t++) {
|
||||
struct irq_reg *reg = &entry->reg[t];
|
||||
|
||||
if (reg->pending_on_resume) {
|
||||
irq_enter();
|
||||
generic_handle_irq(reg->irq);
|
||||
irq_exit();
|
||||
reg->pending_on_resume = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
spin_lock(&irq_lock);
|
||||
spin_lock_irqsave(&irq_lock, flags);
|
||||
list_for_each_entry(entry, &active_fds, list) {
|
||||
if (entry->suspended) {
|
||||
int err = os_set_fd_async(entry->fd);
|
||||
|
||||
@@ -33,7 +33,7 @@ EXPORT_SYMBOL(os_shutdown_socket);
|
||||
EXPORT_SYMBOL(os_create_unix_socket);
|
||||
EXPORT_SYMBOL(os_connect_socket);
|
||||
EXPORT_SYMBOL(os_accept_connection);
|
||||
EXPORT_SYMBOL(os_rcv_fd);
|
||||
EXPORT_SYMBOL(os_rcv_fd_msg);
|
||||
EXPORT_SYMBOL(run_helper);
|
||||
EXPORT_SYMBOL(os_major);
|
||||
EXPORT_SYMBOL(os_minor);
|
||||
|
||||
@@ -73,7 +73,6 @@ void __init mem_init(void)
|
||||
|
||||
/* this will put all low memory onto the freelists */
|
||||
memblock_free_all();
|
||||
max_low_pfn = totalram_pages();
|
||||
max_pfn = max_low_pfn;
|
||||
kmalloc_ok = 1;
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@ void new_thread_handler(void)
|
||||
/* Called magically, see new_thread_handler above */
|
||||
static void fork_handler(void)
|
||||
{
|
||||
force_flush_all();
|
||||
|
||||
schedule_tail(current->thread.prev_sched);
|
||||
|
||||
/*
|
||||
@@ -237,73 +235,6 @@ int copy_from_user_proc(void *to, void __user *from, int size)
|
||||
return copy_from_user(to, from, size);
|
||||
}
|
||||
|
||||
static atomic_t using_sysemu = ATOMIC_INIT(0);
|
||||
int sysemu_supported;
|
||||
|
||||
static void set_using_sysemu(int value)
|
||||
{
|
||||
if (value > sysemu_supported)
|
||||
return;
|
||||
atomic_set(&using_sysemu, value);
|
||||
}
|
||||
|
||||
static int get_using_sysemu(void)
|
||||
{
|
||||
return atomic_read(&using_sysemu);
|
||||
}
|
||||
|
||||
static int sysemu_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "%d\n", get_using_sysemu());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sysemu_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, sysemu_proc_show, NULL);
|
||||
}
|
||||
|
||||
static ssize_t sysemu_proc_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
char tmp[2];
|
||||
|
||||
if (copy_from_user(tmp, buf, 1))
|
||||
return -EFAULT;
|
||||
|
||||
if (tmp[0] >= '0' && tmp[0] <= '2')
|
||||
set_using_sysemu(tmp[0] - '0');
|
||||
/* We use the first char, but pretend to write everything */
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct proc_ops sysemu_proc_ops = {
|
||||
.proc_open = sysemu_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
.proc_write = sysemu_proc_write,
|
||||
};
|
||||
|
||||
static int __init make_proc_sysemu(void)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
if (!sysemu_supported)
|
||||
return 0;
|
||||
|
||||
ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_ops);
|
||||
|
||||
if (ent == NULL)
|
||||
{
|
||||
printk(KERN_WARNING "Failed to register /proc/sysemu\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
late_initcall(make_proc_sysemu);
|
||||
|
||||
int singlestepping(void)
|
||||
{
|
||||
return test_thread_flag(TIF_SINGLESTEP);
|
||||
|
||||
@@ -59,3 +59,18 @@ void machine_halt(void)
|
||||
{
|
||||
machine_power_off();
|
||||
}
|
||||
|
||||
static int sys_power_off_handler(struct sys_off_data *data)
|
||||
{
|
||||
machine_power_off();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int register_power_off(void)
|
||||
{
|
||||
register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
sys_power_off_handler, NULL);
|
||||
return 0;
|
||||
}
|
||||
__initcall(register_power_off);
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
#
|
||||
|
||||
obj-y := clone.o mmu.o process.o syscall.o uaccess.o
|
||||
obj-y := stub.o mmu.o process.o syscall.o uaccess.o
|
||||
|
||||
# clone.o is in the stub, so it can't be built with profiling
|
||||
# stub.o is in the stub, so it can't be built with profiling
|
||||
# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
|
||||
# disable it
|
||||
|
||||
CFLAGS_clone.o := $(CFLAGS_NO_HARDENING)
|
||||
UNPROFILE_OBJS := clone.o
|
||||
|
||||
CFLAGS_stub.o := $(CFLAGS_NO_HARDENING)
|
||||
UNPROFILE_OBJS := stub.o
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
include $(srctree)/arch/um/scripts/Makefile.rules
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
|
||||
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <as-layout.h>
|
||||
#include <ptrace_user.h>
|
||||
#include <stub-data.h>
|
||||
#include <sysdep/stub.h>
|
||||
|
||||
/*
|
||||
* This is in a separate file because it needs to be compiled with any
|
||||
* extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
|
||||
*
|
||||
* Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize
|
||||
* on some systems.
|
||||
*/
|
||||
|
||||
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||
stub_clone_handler(void)
|
||||
{
|
||||
struct stub_data *data = get_stub_data();
|
||||
long err;
|
||||
|
||||
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
||||
(unsigned long)data +
|
||||
STUB_DATA_PAGES * UM_KERN_PAGE_SIZE / 2);
|
||||
if (err) {
|
||||
data->parent_err = err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
|
||||
if (err) {
|
||||
data->child_err = err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
remap_stack_and_trap();
|
||||
|
||||
done:
|
||||
trap_myself();
|
||||
}
|
||||
+34
-20
@@ -14,11 +14,14 @@
|
||||
#include <as-layout.h>
|
||||
#include <os.h>
|
||||
#include <skas.h>
|
||||
#include <stub-data.h>
|
||||
|
||||
/* Ensure the stub_data struct covers the allocated area */
|
||||
static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
|
||||
|
||||
int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
{
|
||||
struct mm_context *from_mm = NULL;
|
||||
struct mm_context *to_mm = &mm->context;
|
||||
struct mm_id *new_id = &mm->context.id;
|
||||
unsigned long stack = 0;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
@@ -26,34 +29,46 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
if (stack == 0)
|
||||
goto out;
|
||||
|
||||
to_mm->id.stack = stack;
|
||||
if (current->mm != NULL && current->mm != &init_mm)
|
||||
from_mm = ¤t->mm->context;
|
||||
new_id->stack = stack;
|
||||
|
||||
block_signals_trace();
|
||||
if (from_mm)
|
||||
to_mm->id.u.pid = copy_context_skas0(stack,
|
||||
from_mm->id.u.pid);
|
||||
else to_mm->id.u.pid = start_userspace(stack);
|
||||
new_id->u.pid = start_userspace(stack);
|
||||
unblock_signals_trace();
|
||||
|
||||
if (to_mm->id.u.pid < 0) {
|
||||
ret = to_mm->id.u.pid;
|
||||
if (new_id->u.pid < 0) {
|
||||
ret = new_id->u.pid;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = init_new_ldt(to_mm, from_mm);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "init_new_context_skas - init_ldt"
|
||||
" failed, errno = %d\n", ret);
|
||||
goto out_free;
|
||||
}
|
||||
/*
|
||||
* Ensure the new MM is clean and nothing unwanted is mapped.
|
||||
*
|
||||
* TODO: We should clear the memory up to STUB_START to ensure there is
|
||||
* nothing mapped there, i.e. we (currently) have:
|
||||
*
|
||||
* |- user memory -|- unused -|- stub -|- unused -|
|
||||
* ^ TASK_SIZE ^ STUB_START
|
||||
*
|
||||
* Meaning we have two unused areas where we may still have valid
|
||||
* mappings from our internal clone(). That isn't really a problem as
|
||||
* userspace is not going to access them, but it is definitely not
|
||||
* correct.
|
||||
*
|
||||
* However, we are "lucky" and if rseq is configured, then on 32 bit
|
||||
* it will fall into the first empty range while on 64 bit it is going
|
||||
* to use an anonymous mapping in the second range. As such, things
|
||||
* continue to work for now as long as we don't start unmapping these
|
||||
* areas.
|
||||
*
|
||||
* Change this to STUB_START once we have a clean userspace.
|
||||
*/
|
||||
unmap(new_id, 0, TASK_SIZE);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
if (to_mm->id.stack != 0)
|
||||
free_pages(to_mm->id.stack, ilog2(STUB_DATA_PAGES));
|
||||
if (new_id->stack != 0)
|
||||
free_pages(new_id->stack, ilog2(STUB_DATA_PAGES));
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -76,5 +91,4 @@ void destroy_context(struct mm_struct *mm)
|
||||
os_kill_ptraced_process(mmu->id.u.pid, 1);
|
||||
|
||||
free_pages(mmu->id.stack, ilog2(STUB_DATA_PAGES));
|
||||
free_ldt(mmu);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user