Re: [PATCH RESEND 3/4] docs: Add HiSilicon PTT device driver documentation

2021-04-19 Thread Yicong Yang
On 2021/4/19 17:07, Daniel Thompson wrote:
> On Sat, Apr 17, 2021 at 06:17:10PM +0800, Yicong Yang wrote:
>> Document the introduction and usage of HiSilicon PTT device driver.
>>
>> Signed-off-by: Yicong Yang 
>> ---
>>  Documentation/trace/hisi-ptt.rst | 326 
>> +++
>>  1 file changed, 326 insertions(+)
>>  create mode 100644 Documentation/trace/hisi-ptt.rst
>>
>> diff --git a/Documentation/trace/hisi-ptt.rst 
>> b/Documentation/trace/hisi-ptt.rst
>> new file mode 100644
>> index 000..f093846
>> --- /dev/null
>> +++ b/Documentation/trace/hisi-ptt.rst
>> @@ -0,0 +1,326 @@
>> [...]
>> +On Kunpeng 930 SoC, the PCIe Root Complex is composed of several
>> +PCIe cores. Each PCIe core includes several Root Ports and a PTT
>> +RCiEP, like below. The PTT device is capable of tuning and
>> +tracing the link of the PCIe core.
>> +::
>> +  +--Core 0---+
>> +  |   |   [   PTT   ] |
>> +  |   |   [Root Port]---[Endpoint]
>> +  |   |   [Root Port]---[Endpoint]
>> +  |   |   [Root Port]---[Endpoint]
>> +Root Complex  |--Core 1---+
>> +  |   |   [   PTT   ] |
>> +  |   |   [Root Port]---[ Switch ]---[Endpoint]
>> +  |   |   [Root Port]---[Endpoint] `-[Endpoint]
>> +  |   |   [Root Port]---[Endpoint]
>> +  +---+
>> +
>> +The PTT device driver cannot be loaded if debugfs is not mounted.
> 
> This can't be right can it? Obviously debugfs must be enabled but why
> mounted?
> 

just mention the limit as I'm not sure it's always be mounted.

> 
>> +Each PTT device will be presented under /sys/kernel/debugfs/hisi_ptt
>> +as its root directory, with name of its BDF number.
>> +::
>> +
>> +/sys/kernel/debug/hisi_ptt/::.
>> +
>> +Tune
>> +
>> +
>> +PTT tune is designed for monitoring and adjusting PCIe link parameters 
>> (events).
>> +Currently we support events in 4 classes. The scope of the events
>> +covers the PCIe core to which the PTT device belongs.
>> +
>> +Each event is presented as a file under $(PTT root dir)/$(BDF)/tune, and
>> +mostly a simple open/read/write/close cycle will be used to tune
>> +the event.
>> +::
>> +$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tune
>> +$ ls
>> +qos_tx_cplqos_tx_npqos_tx_p
>> +tx_path_rx_req_alloc_buf_level
>> +tx_path_tx_req_alloc_buf_level
>> +$ cat qos_tx_dp
>> +1
>> +$ echo 2 > qos_tx_dp
>> +$ cat qos_tx_dp
>> +2
>> +
>> +Current value (numerical value) of the event can be simply read
>> +from the file, and the desired value written to the file to tune.
> 
> I saw that this RFC asks about whether debugfs is an appropriate
> interface for the *tracing* capability of the platform. Have similar
> questions been raised about the tuning interfaces?
> 

yes. as well.

> It looks to me like tuning could be handled entirely using sysfs
> attributes. I think trying to handle these mostly decoupled feature
> in the same place is likely to be a mistake.
> 

Tuning and tracing are two separate functions and it does make sense
to decouple them. Thanks for the advice, we can make tuning using
sysfs attributes as debugfs is not encouraged.

Regards,
Yicong

> 
> Daniel.
> 
> .
> 



Re: [PATCH RESEND 3/4] docs: Add HiSilicon PTT device driver documentation

2021-04-19 Thread Daniel Thompson
On Sat, Apr 17, 2021 at 06:17:10PM +0800, Yicong Yang wrote:
> Document the introduction and usage of HiSilicon PTT device driver.
> 
> Signed-off-by: Yicong Yang 
> ---
>  Documentation/trace/hisi-ptt.rst | 326 
> +++
>  1 file changed, 326 insertions(+)
>  create mode 100644 Documentation/trace/hisi-ptt.rst
> 
> diff --git a/Documentation/trace/hisi-ptt.rst 
> b/Documentation/trace/hisi-ptt.rst
> new file mode 100644
> index 000..f093846
> --- /dev/null
> +++ b/Documentation/trace/hisi-ptt.rst
> @@ -0,0 +1,326 @@
> [...]
> +On Kunpeng 930 SoC, the PCIe Root Complex is composed of several
> +PCIe cores. Each PCIe core includes several Root Ports and a PTT
> +RCiEP, like below. The PTT device is capable of tuning and
> +tracing the link of the PCIe core.
> +::
> +  +--Core 0---+
> +  |   |   [   PTT   ] |
> +  |   |   [Root Port]---[Endpoint]
> +  |   |   [Root Port]---[Endpoint]
> +  |   |   [Root Port]---[Endpoint]
> +Root Complex  |--Core 1---+
> +  |   |   [   PTT   ] |
> +  |   |   [Root Port]---[ Switch ]---[Endpoint]
> +  |   |   [Root Port]---[Endpoint] `-[Endpoint]
> +  |   |   [Root Port]---[Endpoint]
> +  +---+
> +
> +The PTT device driver cannot be loaded if debugfs is not mounted.

This can't be right can it? Obviously debugfs must be enabled but why
mounted?


> +Each PTT device will be presented under /sys/kernel/debugfs/hisi_ptt
> +as its root directory, with name of its BDF number.
> +::
> +
> +/sys/kernel/debug/hisi_ptt/::.
> +
> +Tune
> +
> +
> +PTT tune is designed for monitoring and adjusting PCIe link parameters 
> (events).
> +Currently we support events in 4 classes. The scope of the events
> +covers the PCIe core to which the PTT device belongs.
> +
> +Each event is presented as a file under $(PTT root dir)/$(BDF)/tune, and
> +mostly a simple open/read/write/close cycle will be used to tune
> +the event.
> +::
> +$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tune
> +$ ls
> +qos_tx_cplqos_tx_npqos_tx_p
> +tx_path_rx_req_alloc_buf_level
> +tx_path_tx_req_alloc_buf_level
> +$ cat qos_tx_dp
> +1
> +$ echo 2 > qos_tx_dp
> +$ cat qos_tx_dp
> +2
> +
> +Current value (numerical value) of the event can be simply read
> +from the file, and the desired value written to the file to tune.

I saw that this RFC asks about whether debugfs is an appropriate
interface for the *tracing* capability of the platform. Have similar
questions been raised about the tuning interfaces?

It looks to me like tuning could be handled entirely using sysfs
attributes. I think trying to handle these mostly decoupled feature
in the same place is likely to be a mistake.


Daniel.


[PATCH RESEND 3/4] docs: Add HiSilicon PTT device driver documentation

2021-04-17 Thread Yicong Yang
Document the introduction and usage of HiSilicon PTT device driver.

Signed-off-by: Yicong Yang 
---
 Documentation/trace/hisi-ptt.rst | 326 +++
 1 file changed, 326 insertions(+)
 create mode 100644 Documentation/trace/hisi-ptt.rst

diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
new file mode 100644
index 000..f093846
--- /dev/null
+++ b/Documentation/trace/hisi-ptt.rst
@@ -0,0 +1,326 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==
+HiSilicon PCIe Tune and Trace device
+==
+
+Introduction
+
+
+HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
+integrated Endpoint (RCiEP) device, providing the capability
+to dynamically monitor and tune the PCIe link's events (tune),
+and trace the TLP headers (trace). The two functions are independent,
+but is recommended to use them together to analyze and enhance the
+PCIe link's performance.
+
+On Kunpeng 930 SoC, the PCIe Root Complex is composed of several
+PCIe cores. Each PCIe core includes several Root Ports and a PTT
+RCiEP, like below. The PTT device is capable of tuning and
+tracing the link of the PCIe core.
+::
+  +--Core 0---+
+  |   |   [   PTT   ] |
+  |   |   [Root Port]---[Endpoint]
+  |   |   [Root Port]---[Endpoint]
+  |   |   [Root Port]---[Endpoint]
+Root Complex  |--Core 1---+
+  |   |   [   PTT   ] |
+  |   |   [Root Port]---[ Switch ]---[Endpoint]
+  |   |   [Root Port]---[Endpoint] `-[Endpoint]
+  |   |   [Root Port]---[Endpoint]
+  +---+
+
+The PTT device driver cannot be loaded if debugfs is not mounted.
+Each PTT device will be presented under /sys/kernel/debugfs/hisi_ptt
+as its root directory, with name of its BDF number.
+::
+
+/sys/kernel/debug/hisi_ptt/::.
+
+Tune
+
+
+PTT tune is designed for monitoring and adjusting PCIe link parameters 
(events).
+Currently we support events in 4 classes. The scope of the events
+covers the PCIe core to which the PTT device belongs.
+
+Each event is presented as a file under $(PTT root dir)/$(BDF)/tune, and
+mostly a simple open/read/write/close cycle will be used to tune
+the event.
+::
+$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tune
+$ ls
+qos_tx_cplqos_tx_npqos_tx_p
+tx_path_rx_req_alloc_buf_level
+tx_path_tx_req_alloc_buf_level
+$ cat qos_tx_dp
+1
+$ echo 2 > qos_tx_dp
+$ cat qos_tx_dp
+2
+
+Current value (numerical value) of the event can be simply read
+from the file, and the desired value written to the file to tune.
+
+1. Tx path QoS control
+
+
+The following files are provided to tune the QoS of the tx path of
+the PCIe core.
+
+- qos_tx_cpl: weight of Tx completion TLPs
+- qos_tx_np: weight of Tx non-posted TLPs
+- qos_tx_p: weight of Tx posted TLPs
+
+The weight influences the proportion of certain packets on the PCIe link.
+For example, for the storage scenario, increase the proportion
+of the completion packets on the link to enhance the performance as
+more completions are consumed.
+
+The available tune data of these events is [0, 1, 2].
+Writing a negative value will return an error, and out of range
+values will be converted to 2. Note that the event value just
+indicates a probable level, but is not precise.
+
+2. Tx path buffer control
+-
+
+Following files are provided to tune the buffer of tx path of the PCIe core.
+
+- tx_path_rx_req_alloc_buf_level: watermark of Rx requested
+- tx_path_tx_req_alloc_buf_level: watermark of Tx requested
+
+These events influence the watermark of the buffer allocated for each
+type. Rx means the inbound while Tx means outbound. The packets will
+be stored in the buffer first and then posted either when the watermark
+reached or when timed out. For a busy direction, you should increase
+the related buffer watermark to avoid frequently posting and thus
+enhance the performance. In most cases just keep the default value.
+
+The available tune data of above events is [0, 1, 2].
+Writing a negative value will return an error, and out of range
+values will be converted to 2. Note that the event value just
+indicates a probable level, but is not precise.
+
+Trace
+=
+
+PTT trace is designed for dumping the TLP headers to the memory, which
+can be used to analyze the transactions and usage condition of the PCIe
+Link. You can choose to filter the traced headers by either requester ID,
+or those downstream of a set of Root Ports on the same core of the PTT
+device. It's also supported to trace the headers of certain type and of
+certain direction.
+
+In order to start trace, you need to configure the parameters first.
+The parameters files are provided under $(PTT root dir)/$(BDF)/tr

[GIT PULL] TPM DEVICE DRIVER updates for v5.13

2021-04-14 Thread Jarkko Sakkinen
Hi,

New features:

1. ARM TEE backend for kernel trusted keys to complete the existing TPM
   backend.
2. ASN.1 format for TPM2 trusted keys to make them interact with the
   user space stack, such as OpenConnect VPN.

Other than that, contains bunch of bug fixes.

/Jarkko

The following changes since commit 50987beca096a7ed4f453a6da245fd6a2fadedeb:

  Merge tag 'trace-v5.12-rc7' of 
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace (2021-04-13 
18:40:00 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/ 
tags/tpmdd-next-v5.13

for you to fetch changes up to aec00aa04b1131e17e6744681b380779f89d77b3:

  KEYS: trusted: Fix missing null return from kzalloc call (2021-04-14 16:30:31 
+0300)


tpmdd updates for Linux v5.13


Colin Ian King (1):
  KEYS: trusted: Fix missing null return from kzalloc call

James Bottomley (5):
  lib: Add ASN.1 encoder
  oid_registry: Add TCG defined OIDS for TPM keys
  security: keys: trusted: fix TPM2 authorizations
  security: keys: trusted: use ASN.1 TPM2 key format for the blobs
  security: keys: trusted: Make sealed key properly interoperable

Stefan Berger (3):
  tpm: efi: Use local variable for calculating final log size
  tpm: acpi: Check eventlog signature before using it
  tpm: vtpm_proxy: Avoid reading host log when using a virtual device

Sumit Garg (4):
  KEYS: trusted: Add generic trusted keys framework
  KEYS: trusted: Introduce TEE based Trusted Keys
  doc: trusted-encrypted: updates with TEE as a new trust source
  MAINTAINERS: Add entry for TEE based Trusted Keys

Zhihao Cheng (1):
  char: tpm: fix error return code in tpm_cr50_i2c_tis_recv()

 Documentation/admin-guide/kernel-parameters.txt   |  12 +
 Documentation/security/keys/trusted-encrypted.rst | 229 +--
 MAINTAINERS   |   8 +
 drivers/char/tpm/eventlog/acpi.c  |  33 +-
 drivers/char/tpm/eventlog/common.c|   3 +
 drivers/char/tpm/eventlog/efi.c   |  29 +-
 drivers/char/tpm/tpm_tis_i2c_cr50.c   |   1 +
 include/keys/trusted-type.h   |  55 +++
 include/keys/trusted_tee.h|  16 +
 include/keys/trusted_tpm.h|  29 +-
 include/linux/asn1_encoder.h  |  32 ++
 include/linux/oid_registry.h  |   5 +
 include/linux/tpm.h   |   2 +
 lib/Kconfig   |   3 +
 lib/Makefile  |   1 +
 lib/asn1_encoder.c| 454 ++
 security/keys/Kconfig |   3 +
 security/keys/trusted-keys/Makefile   |   6 +
 security/keys/trusted-keys/tpm2key.asn1   |  11 +
 security/keys/trusted-keys/trusted_core.c | 360 +
 security/keys/trusted-keys/trusted_tee.c  | 318 +++
 security/keys/trusted-keys/trusted_tpm1.c | 398 +--
 security/keys/trusted-keys/trusted_tpm2.c | 269 +++--
 23 files changed, 1887 insertions(+), 390 deletions(-)
 create mode 100644 include/keys/trusted_tee.h
 create mode 100644 include/linux/asn1_encoder.h
 create mode 100644 lib/asn1_encoder.c
 create mode 100644 security/keys/trusted-keys/tpm2key.asn1
 create mode 100644 security/keys/trusted-keys/trusted_core.c
 create mode 100644 security/keys/trusted-keys/trusted_tee.c


Re: Device driver location for the PCIe root port's DMA engine

2021-04-13 Thread Bjorn Helgaas
On Tue, Apr 13, 2021 at 11:42:15PM +0530, Vidya Sagar wrote:
> On 4/13/2021 3:23 AM, Bjorn Helgaas wrote:

> > The existing port services (AER, DPC, hotplug, etc) are things the
> > device advertises via the PCI Capabilities defined by the generic PCIe
> > spec, and in my opinion the support for them should be directly part
> > of the PCI core and activated when the relevant Capability is present.
> Is there an on-going activity to remove port service drivers are move
> AER/DPC/Hotplug etc.. handling within PCI core?

No, not that I'm aware of.  I'd just like to avoid extending that
model.

Bjorn


Re: Device driver location for the PCIe root port's DMA engine

2021-04-13 Thread Vidya Sagar




On 4/13/2021 11:43 PM, Rob Herring wrote:

External email: Use caution opening links or attachments


On Mon, Apr 12, 2021 at 12:01 PM Vidya Sagar  wrote:


Hi
I'm starting this mail to seek advice on the best approach to be taken
to add support for the driver of the PCIe root port's DMA engine.
To give some background, Tegra194's PCIe IPs are dual-mode PCIe IPs i.e.
they work either in the root port mode or in the endpoint mode based on
the boot time configuration.
Since the PCIe hardware IP as such is the same for both (RP and EP)
modes, the DMA engine sub-system of the PCIe IP is also made available
to both modes of operation.
Typically, the DMA engine is seen only in the endpoint mode, and that
DMA engine’s configuration registers are made available to the host
through one of its BARs.
In the situation that we have here, where there is a DMA engine present
as part of the root port, the DMA engine isn’t a typical general-purpose
DMA engine in the sense that it can’t have both source and destination
addresses targeting external memory addresses.
RP’s DMA engine, while doing a write operation,
would always fetch data (i.e. source) from local memory and write it to
the remote memory over PCIe link (i.e. destination would be the BAR of
an endpoint)
whereas while doing a read operation,
would always fetch/read data (i.e. source) from a remote memory over the
PCIe link and write it to the local memory.

I see that there are at least two ways we can have a driver for this DMA
engine.
a) DMA engine driver as one of the port service drivers
 Since the DMA engine is a part of the root port hardware itself
(although it is not part of the standard capabilities of the root port),
it is one of the options to have the driver for the DMA engine go as one
of the port service drivers (along with AER, PME, hot-plug, etc...).
Based on Vendor-ID and Device-ID matching runtime, either it gets
binded/enabled (like in the case of Tegra194) or it doesn't.
b) DMA engine driver as a platform driver
 The DMA engine hardware can be described as a sub-node under the PCIe
controller's node in the device tree and a separate platform driver can
be written to work with it.


DT expects PCI bridge child nodes to be a PCI device. We've already
broken that with the interrupt controller child nodes, but I don't
really want to add more.
Understood. Is there any other way of specifying the DMA functionality 
other than as a child node so that it is inline with the DT framework's 
expectations?





I’m inclined to have the DMA engine driver as a port service driver as
it makes it cleaner and also in line with the design philosophy (the way
I understood it) of the port service drivers.
Please let me know your thoughts on this.


What is the actual usecase and benefit for using the DMA engine with
the RP? The only one I've come up with is the hardware designers think
having DMA is better than not having DMA so they include that option
on the DWC controller.
In Tegra194-to-Tegra194 configuration (with one Tegra194 as RP and the 
other as EP) better performance is expected when DMA engines on both 
sides are used for pushing(writing) the data across instead of using 
only the EP's DMA engine for both push(write) and pull(read).




Rob



Re: Device driver location for the PCIe root port's DMA engine

2021-04-13 Thread Rob Herring
On Mon, Apr 12, 2021 at 12:01 PM Vidya Sagar  wrote:
>
> Hi
> I'm starting this mail to seek advice on the best approach to be taken
> to add support for the driver of the PCIe root port's DMA engine.
> To give some background, Tegra194's PCIe IPs are dual-mode PCIe IPs i.e.
> they work either in the root port mode or in the endpoint mode based on
> the boot time configuration.
> Since the PCIe hardware IP as such is the same for both (RP and EP)
> modes, the DMA engine sub-system of the PCIe IP is also made available
> to both modes of operation.
> Typically, the DMA engine is seen only in the endpoint mode, and that
> DMA engine’s configuration registers are made available to the host
> through one of its BARs.
> In the situation that we have here, where there is a DMA engine present
> as part of the root port, the DMA engine isn’t a typical general-purpose
> DMA engine in the sense that it can’t have both source and destination
> addresses targeting external memory addresses.
> RP’s DMA engine, while doing a write operation,
> would always fetch data (i.e. source) from local memory and write it to
> the remote memory over PCIe link (i.e. destination would be the BAR of
> an endpoint)
> whereas while doing a read operation,
> would always fetch/read data (i.e. source) from a remote memory over the
> PCIe link and write it to the local memory.
>
> I see that there are at least two ways we can have a driver for this DMA
> engine.
> a) DMA engine driver as one of the port service drivers
> Since the DMA engine is a part of the root port hardware itself
> (although it is not part of the standard capabilities of the root port),
> it is one of the options to have the driver for the DMA engine go as one
> of the port service drivers (along with AER, PME, hot-plug, etc...).
> Based on Vendor-ID and Device-ID matching runtime, either it gets
> binded/enabled (like in the case of Tegra194) or it doesn't.
> b) DMA engine driver as a platform driver
> The DMA engine hardware can be described as a sub-node under the PCIe
> controller's node in the device tree and a separate platform driver can
> be written to work with it.

DT expects PCI bridge child nodes to be a PCI device. We've already
broken that with the interrupt controller child nodes, but I don't
really want to add more.

> I’m inclined to have the DMA engine driver as a port service driver as
> it makes it cleaner and also in line with the design philosophy (the way
> I understood it) of the port service drivers.
> Please let me know your thoughts on this.

What is the actual usecase and benefit for using the DMA engine with
the RP? The only one I've come up with is the hardware designers think
having DMA is better than not having DMA so they include that option
on the DWC controller.

Rob


Re: Device driver location for the PCIe root port's DMA engine

2021-04-13 Thread Vidya Sagar




On 4/13/2021 3:23 AM, Bjorn Helgaas wrote:

External email: Use caution opening links or attachments


[+cc Matthew for portdrv comment]

On Mon, Apr 12, 2021 at 10:31:02PM +0530, Vidya Sagar wrote:

Hi
I'm starting this mail to seek advice on the best approach to be taken to
add support for the driver of the PCIe root port's DMA engine.
To give some background, Tegra194's PCIe IPs are dual-mode PCIe IPs i.e.
they work either in the root port mode or in the endpoint mode based on the
boot time configuration.
Since the PCIe hardware IP as such is the same for both (RP and EP) modes,
the DMA engine sub-system of the PCIe IP is also made available to both
modes of operation.
Typically, the DMA engine is seen only in the endpoint mode, and that DMA
engine’s configuration registers are made available to the host through one
of its BARs.
In the situation that we have here, where there is a DMA engine present as
part of the root port, the DMA engine isn’t a typical general-purpose DMA
engine in the sense that it can’t have both source and destination addresses
targeting external memory addresses.
RP’s DMA engine, while doing a write operation,
would always fetch data (i.e. source) from local memory and write it to the
remote memory over PCIe link (i.e. destination would be the BAR of an
endpoint)
whereas while doing a read operation,
would always fetch/read data (i.e. source) from a remote memory over the
PCIe link and write it to the local memory.

I see that there are at least two ways we can have a driver for this DMA
engine.
a) DMA engine driver as one of the port service drivers
   Since the DMA engine is a part of the root port hardware itself (although
it is not part of the standard capabilities of the root port), it is one of
the options to have the driver for the DMA engine go as one of the port
service drivers (along with AER, PME, hot-plug, etc...). Based on Vendor-ID
and Device-ID matching runtime, either it gets binded/enabled (like in the
case of Tegra194) or it doesn't.
b) DMA engine driver as a platform driver
   The DMA engine hardware can be described as a sub-node under the PCIe
controller's node in the device tree and a separate platform driver can be
written to work with it.

I’m inclined to have the DMA engine driver as a port service driver as it
makes it cleaner and also in line with the design philosophy (the way I
understood it) of the port service drivers.
Please let me know your thoughts on this.


Personally I'm not a fan of the port service driver model.  It creates
additional struct devices for things that are not separate devices.
And it creates a parallel hierarchy in /sys/bus/pci_express/devices/
that I think does not accurately model the hardware.

Agree.



The existing port services (AER, DPC, hotplug, etc) are things the
device advertises via the PCI Capabilities defined by the generic PCIe
spec, and in my opinion the support for them should be directly part
of the PCI core and activated when the relevant Capability is present.
Is there an on-going activity to remove port service drivers are move 
AER/DPC/Hotplug etc.. handling within PCI core?




The DMA engine is different -- this is device-specific functionality
and I think the obvious way to discover it and bind a driver to it is
via the PCI Vendor and Device ID.

This *is* complicated by the fact that you can't just use
pci_register_driver() to claim functionality implemented in Root Ports
or Switch Ports because portdrv binds to them before you have a
chance.  I think that's a defect in the portdrv design.  The usual
Yes. Hence I was thinking of adding a service driver for the DMA 
functionality



workaround is to use pci_get_device(), which has its own issues (it's
ugly, it's outside the normal driver binding model, doesn't work
nicely with hotplug or udev, doesn't coordinate with other drivers
using the same device, etc).  There are many examples of this in the
EDAC code.
I didn't think of approaching this issue in this way. Thanks for the 
pointers to EDAC code. I'll wait for comments from Matthew before I 
proceed with this approach.




Bjorn



[RESEND PATCH v3 3/3] watchdog: f71808e_wdt: refactor to platform device/driver pair

2021-04-13 Thread Ahmad Fatoum
Driver so far wasn't ported to the driver model and registered
the watchdog device out of the init after probing the I/O ports
for a watchdog with correct vendor and device revision.

Keep the device detection part at init time, but move watchdog
registration to a platform driver probe function.

Suggested-by: Guenter Roeck 
Signed-off-by: Ahmad Fatoum 
---
 drivers/watchdog/f71808e_wdt.c | 42 +++
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 5496d2bb0089..e96f2c274b80 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define DRVNAME "f71808e_wdt"
@@ -432,10 +433,18 @@ static const struct watchdog_ops fintek_wdt_ops = {
.set_timeout = fintek_wdt_set_timeout,
 };
 
-static int __init watchdog_init(int sioaddr)
+static int fintek_wdt_probe(struct platform_device *pdev)
 {
struct watchdog_device *wdd;
int wdt_conf, err = 0;
+   struct resource *res;
+   int sioaddr;
+
+   res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+   if (!res)
+   return -ENXIO;
+
+   sioaddr = res->start;
 
watchdog.sioaddr = sioaddr;
watchdog.ident.options = WDIOF_SETTIMEOUT
@@ -468,6 +477,7 @@ static int __init watchdog_init(int sioaddr)
 
superio_exit(sioaddr);
 
+   wdd->parent = >dev;
wdd->info   = 
wdd->ops= _wdt_ops;
wdd->min_timeout= 1;
@@ -488,7 +498,7 @@ static int __init watchdog_init(int sioaddr)
fintek_wdt_set_timeout(wdd, timeout);
fintek_wdt_set_pulse_width(pulse_width);
 
-   return watchdog_register_device(wdd);
+   return devm_watchdog_register_device(>dev, wdd);
 }
 
 static int __init fintek_wdt_find(int sioaddr)
@@ -554,9 +564,19 @@ static int __init fintek_wdt_find(int sioaddr)
return err;
 }
 
+static struct platform_driver fintek_wdt_driver = {
+   .probe  = fintek_wdt_probe,
+   .driver = {
+   .name   = DRVNAME,
+   },
+};
+
+static struct platform_device *fintek_wdt_pdev;
+
 static int __init fintek_wdt_init(void)
 {
static const unsigned short addrs[] = { 0x2e, 0x4e };
+   struct resource wdt_res = {};
int err = -ENODEV;
int i;
 
@@ -573,12 +593,26 @@ static int __init fintek_wdt_init(void)
if (i == ARRAY_SIZE(addrs))
return err;
 
-   return watchdog_init(addrs[i]);
+   platform_driver_register(_wdt_driver);
+
+   wdt_res.name = "superio port";
+   wdt_res.flags = IORESOURCE_IO;
+   wdt_res.start = addrs[i];
+   wdt_res.end   = addrs[i] + 1;
+
+   fintek_wdt_pdev = platform_device_register_simple(DRVNAME, -1, 
_res, 1);
+   if (IS_ERR(fintek_wdt_pdev)) {
+   platform_driver_unregister(_wdt_driver);
+   return PTR_ERR(fintek_wdt_pdev);
+   }
+
+   return 0;
 }
 
 static void __exit fintek_wdt_exit(void)
 {
-   watchdog_unregister_device();
+   platform_device_unregister(fintek_wdt_pdev);
+   platform_driver_unregister(_wdt_driver);
 }
 
 MODULE_DESCRIPTION("F71808E Watchdog Driver");
-- 
git-series 0.9.1


Re: Device driver location for the PCIe root port's DMA engine

2021-04-12 Thread Bjorn Helgaas
[+cc Matthew for portdrv comment]

On Mon, Apr 12, 2021 at 10:31:02PM +0530, Vidya Sagar wrote:
> Hi
> I'm starting this mail to seek advice on the best approach to be taken to
> add support for the driver of the PCIe root port's DMA engine.
> To give some background, Tegra194's PCIe IPs are dual-mode PCIe IPs i.e.
> they work either in the root port mode or in the endpoint mode based on the
> boot time configuration.
> Since the PCIe hardware IP as such is the same for both (RP and EP) modes,
> the DMA engine sub-system of the PCIe IP is also made available to both
> modes of operation.
> Typically, the DMA engine is seen only in the endpoint mode, and that DMA
> engine’s configuration registers are made available to the host through one
> of its BARs.
> In the situation that we have here, where there is a DMA engine present as
> part of the root port, the DMA engine isn’t a typical general-purpose DMA
> engine in the sense that it can’t have both source and destination addresses
> targeting external memory addresses.
> RP’s DMA engine, while doing a write operation,
> would always fetch data (i.e. source) from local memory and write it to the
> remote memory over PCIe link (i.e. destination would be the BAR of an
> endpoint)
> whereas while doing a read operation,
> would always fetch/read data (i.e. source) from a remote memory over the
> PCIe link and write it to the local memory.
> 
> I see that there are at least two ways we can have a driver for this DMA
> engine.
> a) DMA engine driver as one of the port service drivers
>   Since the DMA engine is a part of the root port hardware itself 
> (although
> it is not part of the standard capabilities of the root port), it is one of
> the options to have the driver for the DMA engine go as one of the port
> service drivers (along with AER, PME, hot-plug, etc...). Based on Vendor-ID
> and Device-ID matching runtime, either it gets binded/enabled (like in the
> case of Tegra194) or it doesn't.
> b) DMA engine driver as a platform driver
>   The DMA engine hardware can be described as a sub-node under the PCIe
> controller's node in the device tree and a separate platform driver can be
> written to work with it.
> 
> I’m inclined to have the DMA engine driver as a port service driver as it
> makes it cleaner and also in line with the design philosophy (the way I
> understood it) of the port service drivers.
> Please let me know your thoughts on this.

Personally I'm not a fan of the port service driver model.  It creates
additional struct devices for things that are not separate devices.
And it creates a parallel hierarchy in /sys/bus/pci_express/devices/
that I think does not accurately model the hardware.

The existing port services (AER, DPC, hotplug, etc) are things the
device advertises via the PCI Capabilities defined by the generic PCIe
spec, and in my opinion the support for them should be directly part
of the PCI core and activated when the relevant Capability is present.

The DMA engine is different -- this is device-specific functionality
and I think the obvious way to discover it and bind a driver to it is
via the PCI Vendor and Device ID.

This *is* complicated by the fact that you can't just use
pci_register_driver() to claim functionality implemented in Root Ports
or Switch Ports because portdrv binds to them before you have a
chance.  I think that's a defect in the portdrv design.  The usual
workaround is to use pci_get_device(), which has its own issues (it's
ugly, it's outside the normal driver binding model, doesn't work
nicely with hotplug or udev, doesn't coordinate with other drivers
using the same device, etc).  There are many examples of this in the
EDAC code.

Bjorn


Device driver location for the PCIe root port's DMA engine

2021-04-12 Thread Vidya Sagar

Hi
I'm starting this mail to seek advice on the best approach to be taken 
to add support for the driver of the PCIe root port's DMA engine.
To give some background, Tegra194's PCIe IPs are dual-mode PCIe IPs i.e. 
they work either in the root port mode or in the endpoint mode based on 
the boot time configuration.
Since the PCIe hardware IP as such is the same for both (RP and EP) 
modes, the DMA engine sub-system of the PCIe IP is also made available 
to both modes of operation.
Typically, the DMA engine is seen only in the endpoint mode, and that 
DMA engine’s configuration registers are made available to the host 
through one of its BARs.
In the situation that we have here, where there is a DMA engine present 
as part of the root port, the DMA engine isn’t a typical general-purpose 
DMA engine in the sense that it can’t have both source and destination 
addresses targeting external memory addresses.

RP’s DMA engine, while doing a write operation,
would always fetch data (i.e. source) from local memory and write it to 
the remote memory over PCIe link (i.e. destination would be the BAR of 
an endpoint)

whereas while doing a read operation,
would always fetch/read data (i.e. source) from a remote memory over the 
PCIe link and write it to the local memory.


I see that there are at least two ways we can have a driver for this DMA 
engine.

a) DMA engine driver as one of the port service drivers
	Since the DMA engine is a part of the root port hardware itself 
(although it is not part of the standard capabilities of the root port), 
it is one of the options to have the driver for the DMA engine go as one 
of the port service drivers (along with AER, PME, hot-plug, etc...). 
Based on Vendor-ID and Device-ID matching runtime, either it gets 
binded/enabled (like in the case of Tegra194) or it doesn't.

b) DMA engine driver as a platform driver
	The DMA engine hardware can be described as a sub-node under the PCIe 
controller's node in the device tree and a separate platform driver can 
be written to work with it.


I’m inclined to have the DMA engine driver as a port service driver as 
it makes it cleaner and also in line with the design philosophy (the way 
I understood it) of the port service drivers.

Please let me know your thoughts on this.

Thanks,
Vidya Sagar



Re: [PATCH 3/4] docs: Add documentation for HiSilicon PTT device driver

2021-04-09 Thread Yicong Yang
On 2021/4/9 0:57, Bjorn Helgaas wrote:
> On Thu, Apr 08, 2021 at 09:22:52PM +0800, Yicong Yang wrote:
>> On 2021/4/8 2:55, Bjorn Helgaas wrote:
>>> On Tue, Apr 06, 2021 at 08:45:53PM +0800, Yicong Yang wrote:
> 
 +On Kunpeng 930 SoC, the PCIe root complex is composed of several
 +PCIe cores.
>>
>>> Can you connect "Kunpeng 930" to something in the kernel tree?
>>> "git grep -i kunpeng" shows nothing that's obviously relevant.
>>> I assume there's a related driver in drivers/pci/controller/?
>>
>> Kunpeng 930 is the product name of Hip09 platform. The PCIe
>> controller uses the generic PCIe driver based on ACPI.
> 
> I guess I'm just looking for a hint to help users know when to enable
> the Kconfig for this.  Maybe the "HiSilicon" in the Kconfig help is
> enough?  Maybe "Kunpeng 930" is not even necessary?  If "Kunpeng 930"
> *is* necessary, there should be some way to relate it to something
> else.
> 

since it's added in Kunpeng 930. otherwise users maybe confused why they
don't find it on Kunpeng 920 (Hip 08) or older platforms. The Kunpeng is
the product name, users should have known it when they have such a platform.

 +from the file, and the desired value written to the file to tune.
>>>
 +Tuning multiple events at the same time is not permitted, which means
 +you cannot read or write more than one tune file at one time.
>>>
>>> I think this is obvious from the model, so the sentence doesn't really
>>> add anything.  Each event is a separate file, and it's obvious that
>>> there's no way to write to multiple files simultaneously.
>>
>> from the usage we shown below this situation won't happen. I just worry
>> that users may have a program to open multiple files at the same time and
>> read/write simultaneously, so add this line here to mention the restriction.
> 
> How is this possible?  I don't think "writing multiple files
> simultaneously" is even possible in the Linux syscall model.  I don't
> think a user will do anything differently after reading "you cannot
> read or write more than one tune file at one time."
> 
then I'll remove this line. thanks.
 +- tx_path_rx_req_alloc_buf_level: watermark of RX requested
 +- tx_path_tx_req_alloc_buf_level: watermark of TX requested
 +
 +These events influence the watermark of the buffer allocated for each
 +type. RX means the inbound while Tx means outbound. For a busy
 +direction, you should increase the related buffer watermark to enhance
 +the performance.
>>>
>>> Based on what you have written here, I would just write 2 to both
>>> files to enhance the performance in both directions.  But obviously
>>> there must be some tradeoff here, e.g., increasing Rx performance
>>> comes at the cost of Tx performane.
>>
>> the Rx buffer and Tx buffer are separate, so they won't influence
>> each other.
> 
> Why would I write anything other than 2 to these files?  That's the
> question I think this paragraph should answer.
> 

In most cases just keep the normal level.

the data in the buffer will be posted when reaching the watermark
or timed out. for some situation you have an idle traffic but you
want a quick response, then set the watermark in lower level.

 +9. data_format
 +--
 +
 +File to indicate the format of the traced TLP headers. User can also
 +specify the desired format of traced TLP headers. Available formats
 +are 4DW, 8DW which indicates the length of each TLP headers traced.
 +::
 +$ cat data_format
 +[4DW]8DW
 +$ echo 8 > data_format
 +$ cat data_format
 +4DW [8DW]
 +
 +The traced TLP header format is different from the PCIe standard.
>>>
>>> I'm confused.  Below you say the fields of the traced TLP header are
>>> defined by the PCIe spec.  But here you say the format is *different*.
>>> What exactly is different?
>>
>> For the Request Header Format for 64-bit addressing of Memory, defind in
>> PCIe spec 4.0, Figure 2-15, the 1st DW is like:
>>
>> Byte 0 > [Fmt] [Type] [T9] [Tc] [T8] [Attr] [LN] [TH] ... [Length]
>>
>> some are recorded in our traced header like below, which some are not.
>> that's what I mean the format of the header are different. But for a
>> certain field like 'Fmt', the meaning keeps same with what Spec defined.
>> that's what I mean the fields definition of our traced header keep same
>> with the Spec.
> 
> Ah, that helps a lot, thank you.  Maybe you could say something along
> the lines of this:
> 
>   When using the 8DW data format, the entire TLP header is logged.
>   For example, the TLP header for Memory Reads with 64-bit addresses
>   is shown in PCIe r5.0, Figure 2-17; the header for Configuration
>   Requests is shown in Figure 2.20, etc.
> 
>   In addition, 8DW trace buffer entries contain a timestamp and
>   possibly a prefix, e.g., a PASID TLP prefix (see Figure 6-20).  TLPs
>   may include more than one prefix, but only one can be logged in
>   trace buffer entries.
> 

Fwd: Function Level Reset notification to PCIe device driver

2021-04-09 Thread ragas gupta
 Hello, 
  
 This query is regarding Function level reset feature for SRIOV. 
 As per code in Linux PCIe driver the function level reset is done by writing 
“1” to “reset” under sysfs interface. 
 e.g. “echo 1 > /sys/bus/pci/devices/ /reset “ 
  
 As function level reset is not triggered via the PCIe device driver how PCIe 
device driver can get the notification of the function level reset(FLR)? 



Re: [PATCH 3/4] docs: Add documentation for HiSilicon PTT device driver

2021-04-08 Thread Bjorn Helgaas
On Thu, Apr 08, 2021 at 09:22:52PM +0800, Yicong Yang wrote:
> On 2021/4/8 2:55, Bjorn Helgaas wrote:
> > On Tue, Apr 06, 2021 at 08:45:53PM +0800, Yicong Yang wrote:

> >> +On Kunpeng 930 SoC, the PCIe root complex is composed of several
> >> +PCIe cores.
> 
> > Can you connect "Kunpeng 930" to something in the kernel tree?
> > "git grep -i kunpeng" shows nothing that's obviously relevant.
> > I assume there's a related driver in drivers/pci/controller/?
> 
> Kunpeng 930 is the product name of Hip09 platform. The PCIe
> controller uses the generic PCIe driver based on ACPI.

I guess I'm just looking for a hint to help users know when to enable
the Kconfig for this.  Maybe the "HiSilicon" in the Kconfig help is
enough?  Maybe "Kunpeng 930" is not even necessary?  If "Kunpeng 930"
*is* necessary, there should be some way to relate it to something
else.

> >> +from the file, and the desired value written to the file to tune.
> > 
> >> +Tuning multiple events at the same time is not permitted, which means
> >> +you cannot read or write more than one tune file at one time.
> > 
> > I think this is obvious from the model, so the sentence doesn't really
> > add anything.  Each event is a separate file, and it's obvious that
> > there's no way to write to multiple files simultaneously.
> 
> from the usage we shown below this situation won't happen. I just worry
> that users may have a program to open multiple files at the same time and
> read/write simultaneously, so add this line here to mention the restriction.

How is this possible?  I don't think "writing multiple files
simultaneously" is even possible in the Linux syscall model.  I don't
think a user will do anything differently after reading "you cannot
read or write more than one tune file at one time."

> >> +- tx_path_rx_req_alloc_buf_level: watermark of RX requested
> >> +- tx_path_tx_req_alloc_buf_level: watermark of TX requested
> >> +
> >> +These events influence the watermark of the buffer allocated for each
> >> +type. RX means the inbound while Tx means outbound. For a busy
> >> +direction, you should increase the related buffer watermark to enhance
> >> +the performance.
> > 
> > Based on what you have written here, I would just write 2 to both
> > files to enhance the performance in both directions.  But obviously
> > there must be some tradeoff here, e.g., increasing Rx performance
> > comes at the cost of Tx performane.
> 
> the Rx buffer and Tx buffer are separate, so they won't influence
> each other.

Why would I write anything other than 2 to these files?  That's the
question I think this paragraph should answer.

> >> +9. data_format
> >> +--
> >> +
> >> +File to indicate the format of the traced TLP headers. User can also
> >> +specify the desired format of traced TLP headers. Available formats
> >> +are 4DW, 8DW which indicates the length of each TLP headers traced.
> >> +::
> >> +$ cat data_format
> >> +[4DW]8DW
> >> +$ echo 8 > data_format
> >> +$ cat data_format
> >> +4DW [8DW]
> >> +
> >> +The traced TLP header format is different from the PCIe standard.
> > 
> > I'm confused.  Below you say the fields of the traced TLP header are
> > defined by the PCIe spec.  But here you say the format is *different*.
> > What exactly is different?
> 
> For the Request Header Format for 64-bit addressing of Memory, defind in
> PCIe spec 4.0, Figure 2-15, the 1st DW is like:
> 
> Byte 0 > [Fmt] [Type] [T9] [Tc] [T8] [Attr] [LN] [TH] ... [Length]
> 
> some are recorded in our traced header like below, which some are not.
> that's what I mean the format of the header are different. But for a
> certain field like 'Fmt', the meaning keeps same with what Spec defined.
> that's what I mean the fields definition of our traced header keep same
> with the Spec.

Ah, that helps a lot, thank you.  Maybe you could say something along
the lines of this:

  When using the 8DW data format, the entire TLP header is logged.
  For example, the TLP header for Memory Reads with 64-bit addresses
  is shown in PCIe r5.0, Figure 2-17; the header for Configuration
  Requests is shown in Figure 2.20, etc.

  In addition, 8DW trace buffer entries contain a timestamp and
  possibly a prefix, e.g., a PASID TLP prefix (see Figure 6-20).  TLPs
  may include more than one prefix, but only one can be logged in
  trace buffer entries.

  When using the 4DW data format, DW0 of the trace buffer entry
  contains selected fields of DW0 of the TLP, together with a
  timestamp.  DW1-DW3 of the trace buffer entry contain DW1-DW3
  directly from the TLP header.

This looks like a really cool device.  I wish we had this for more
platforms.

Bjorn


Re: [PATCH 3/4] docs: Add documentation for HiSilicon PTT device driver

2021-04-08 Thread Yicong Yang
On 2021/4/8 2:55, Bjorn Helgaas wrote:
> Move important info in the subject earlier, e.g.,
> 
>   docs: Add HiSilicon PTT device documentation
> 
> On Tue, Apr 06, 2021 at 08:45:53PM +0800, Yicong Yang wrote:
>> Document the introduction and usage of HiSilicon PTT device driver.
>>
>> Signed-off-by: Yicong Yang 
>> ---
>>  Documentation/trace/hisi-ptt.rst | 316 
>> +++
>>  1 file changed, 316 insertions(+)
>>  create mode 100644 Documentation/trace/hisi-ptt.rst
>>
>> diff --git a/Documentation/trace/hisi-ptt.rst 
>> b/Documentation/trace/hisi-ptt.rst
>> new file mode 100644
>> index 000..215676f
>> --- /dev/null
>> +++ b/Documentation/trace/hisi-ptt.rst
>> @@ -0,0 +1,316 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +==
>> +HiSilicon PCIe Tune and Trace device
>> +==
>> +
>> +Introduction
>> +
>> +
>> +HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
>> +integrated Endpoint (RCiEP) device, providing the capability
>> +to dynamically monitor and tune the PCIe link's events (tune),
>> +and trace the TLP headers (trace). The two functions are independent,
>> +but is recommended to use them together to analyze and enhance the
>> +PCIe link's performance.
> 
>> +On Kunpeng 930 SoC, the PCIe root complex is composed of several
>> +PCIe cores.
>> +Each core is composed of several root ports, RCiEPs, and one
>> +PTT device, like below. The PTT device is capable of tuning and
>> +tracing the link of the PCIe core.
> 
> s/root complex/Root Complex/ to match spec, diagram, RCiEP above
> s/root ports/Root Ports/ to match spec, etc (also below)
> 

thanks. will fix here and below in this doc.

> Can you connect "Kunpeng 930" to something in the kernel tree?
> "git grep -i kunpeng" shows nothing that's obviously relevant.
> I assume there's a related driver in drivers/pci/controller/?
> 

Kunpeng 930 is the product name of Hip09 platform. The PCIe
controller uses the generic PCIe driver based on ACPI.

> Is this one paragraph or two?  If one, reflow.  If two, add blank line
> between.
> 

will reflow here and below. it's one paragraph.

> IIUC, the diagram below shows two PCIe cores, each with three Root
> Ports and a PTT RCiEP.  Your text mentions "RCiEPs, and one PTT" which
> suggests RCiEPs in addition to the PTT, but the diagram doesn't show
> any, and if there are other RCiEPs, they don't seem relevant to this
> doc.  Maybe something like this?
> 
>   Each PCIe core includes several Root Ports and a PTT RCiEP ...
> 

will fix.

>> +::
>> +  +--Core 0---+
>> +  |   |   [   PTT   ] |
>> +  |   |   [Root Port]---[Endpoint]
>> +  |   |   [Root Port]---[Endpoint]
>> +  |   |   [Root Port]---[Endpoint]
>> +Root Complex  |--Core 1---+
>> +  |   |   [   PTT   ] |
>> +  |   |   [Root Port]---[ Switch ]---[Endpoint]
>> +  |   |   [Root Port]---[Endpoint] `-[Endpoint]
>> +  |   |   [Root Port]---[Endpoint]
>> +  +---+
>> +
>> +The PTT device driver cannot be loaded if debugfs is not mounted.
>> +Each PTT device will be presented under /sys/kernel/debugfs/hisi_ptt
>> +as its root directory, with name of its BDF number.
>> +::
>> +
>> +/sys/kernel/debug/hisi_ptt/::.
>> +
>> +Tune
>> +
>> +
>> +PTT tune is designed for monitoring and adjusting PCIe link 
>> parameters(events).
> 
> Add a space before "(".
> 

will add here and below.

>> +Currently we support events in 4 classes. The scope of the events
>> +covers the PCIe core with which the PTT device belongs to.
> 
> ... the PCIe core to which the PTT device belongs.

will fix.

>> +
>> +Each event is presented as a file under $(PTT root dir)/$(BDF)/tune, and
>> +mostly a simple open/read/write/close cycle will be used to tune
>> +the event.
>> +::
>> +$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tune
>> +$ ls
>> +qos_tx_cplqos_tx_npqos_tx_p
>> +tx_path_rx_req_alloc_buf_level
>> +tx_path_tx_req_alloc_buf_level
>> +$ cat qos_tx_dp
>> +1
>> +$ echo 2 > qos_tx_dp
>> +$ cat qos_tx_dp
>> +2
>> +
>> +Current value(numerical value) of the event can be simply read
> 
> Add space before &

Re: [PATCH 3/4] docs: Add documentation for HiSilicon PTT device driver

2021-04-07 Thread Bjorn Helgaas
Move important info in the subject earlier, e.g.,

  docs: Add HiSilicon PTT device documentation

On Tue, Apr 06, 2021 at 08:45:53PM +0800, Yicong Yang wrote:
> Document the introduction and usage of HiSilicon PTT device driver.
> 
> Signed-off-by: Yicong Yang 
> ---
>  Documentation/trace/hisi-ptt.rst | 316 
> +++
>  1 file changed, 316 insertions(+)
>  create mode 100644 Documentation/trace/hisi-ptt.rst
> 
> diff --git a/Documentation/trace/hisi-ptt.rst 
> b/Documentation/trace/hisi-ptt.rst
> new file mode 100644
> index 000..215676f
> --- /dev/null
> +++ b/Documentation/trace/hisi-ptt.rst
> @@ -0,0 +1,316 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==
> +HiSilicon PCIe Tune and Trace device
> +==
> +
> +Introduction
> +
> +
> +HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
> +integrated Endpoint (RCiEP) device, providing the capability
> +to dynamically monitor and tune the PCIe link's events (tune),
> +and trace the TLP headers (trace). The two functions are independent,
> +but is recommended to use them together to analyze and enhance the
> +PCIe link's performance.

> +On Kunpeng 930 SoC, the PCIe root complex is composed of several
> +PCIe cores.
> +Each core is composed of several root ports, RCiEPs, and one
> +PTT device, like below. The PTT device is capable of tuning and
> +tracing the link of the PCIe core.

s/root complex/Root Complex/ to match spec, diagram, RCiEP above
s/root ports/Root Ports/ to match spec, etc (also below)

Can you connect "Kunpeng 930" to something in the kernel tree?
"git grep -i kunpeng" shows nothing that's obviously relevant.
I assume there's a related driver in drivers/pci/controller/?

Is this one paragraph or two?  If one, reflow.  If two, add blank line
between.

IIUC, the diagram below shows two PCIe cores, each with three Root
Ports and a PTT RCiEP.  Your text mentions "RCiEPs, and one PTT" which
suggests RCiEPs in addition to the PTT, but the diagram doesn't show
any, and if there are other RCiEPs, they don't seem relevant to this
doc.  Maybe something like this?

  Each PCIe core includes several Root Ports and a PTT RCiEP ...

> +::
> +  +--Core 0---+
> +  |   |   [   PTT   ] |
> +  |   |   [Root Port]---[Endpoint]
> +  |   |   [Root Port]---[Endpoint]
> +  |   |   [Root Port]---[Endpoint]
> +Root Complex  |--Core 1---+
> +  |   |   [   PTT   ] |
> +  |   |   [Root Port]---[ Switch ]---[Endpoint]
> +  |       |   [Root Port]---[Endpoint] `-[Endpoint]
> +  |   |   [Root Port]---[Endpoint]
> +  +---+
> +
> +The PTT device driver cannot be loaded if debugfs is not mounted.
> +Each PTT device will be presented under /sys/kernel/debugfs/hisi_ptt
> +as its root directory, with name of its BDF number.
> +::
> +
> +/sys/kernel/debug/hisi_ptt/::.
> +
> +Tune
> +
> +
> +PTT tune is designed for monitoring and adjusting PCIe link 
> parameters(events).

Add a space before "(".

> +Currently we support events in 4 classes. The scope of the events
> +covers the PCIe core with which the PTT device belongs to.

... the PCIe core to which the PTT device belongs.
> +
> +Each event is presented as a file under $(PTT root dir)/$(BDF)/tune, and
> +mostly a simple open/read/write/close cycle will be used to tune
> +the event.
> +::
> +$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tune
> +$ ls
> +qos_tx_cplqos_tx_npqos_tx_p
> +tx_path_rx_req_alloc_buf_level
> +tx_path_tx_req_alloc_buf_level
> +$ cat qos_tx_dp
> +1
> +$ echo 2 > qos_tx_dp
> +$ cat qos_tx_dp
> +2
> +
> +Current value(numerical value) of the event can be simply read

Add space before "(".

> +from the file, and the desired value written to the file to tune.

> +Tuning multiple events at the same time is not permitted, which means
> +you cannot read or write more than one tune file at one time.

I think this is obvious from the model, so the sentence doesn't really
add anything.  Each event is a separate file, and it's obvious that
there's no way to write to multiple files simultaneously.

> +1. Tx path QoS control
> +
> +
> +Following files are provided to tune the QoS of the tx path of the PCIe core.

"The following ..."

> +- qos_tx_cpl: weight of tx completion TLPs
> +- qos_tx_np: weight of tx non-posted TLPs
> +- qos_tx_p: weight of tx posted TLPs
> +
> +The weight inf

[PATCH 3/4] docs: Add documentation for HiSilicon PTT device driver

2021-04-06 Thread Yicong Yang
Document the introduction and usage of HiSilicon PTT device driver.

Signed-off-by: Yicong Yang 
---
 Documentation/trace/hisi-ptt.rst | 316 +++
 1 file changed, 316 insertions(+)
 create mode 100644 Documentation/trace/hisi-ptt.rst

diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
new file mode 100644
index 000..215676f
--- /dev/null
+++ b/Documentation/trace/hisi-ptt.rst
@@ -0,0 +1,316 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==
+HiSilicon PCIe Tune and Trace device
+==
+
+Introduction
+
+
+HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
+integrated Endpoint (RCiEP) device, providing the capability
+to dynamically monitor and tune the PCIe link's events (tune),
+and trace the TLP headers (trace). The two functions are independent,
+but is recommended to use them together to analyze and enhance the
+PCIe link's performance.
+
+On Kunpeng 930 SoC, the PCIe root complex is composed of several
+PCIe cores.
+Each core is composed of several root ports, RCiEPs, and one
+PTT device, like below. The PTT device is capable of tuning and
+tracing the link of the PCIe core.
+::
+  +--Core 0---+
+  |   |   [   PTT   ] |
+  |   |   [Root Port]---[Endpoint]
+  |   |   [Root Port]---[Endpoint]
+  |   |   [Root Port]---[Endpoint]
+Root Complex  |--Core 1---+
+  |   |   [   PTT   ] |
+  |   |   [Root Port]---[ Switch ]---[Endpoint]
+  |   |   [Root Port]---[Endpoint] `-[Endpoint]
+  |   |   [Root Port]---[Endpoint]
+  +---+
+
+The PTT device driver cannot be loaded if debugfs is not mounted.
+Each PTT device will be presented under /sys/kernel/debugfs/hisi_ptt
+as its root directory, with name of its BDF number.
+::
+
+/sys/kernel/debug/hisi_ptt/::.
+
+Tune
+
+
+PTT tune is designed for monitoring and adjusting PCIe link parameters(events).
+Currently we support events in 4 classes. The scope of the events
+covers the PCIe core with which the PTT device belongs to.
+
+Each event is presented as a file under $(PTT root dir)/$(BDF)/tune, and
+mostly a simple open/read/write/close cycle will be used to tune
+the event.
+::
+$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tune
+$ ls
+qos_tx_cplqos_tx_npqos_tx_p
+tx_path_rx_req_alloc_buf_level
+tx_path_tx_req_alloc_buf_level
+$ cat qos_tx_dp
+1
+$ echo 2 > qos_tx_dp
+$ cat qos_tx_dp
+2
+
+Current value(numerical value) of the event can be simply read
+from the file, and the desired value written to the file to tune.
+Tuning multiple events at the same time is not permitted, which means
+you cannot read or write more than one tune file at one time.
+
+1. Tx path QoS control
+
+
+Following files are provided to tune the QoS of the tx path of the PCIe core.
+
+- qos_tx_cpl: weight of tx completion TLPs
+- qos_tx_np: weight of tx non-posted TLPs
+- qos_tx_p: weight of tx posted TLPs
+
+The weight influences the proportion of certain packets on the PCIe link.
+For example, for the storage scenario, increase the proportion
+of the completion packets on the link to enhance the performance as
+more completions are consumed.
+
+The available tune data of these events is [0, 1, 2].
+Writing a negative value will return an error, and out of range
+values will be converted to 2. Note that the event value just
+indicates a probable level, but is not precise.
+
+2. Tx path buffer control
+-
+
+Following files are provided to tune the buffer of tx path of the PCIe core.
+
+- tx_path_rx_req_alloc_buf_level: watermark of RX requested
+- tx_path_tx_req_alloc_buf_level: watermark of TX requested
+
+These events influence the watermark of the buffer allocated for each
+type. RX means the inbound while Tx means outbound. For a busy
+direction, you should increase the related buffer watermark to enhance
+the performance.
+
+The available tune data of above events is [0, 1, 2].
+Writing a negative value will return an error, and out of range
+values will be converted to 2. Note that the event value just
+indicates a probable level, but is not precise.
+
+Trace
+=
+
+PTT trace is designed for dumping the TLP headers to the memory, which
+can be used to analyze the transactions and usage condition of the PCIe
+Link. You can chose to filter the traced headers by either requester ID,
+or those downstream of a set of root ports on the same core of the PTT
+device. It's also support to trace the headers of certain type and of
+certain direction.
+
+In order to start trace, you need to configure the parameters first.
+The parameters files is provided under $(PTT root dir)/$(BDF)/trace.
+::
+$ cd /sys/kernel/debug/hisi_ptt/$(BDF)/tr

Re: [PATCH] MAINTAINERS: Update MCAN MMIO device driver maintainer

2021-03-19 Thread Marc Kleine-Budde
On 18.03.2021 16:56:34, Pankaj Sharma wrote:
> Update Chandrasekar Ramakrishnan as maintainer for mcan mmio device driver as 
> I
> will be moving to a different role.

Applied to can-next/testing.

regards,
Marc

-- 
Pengutronix e.K. | Marc Kleine-Budde   |
Embedded Linux   | https://www.pengutronix.de  |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917- |


signature.asc
Description: PGP signature


[PATCH] MAINTAINERS: Update MCAN MMIO device driver maintainer

2021-03-18 Thread Pankaj Sharma
Update Chandrasekar Ramakrishnan as maintainer for mcan mmio device driver as I
will be moving to a different role.

Signed-off-by: Pankaj Sharma 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a50a543e3c81..76db44337f6c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10820,7 +10820,7 @@ F:  drivers/media/radio/radio-maxiradio*
 
 MCAN MMIO DEVICE DRIVER
 M: Dan Murphy 
-M: Pankaj Sharma 
+M: Chandrasekar Ramakrishnan 
 L: linux-...@vger.kernel.org
 S: Maintained
 F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
-- 
2.17.1



Re: [GIT PULL] TPM DEVICE DRIVER changes for v5.12-rc2

2021-03-04 Thread pr-tracker-bot
The pull request you sent on Wed, 3 Mar 2021 17:52:40 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/ 
> tags/tpmdd-next-v5.12-rc2

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/3cb60ee6323968b694208c4cbd56a7176396e931

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


[GIT PULL] TPM DEVICE DRIVER changes for v5.12-rc2

2021-03-03 Thread Jarkko Sakkinen
Hi Linus,

Three urgent fixes for rc2.

/Jarkko

The following changes since commit c03c21ba6f4e95e406a1a7b4c34ef334b977c194:

  Merge tag 'keys-misc-20210126' of 
git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs (2021-02-23 
16:09:23 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/ 
tags/tpmdd-next-v5.12-rc2

for you to fetch changes up to 232a37ea3aee9cb37bbc154fb1440a66ae4743f4:

  tpm: Remove unintentional dump_stack() call (2021-03-03 17:43:52 +0200)


tpmdd updates for Linux v5.12-rc2


Jarkko Sakkinen (2):
  tpm, tpm_tis: Decorate tpm_get_timeouts() with request_locality()
  tpm: Remove unintentional dump_stack() call

Lukasz Majczak (1):
  tpm, tpm_tis: Decorate tpm_tis_gen_interrupt() with request_locality()

 drivers/char/tpm/tpm-chip.c |  2 --
 drivers/char/tpm/tpm_tis_core.c | 30 +-
 2 files changed, 25 insertions(+), 7 deletions(-)


Re: [GIT PULL] TPM DEVICE DRIVER changes for v5.12

2021-02-21 Thread pr-tracker-bot
The pull request you sent on Thu, 18 Feb 2021 05:31:29 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/ 
> tags/tpmdd-next-v5.12-rc1-v2

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/a2b095e0efa7229a1a88602283ba1a8a32004851

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


[GIT PULL] TPM DEVICE DRIVER changes for v5.12

2021-02-17 Thread Jarkko Sakkinen
Hi Linus,

This now my "official" first PR for v5.12. There's still some known issues
in the tpm_tis driver *not& fixed in this first pull request, which trigger a
warning but do not overally collapse the kernel by any means.

The fixes are in good progress, but unfortunately there's still some fine
tuning required before I can include to a pull request. I'm sure we will
get them done around rc2/rc3. Better to make sure that the fixes do right
things right, rather than rush them to a PR.

That's also the reason why this comes so late. Sorry about that. I have
also kind of "reorg" going on with my maintainer workflows, given the
increased review activity in keyrings and SGX, which temporarily causes
a bit overhead until becoming "status quo".

New features


1. Cr50 I2C TPM driver.
2. Sysfs exports of PCR registers in TPM 2.0 chips.

Bug fixes
=

*  This contains bug fixes for tpm_tis driver, which had a racy wait for
   hardware state change to be ready to send a command to the TPM chip. The
   bug has existed already since 2006, but has only made itself known in
   recent past. This is the same as the "last time" :-)
*  Otherwise there's bunch of fixes for not as alarming regressions. I
   think the list is about the same as last time, except I added fixes for
   some disjoint bugs in trusted keys that I found some time ago.

/Jarkko

The following changes since commit f40ddce88593482919761f74910f42f4b84c004b:

  Linux 5.11 (2021-02-14 14:32:24 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/ 
tags/tpmdd-next-v5.12-rc1-v2

for you to fetch changes up to 8c657a0590de585b1115847c17b34a58025f2f4b:

  KEYS: trusted: Reserve TPM for seal and unseal operations (2021-02-16 
10:40:28 +0200)


tpmdd updates for Linux v5.12-rc1


Andrew Zaborowski (1):
  keys: Update comment for restrict_link_by_key_or_keyring_chain

Duncan Laurie (1):
  char: tpm: add i2c driver for cr50

Gustavo A. R. Silva (1):
  tpm: Fix fall-through warnings for Clang

James Bottomley (4):
  tpm_tis: Fix check_locality for correct locality acquisition
  tpm_tis: Clean up locality release
  tpm: add sysfs exports for all banks of PCR registers
  ABI: add sysfs description for tpm exports of PCR registers

Jarkko Sakkinen (3):
  KEYS: trusted: Fix incorrect handling of tpm_get_random()
  KEYS: trusted: Fix migratable=1 failing
  KEYS: trusted: Reserve TPM for seal and unseal operations

Rikard Falkeborn (1):
  tpm/ppi: Constify static struct attribute_group

Sebastian Andrzej Siewior (1):
  tpm: Remove tpm_dev_wq_lock

 Documentation/ABI/stable/sysfs-class-tpm  |  14 +
 crypto/asymmetric_keys/restrict.c |   7 +-
 drivers/char/tpm/Kconfig  |  10 +
 drivers/char/tpm/Makefile |   2 +
 drivers/char/tpm/eventlog/tpm1.c  |   1 +
 drivers/char/tpm/tpm-chip.c   |   2 +
 drivers/char/tpm/tpm-dev-common.c |   1 -
 drivers/char/tpm/tpm-sysfs.c  | 179 +++
 drivers/char/tpm/tpm.h|   4 -
 drivers/char/tpm/tpm_ppi.c|   2 +-
 drivers/char/tpm/tpm_tis_core.c   |  50 +-
 drivers/char/tpm/tpm_tis_i2c_cr50.c   | 790 ++
 include/linux/tpm.h   |  14 +-
 security/keys/trusted-keys/trusted_tpm1.c |  22 +-
 security/keys/trusted-keys/trusted_tpm2.c |  22 +-
 15 files changed, 1054 insertions(+), 66 deletions(-)
 create mode 100644 drivers/char/tpm/tpm_tis_i2c_cr50.c


[PATCH v3 3/3] watchdog: f71808e_wdt: refactor to platform device/driver pair

2021-02-04 Thread Ahmad Fatoum
Driver so far wasn't ported to the driver model and registered
the watchdog device out of the init after probing the I/O ports
for a watchdog with correct vendor and device revision.

Keep the device detection part at init time, but move watchdog
registration to a platform driver probe function.

Suggested-by: Guenter Roeck 
Signed-off-by: Ahmad Fatoum 
---
 drivers/watchdog/f71808e_wdt.c | 42 +++
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 5496d2bb0089..e96f2c274b80 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define DRVNAME "f71808e_wdt"
@@ -432,10 +433,18 @@ static const struct watchdog_ops fintek_wdt_ops = {
.set_timeout = fintek_wdt_set_timeout,
 };
 
-static int __init watchdog_init(int sioaddr)
+static int fintek_wdt_probe(struct platform_device *pdev)
 {
struct watchdog_device *wdd;
int wdt_conf, err = 0;
+   struct resource *res;
+   int sioaddr;
+
+   res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+   if (!res)
+   return -ENXIO;
+
+   sioaddr = res->start;
 
watchdog.sioaddr = sioaddr;
watchdog.ident.options = WDIOF_SETTIMEOUT
@@ -468,6 +477,7 @@ static int __init watchdog_init(int sioaddr)
 
superio_exit(sioaddr);
 
+   wdd->parent = >dev;
wdd->info   = 
wdd->ops= _wdt_ops;
wdd->min_timeout= 1;
@@ -488,7 +498,7 @@ static int __init watchdog_init(int sioaddr)
fintek_wdt_set_timeout(wdd, timeout);
fintek_wdt_set_pulse_width(pulse_width);
 
-   return watchdog_register_device(wdd);
+   return devm_watchdog_register_device(>dev, wdd);
 }
 
 static int __init fintek_wdt_find(int sioaddr)
@@ -554,9 +564,19 @@ static int __init fintek_wdt_find(int sioaddr)
return err;
 }
 
+static struct platform_driver fintek_wdt_driver = {
+   .probe  = fintek_wdt_probe,
+   .driver = {
+   .name   = DRVNAME,
+   },
+};
+
+static struct platform_device *fintek_wdt_pdev;
+
 static int __init fintek_wdt_init(void)
 {
static const unsigned short addrs[] = { 0x2e, 0x4e };
+   struct resource wdt_res = {};
int err = -ENODEV;
int i;
 
@@ -573,12 +593,26 @@ static int __init fintek_wdt_init(void)
if (i == ARRAY_SIZE(addrs))
return err;
 
-   return watchdog_init(addrs[i]);
+   platform_driver_register(_wdt_driver);
+
+   wdt_res.name = "superio port";
+   wdt_res.flags = IORESOURCE_IO;
+   wdt_res.start = addrs[i];
+   wdt_res.end   = addrs[i] + 1;
+
+   fintek_wdt_pdev = platform_device_register_simple(DRVNAME, -1, 
_res, 1);
+   if (IS_ERR(fintek_wdt_pdev)) {
+   platform_driver_unregister(_wdt_driver);
+   return PTR_ERR(fintek_wdt_pdev);
+   }
+
+   return 0;
 }
 
 static void __exit fintek_wdt_exit(void)
 {
-   watchdog_unregister_device();
+   platform_device_unregister(fintek_wdt_pdev);
+   platform_driver_unregister(_wdt_driver);
 }
 
 MODULE_DESCRIPTION("F71808E Watchdog Driver");
-- 
git-series 0.9.1


Re: [PATCH net-next v4 0/2] Add nci suit and virtual nci device driver

2021-01-30 Thread patchwork-bot+netdevbpf
Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Wed, 27 Jan 2021 22:08:27 +0900 you wrote:
> From: Bongsu Jeon 
> 
> 1/2 is the Virtual NCI device driver.
> 2/2 is the NCI selftest suite
> 
> v4:
>  1/2
>  - flip the condition for the ioctl.
>  - refactor some code.
>  - remove the unused function after refactoring.
> v3:
>  1/2
>  - change the Kconfig help comment.
>  - remove the mutex init code.
>  - remove the unnecessary mutex(nci_send_mutex).
>  - remove the full_txbuff.
>  - add the code to release skb at error case.
>  - refactor some code.
> v2:
>  1/2
>  - change the permission of the Virtual NCI device.
>  - add the ioctl to find the nci device index.
>  2/2
>  - add the NCI selftest suite.
> 
> [...]

Here is the summary with links:
  - [net-next,v4,1/2] nfc: Add a virtual nci device driver
https://git.kernel.org/netdev/net-next/c/e624e6c3e777
  - [net-next,v4,2/2] selftests: Add nci suite
https://git.kernel.org/netdev/net-next/c/f595cf1242f3

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




[PATCH v10 00/20] dlb: introduce DLB device driver

2021-01-27 Thread Mike Ximing Chen
Introduce a new misc device driver for the Intel(r) Dynamic Load Balancer
(Intel(r) DLB). The Intel DLB is a PCIe device that provides
load-balanced, prioritized scheduling of core-to-core communication.

Intel DLB is an accelerator for the event-driven programming model of
DPDK's Event Device Library[2]. The library is used in packet processing
pipelines that arrange for multi-core scalability, dynamic load-balancing,
and variety of packet distribution and synchronization schemes

These distribution schemes include "parallel" (packets are load-balanced
across multiple cores and processed in parallel), "ordered" (similar to
"parallel" but packets are reordered into ingress order by the device), and
"atomic" (packet flows are scheduled to a single core at a time such that
locks are not required to access per-flow data, and dynamically migrated to
ensure load-balance).

This submission supports Intel DLB 2.0 only.

The Intel DLB consists of queues and arbiters that connect producer
cores and consumer cores. The device implements load-balanced queueing
features including:
- Lock-free multi-producer/multi-consumer operation.
- Multiple priority levels for varying traffic types.
- 'Direct' traffic (i.e. multi-producer/single-consumer)
- Simple unordered load-balanced distribution.
- Atomic lock free load balancing across multiple consumers.
- Queue element reordering feature allowing ordered load-balanced
  distribution.

The fundamental unit of communication through the device is a queue entry
(QE), which consists of 8B of data and 8B of metadata (destination queue,
priority, etc.). The data field can be any type that fits within 8B.

A core's interface to the device, a "port," consists of a memory-mappable
region through which the core enqueues a queue entry, and an in-memory
queue (the "consumer queue") to which the device schedules QEs. Each QE
is enqueued to a device-managed queue, and from there scheduled to a port.
Software specifies the "linking" of queues and ports; i.e. which ports the
device is allowed to schedule to for a given queue. The device uses a
credit scheme to prevent overflow of the on-device queue storage.

Applications can interface directly with the device by mapping the port's
memory and MMIO regions into the application's address space for enqueue
and dequeue operations, but call into the kernel driver for configuration
operations. An application can also be polling- or interrupt-driven;
Intel DLB supports both modes of operation.

Device resources -- i.e. ports, queues, and credits -- are contained within
a scheduling domain. Scheduling domains are isolated from one another; a
port can only enqueue to and dequeue from queues within its scheduling
domain. A scheduling domain's resources are configured through a scheduling
domain file, which is acquired through an ioctl.

Intel DLB supports SR-IOV and Scalable IOV, and allows for a flexible
division of its resources among the PF and its virtual devices. The virtual
devices are incapable of configuring the device directly; they use a
hardware mailbox to proxy configuration requests to the PF driver. This
driver supports both PF and virtual devices, as there is significant code
re-use between the two, with device-specific behavior handled through a
callback interface.  Virtualization support will be added in a later patch
set.

The dlb driver uses ioctls as its primary interface (it makes use of sysfs
as well, to a lesser extent). The dlb device file supports a different
ioctl interface than the scheduling domain file; the dlb device file
is used for device-wide operations (including scheduling domain creation),
and the scheduling domain file supports operations on the scheduling
domain's resources (primarily resource configuration). Scheduling domains
are created dynamically (using a dlb device file ioctl) by user-space
software, and the scheduling domain file is created from an anonymous file
that is installed in the ioctl's calling process's file descriptor table.

[1] 
https://builders.intel.com/docs/networkbuilders/SKU-343247-001US-queue-management-and-load-balancing-on-intel-architecture.pdf
[2] https://doc.dpdk.org/guides/prog_guide/eventdev.html

v10:
- Addressed an issue reported by kernel test robot 
-- Add "WITH Linux-syscall-note" to the SPDX-License-Identifier in uapi
   header file dlb.h.

v9:
- Addressed all of Greg's feecback on v8, including
-- Remove function name (__func__) from dev_err() messages, that could spam log.
-- Replace list and function pointer calls in dlb_ioctl() with switch-case
   and real function calls for ioctl.
-- Drop the compat_ptr_ioctl in dlb_ops (struct file_operations).
-- Change ioctl magic number for DLB to unused 0x81 (from 'h').
-- Remove all placeholder/dummy functions in the patch set.
-- Re-arrange the comments in dlb.h so that the order is consistent with that
   of data structures referred.
-- Co

[PATCH net-next v4 1/2] nfc: Add a virtual nci device driver

2021-01-27 Thread Bongsu Jeon
From: Bongsu Jeon 

NCI virtual device simulates a NCI device to the user. It can be used to
validate the NCI module and applications. This driver supports
communication between the virtual NCI device and NCI module.

Signed-off-by: Bongsu Jeon 
---
 drivers/nfc/Kconfig  |  11 ++
 drivers/nfc/Makefile |   1 +
 drivers/nfc/virtual_ncidev.c | 215 +++
 3 files changed, 227 insertions(+)
 create mode 100644 drivers/nfc/virtual_ncidev.c

diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 75c65d339018..288c6f1c6979 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -49,6 +49,17 @@ config NFC_PORT100
 
  If unsure, say N.
 
+config NFC_VIRTUAL_NCI
+   tristate "NCI device simulator driver"
+   depends on NFC_NCI
+   help
+ NCI virtual device simulates a NCI device to the user.
+ It can be used to validate the NCI module and applications.
+ This driver supports communication between the virtual NCI device and
+ module.
+
+ If unsure, say N.
+
 source "drivers/nfc/fdp/Kconfig"
 source "drivers/nfc/pn544/Kconfig"
 source "drivers/nfc/pn533/Kconfig"
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 5393ba59b17d..7b1bfde1d971 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_NFC_ST_NCI)  += st-nci/
 obj-$(CONFIG_NFC_NXP_NCI)  += nxp-nci/
 obj-$(CONFIG_NFC_S3FWRN5)  += s3fwrn5/
 obj-$(CONFIG_NFC_ST95HF)   += st95hf/
+obj-$(CONFIG_NFC_VIRTUAL_NCI)  += virtual_ncidev.o
diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
new file mode 100644
index ..f73ee0bf3593
--- /dev/null
+++ b/drivers/nfc/virtual_ncidev.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Virtual NCI device simulation driver
+ *
+ * Copyright (C) 2020 Samsung Electrnoics
+ * Bongsu Jeon 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum virtual_ncidev_mode {
+   virtual_ncidev_enabled,
+   virtual_ncidev_disabled,
+   virtual_ncidev_disabling,
+};
+
+#define IOCTL_GET_NCIDEV_IDX0
+#define VIRTUAL_NFC_PROTOCOLS  (NFC_PROTO_JEWEL_MASK | \
+NFC_PROTO_MIFARE_MASK | \
+NFC_PROTO_FELICA_MASK | \
+NFC_PROTO_ISO14443_MASK | \
+NFC_PROTO_ISO14443_B_MASK | \
+NFC_PROTO_ISO15693_MASK)
+
+static enum virtual_ncidev_mode state;
+static struct miscdevice miscdev;
+static struct sk_buff *send_buff;
+static struct nci_dev *ndev;
+static DEFINE_MUTEX(nci_mutex);
+
+static int virtual_nci_open(struct nci_dev *ndev)
+{
+   return 0;
+}
+
+static int virtual_nci_close(struct nci_dev *ndev)
+{
+   mutex_lock(_mutex);
+   kfree_skb(send_buff);
+   send_buff = NULL;
+   mutex_unlock(_mutex);
+
+   return 0;
+}
+
+static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+{
+   mutex_lock(_mutex);
+   if (state != virtual_ncidev_enabled) {
+   mutex_unlock(_mutex);
+   return 0;
+   }
+
+   if (send_buff) {
+   mutex_unlock(_mutex);
+   return -1;
+   }
+   send_buff = skb_copy(skb, GFP_KERNEL);
+   mutex_unlock(_mutex);
+
+   return 0;
+}
+
+static struct nci_ops virtual_nci_ops = {
+   .open = virtual_nci_open,
+   .close = virtual_nci_close,
+   .send = virtual_nci_send
+};
+
+static ssize_t virtual_ncidev_read(struct file *file, char __user *buf,
+  size_t count, loff_t *ppos)
+{
+   size_t actual_len;
+
+   mutex_lock(_mutex);
+   if (!send_buff) {
+   mutex_unlock(_mutex);
+   return 0;
+   }
+
+   actual_len = min_t(size_t, count, send_buff->len);
+
+   if (copy_to_user(buf, send_buff->data, actual_len)) {
+   mutex_unlock(_mutex);
+   return -EFAULT;
+   }
+
+   skb_pull(send_buff, actual_len);
+   if (send_buff->len == 0) {
+   consume_skb(send_buff);
+   send_buff = NULL;
+   }
+   mutex_unlock(_mutex);
+
+   return actual_len;
+}
+
+static ssize_t virtual_ncidev_write(struct file *file,
+   const char __user *buf,
+   size_t count, loff_t *ppos)
+{
+   struct sk_buff *skb;
+
+   skb = alloc_skb(count, GFP_KERNEL);
+   if (!skb)
+   return -ENOMEM;
+
+   if (copy_from_user(skb_put(skb, count), buf, count)) {
+   kfree_skb(skb);
+   return -EFAULT;
+   }
+
+   nci_recv_frame(ndev, skb);
+   return count;
+}
+
+static int virtual_ncidev_open(struct inode *inode, struct file *file)
+{
+   int ret = 0;
+
+   mutex_lock(_mutex);
+   if (state != virtual_ncidev_disabled) {
+   mutex_unlock(_mutex);
+

[PATCH net-next v4 0/2] Add nci suit and virtual nci device driver

2021-01-27 Thread Bongsu Jeon
From: Bongsu Jeon 

1/2 is the Virtual NCI device driver.
2/2 is the NCI selftest suite

v4:
 1/2
 - flip the condition for the ioctl.
 - refactor some code.
 - remove the unused function after refactoring.
v3:
 1/2
 - change the Kconfig help comment.
 - remove the mutex init code.
 - remove the unnecessary mutex(nci_send_mutex).
 - remove the full_txbuff.
 - add the code to release skb at error case.
 - refactor some code.
v2:
 1/2
 - change the permission of the Virtual NCI device.
 - add the ioctl to find the nci device index.
 2/2
 - add the NCI selftest suite.

Bongsu Jeon (2):
  nfc: Add a virtual nci device driver
  selftests: Add nci suite

 MAINTAINERS   |   8 +
 drivers/nfc/Kconfig   |  11 +
 drivers/nfc/Makefile  |   1 +
 drivers/nfc/virtual_ncidev.c  | 215 +
 tools/testing/selftests/Makefile  |   1 +
 tools/testing/selftests/nci/Makefile  |   6 +
 tools/testing/selftests/nci/config|   3 +
 tools/testing/selftests/nci/nci_dev.c | 599 ++
 8 files changed, 844 insertions(+)
 create mode 100644 drivers/nfc/virtual_ncidev.c
 create mode 100644 tools/testing/selftests/nci/Makefile
 create mode 100644 tools/testing/selftests/nci/config
 create mode 100644 tools/testing/selftests/nci/nci_dev.c

-- 
2.25.1



[PATCH v9 00/20] dlb: introduce DLB device driver

2021-01-22 Thread Mike Ximing Chen
Introduce a new misc device driver for the Intel(r) Dynamic Load Balancer
(Intel(r) DLB). The Intel DLB is a PCIe device that provides
load-balanced, prioritized scheduling of core-to-core communication.

Intel DLB is an accelerator for the event-driven programming model of
DPDK's Event Device Library[2]. The library is used in packet processing
pipelines that arrange for multi-core scalability, dynamic load-balancing,
and variety of packet distribution and synchronization schemes

These distribution schemes include "parallel" (packets are load-balanced
across multiple cores and processed in parallel), "ordered" (similar to
"parallel" but packets are reordered into ingress order by the device), and
"atomic" (packet flows are scheduled to a single core at a time such that
locks are not required to access per-flow data, and dynamically migrated to
ensure load-balance).

This submission supports Intel DLB 2.0 only.

The Intel DLB consists of queues and arbiters that connect producer
cores and consumer cores. The device implements load-balanced queueing
features including:
- Lock-free multi-producer/multi-consumer operation.
- Multiple priority levels for varying traffic types.
- 'Direct' traffic (i.e. multi-producer/single-consumer)
- Simple unordered load-balanced distribution.
- Atomic lock free load balancing across multiple consumers.
- Queue element reordering feature allowing ordered load-balanced
  distribution.

The fundamental unit of communication through the device is a queue entry
(QE), which consists of 8B of data and 8B of metadata (destination queue,
priority, etc.). The data field can be any type that fits within 8B.

A core's interface to the device, a "port," consists of a memory-mappable
region through which the core enqueues a queue entry, and an in-memory
queue (the "consumer queue") to which the device schedules QEs. Each QE
is enqueued to a device-managed queue, and from there scheduled to a port.
Software specifies the "linking" of queues and ports; i.e. which ports the
device is allowed to schedule to for a given queue. The device uses a
credit scheme to prevent overflow of the on-device queue storage.

Applications can interface directly with the device by mapping the port's
memory and MMIO regions into the application's address space for enqueue
and dequeue operations, but call into the kernel driver for configuration
operations. An application can also be polling- or interrupt-driven;
Intel DLB supports both modes of operation.

Device resources -- i.e. ports, queues, and credits -- are contained within
a scheduling domain. Scheduling domains are isolated from one another; a
port can only enqueue to and dequeue from queues within its scheduling
domain. A scheduling domain's resources are configured through a scheduling
domain file, which is acquired through an ioctl.

Intel DLB supports SR-IOV and Scalable IOV, and allows for a flexible
division of its resources among the PF and its virtual devices. The virtual
devices are incapable of configuring the device directly; they use a
hardware mailbox to proxy configuration requests to the PF driver. This
driver supports both PF and virtual devices, as there is significant code
re-use between the two, with device-specific behavior handled through a
callback interface.  Virtualization support will be added in a later patch
set.

The dlb driver uses ioctls as its primary interface (it makes use of sysfs
as well, to a lesser extent). The dlb device file supports a different
ioctl interface than the scheduling domain file; the dlb device file
is used for device-wide operations (including scheduling domain creation),
and the scheduling domain file supports operations on the scheduling
domain's resources (primarily resource configuration). Scheduling domains
are created dynamically (using a dlb device file ioctl) by user-space
software, and the scheduling domain file is created from an anonymous file
that is installed in the ioctl's calling process's file descriptor table.

[1] 
https://builders.intel.com/docs/networkbuilders/SKU-343247-001US-queue-management-and-load-balancing-on-intel-architecture.pdf
[2] https://doc.dpdk.org/guides/prog_guide/eventdev.html

v9:
- Addressed all of Greg's feecback on v8, including
-- Remove function name (__func__) from dev_err() messages, that could spam log.
-- Replace list and function pointer calls in dlb_ioctl() with switch-case
   and real function callsi for ioctl.
-- Drop the compat_ptr_ioctl in dlb_ops (struct file_operations).
-- Change ioctl magic number for DLB to unused 0x81 (from 'h').
-- Remove all placeholder/dummy functions in the patch set.
-- Re-arrange the comments in dlb.h so that the order is consistent with that
   of data structures referred.
-- Correct the comments on SPDX License and DLB versions in dlb.h.
-- Replace BIT_SET() and BITS_CLR() marcos with direct coding.   
-- Remove NULL pointer checking

Re: [PATCH v7 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2021-01-12 Thread Vinod Koul
On 15-12-20, 11:09, Dongjiu Geng wrote:
> Hisilicon EDMA Controller(EDMAC) directly transfers data
> between a memory and a peripheral, between peripherals, or
> between memories. This avoids the CPU intervention and reduces
> the interrupt handling overhead of the CPU, this driver enables
> this controller.
> 
> Reported-by: kernel test robot 
> Signed-off-by: Dongjiu Geng 
> ---
>  drivers/dma/Kconfig   |   14 +
>  drivers/dma/Makefile  |1 +
>  drivers/dma/hiedmacv310.c | 1442 +
>  drivers/dma/hiedmacv310.h |  136 
>  4 files changed, 1593 insertions(+)
>  create mode 100644 drivers/dma/hiedmacv310.c
>  create mode 100644 drivers/dma/hiedmacv310.h
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 90284ffda58a..3e5107120ff1 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -327,6 +327,20 @@ config K3_DMA
> Support the DMA engine for Hisilicon K3 platform
> devices.
>  
> +config HIEDMACV310
> + tristate "Hisilicon EDMAC Controller support"
> + depends on ARCH_HISI
> + select DMA_ENGINE
> + select DMA_VIRTUAL_CHANNELS
> + help
> +   The Direction Memory Access(EDMA) is a high-speed data transfer
> +   operation. It supports data read/write between peripherals and
> +   memories without using the CPU.
> +   Hisilicon EDMA Controller(EDMAC) directly transfers data between
> +   a memory and a peripheral, between peripherals, or between memories.
> +   This avoids the CPU intervention and reduces the interrupt handling
> +   overhead of the CPU.
> +
>  config LPC18XX_DMAMUX
>   bool "NXP LPC18xx/43xx DMA MUX for PL080"
>   depends on ARCH_LPC18XX || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 948a8da05f8b..28c7298b671e 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
>  obj-$(CONFIG_ZX_DMA) += zx_dma.o
>  obj-$(CONFIG_ST_FDMA) += st_fdma.o
>  obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
> +obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
>  
>  obj-y += mediatek/
>  obj-y += qcom/
> diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
> new file mode 100644
> index ..c0df5088a6a1
> --- /dev/null
> +++ b/drivers/dma/hiedmacv310.c
> @@ -0,0 +1,1442 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * The Hiedma Controller v310 Device Driver for HiSilicon
> + *
> + * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
> + *
> + * Author: Dongjiu Geng 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

Do you need all of these? Also keep them sorted pls

> +
> +#include "hiedmacv310.h"
> +#include "dmaengine.h"
> +#include "virt-dma.h"
> +
> +#define DRIVER_NAME "hiedmacv310"
> +
> +#define MAX_TSFR_LLIS   512
> +#define EDMACV300_LLI_WORDS 64
> +#define EDMACV300_POOL_ALIGN64
> +#define BITS_PER_HALF_WORD 32

Space or tab, not both!

> +
> +struct hiedmac_lli {
> + u64 next_lli;
> + u32 reserved[5];

why reserved..?

> + u32 count;
> + u64 src_addr;
> + u64 dest_addr;
> + u32 config;
> + u32 pad[3];
> +};
> +
> +struct hiedmac_sg {
> + dma_addr_t src_addr;
> + dma_addr_t dst_addr;
> + size_t len;
> + struct list_head node;
> +};

why invent your own sg..? why not use kernel list?

> +
> +struct transfer_desc {
> + struct virt_dma_desc virt_desc;
> + dma_addr_t llis_busaddr;
> + u64 *llis_vaddr;
> + u32 ccfg;
> + size_t size;
> + bool done;
> + bool cyclic;
> +};
> +
> +enum edmac_dma_chan_state {
> + HIEDMAC_CHAN_IDLE,
> + HIEDMAC_CHAN_RUNNING,
> + HIEDMAC_CHAN_PAUSED,
> + HIEDMAC_CHAN_WAITING,
> +};
> +
> +struct hiedmacv310_dma_chan {
> + bool slave;
> + int signal;
> + int id;
> + struct virt_dma_chan virt_chan;
> + struct hiedmacv310_phy_chan *phychan;
> + struct dma_slave_config cfg;
> + struct transfer_desc *at;
> + struct hiedmacv310_driver_data *host;
> + enum edmac_dma_chan_state state;
> +};
> +
> +struct hiedmacv310_phy_chan {
> + unsigned int id;
> + void __iomem *base;
> + spinlock_t lock;
> + struct hiedmacv310_d

Re: [PATCH net-next] nfc: Add a virtual nci device driver

2021-01-07 Thread Bongsu Jeon
On Thu, Jan 7, 2021 at 2:01 AM Jakub Kicinski  wrote:
>
> On Wed, 6 Jan 2021 08:16:47 +0900 Bongsu Jeon wrote:
> > On Tue, Jan 5, 2021 at 4:48 AM Jakub Kicinski  wrote:
> > > > thank you for your answer.
> > > > I think that neard(NFC deamon) is necessary to test the NCI subsystem
> > > > meaningfully.
> > > > The NCI virtual device in user space can communicate with neard
> > > > through this driver.
> > > > Is it enough to make NCI virtual device at tools/nfc for some test?
> > >
> > > I'm not sure if I understand. Are you asking if it's okay for the test
> > > or have a dependency on neard?
> >
> > Sorry for confusing you.
> > There is no dependency between neard and a NCI virtual device.
> > But, To test the NCI module, it is necessary to make an application like 
> > neard.
> > Is it okay to just make a NCI virtual device as a tool at tools/nfc
> > without the application?
>
> Meaning the device will be created but there will be no test cases in
> the tree?

yes.

>
> What we'd like to see is some form of a test which would exercise the
> NFC-related kernel code on such a device and can signal success /
> failure. It doesn't have to be very complex.
>
> You can build a more complex user space applications and tests
> separately.

okay. I understand it. I will try to make it.


Re: [PATCH net-next] nfc: Add a virtual nci device driver

2021-01-06 Thread Jakub Kicinski
On Wed, 6 Jan 2021 08:16:47 +0900 Bongsu Jeon wrote:
> On Tue, Jan 5, 2021 at 4:48 AM Jakub Kicinski  wrote:
> > > thank you for your answer.
> > > I think that neard(NFC deamon) is necessary to test the NCI subsystem
> > > meaningfully.
> > > The NCI virtual device in user space can communicate with neard
> > > through this driver.
> > > Is it enough to make NCI virtual device at tools/nfc for some test?  
> >
> > I'm not sure if I understand. Are you asking if it's okay for the test
> > or have a dependency on neard?  
> 
> Sorry for confusing you.
> There is no dependency between neard and a NCI virtual device.
> But, To test the NCI module, it is necessary to make an application like 
> neard.
> Is it okay to just make a NCI virtual device as a tool at tools/nfc
> without the application?

Meaning the device will be created but there will be no test cases in
the tree?

What we'd like to see is some form of a test which would exercise the
NFC-related kernel code on such a device and can signal success /
failure. It doesn't have to be very complex.

You can build a more complex user space applications and tests
separately.


[PATCH v2 3/4] media: vidtv: use a simpler name in platform_{device|driver}

2021-01-05 Thread Daniel W. S. Almeida
From: "Daniel W. S. Almeida" 

Change from "vidtv_bridge" to simply "vidtv" so that vidtv looks
more similar to the other media virtual drivers in /sys/bus/platform.

Signed-off-by: Daniel W. S. Almeida 
---
 drivers/media/test-drivers/vidtv/vidtv_bridge.c | 4 ++--
 drivers/media/test-drivers/vidtv/vidtv_bridge.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c 
b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
index 405e89f62b5a..9964d1331aff 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
@@ -564,13 +564,13 @@ static void vidtv_bridge_dev_release(struct device *dev)
 }
 
 static struct platform_device vidtv_bridge_dev = {
-   .name   = "vidtv_bridge",
+   .name   = VIDTV_PDEV_NAME,
.dev.release= vidtv_bridge_dev_release,
 };
 
 static struct platform_driver vidtv_bridge_driver = {
.driver = {
-   .name= "vidtv_bridge",
+   .name = VIDTV_PDEV_NAME,
},
.probe= vidtv_bridge_probe,
.remove   = vidtv_bridge_remove,
diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.h 
b/drivers/media/test-drivers/vidtv/vidtv_bridge.h
index d42899a31295..101a26a4415f 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.h
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.h
@@ -16,6 +16,7 @@
  * For now, only one frontend is supported. See vidtv_start_streaming()
  */
 #define NUM_FE 1
+#define VIDTV_PDEV_NAME "vidtv"
 
 #include 
 #include 
-- 
2.30.0



Re: [PATCH net-next] nfc: Add a virtual nci device driver

2021-01-05 Thread Bongsu Jeon
On Tue, Jan 5, 2021 at 4:48 AM Jakub Kicinski  wrote:
>
> On Thu, 31 Dec 2020 14:22:45 +0900 Bongsu Jeon wrote:
> > On Tue, Dec 29, 2020 at 6:16 AM Jakub Kicinski  wrote:
> > >
> > > On Mon, 28 Dec 2020 18:45:07 +0900 Bongsu Jeon wrote:
> > > > From: Bongsu Jeon 
> > > >
> > > > A NCI virtual device can be made to simulate a NCI device in user space.
> > > > Using the virtual NCI device, The NCI module and application can be
> > > > validated. This driver supports to communicate between the virtual NCI
> > > > device and NCI module.
> > > >
> > > > Signed-off-by: Bongsu Jeon 
> > >
> > > net-next is still closed:
> > >
> > > http://vger.kernel.org/~davem/net-next.html
> > >
> > > Please repost in a few days.
> > >
> > > As far as the patch goes - please include some tests for the NCI/NFC
> > > subsystem based on this virtual device, best if they live in tree under
> > > tools/testing/selftest.
> >
> > thank you for your answer.
> > I think that neard(NFC deamon) is necessary to test the NCI subsystem
> > meaningfully.
> > The NCI virtual device in user space can communicate with neard
> > through this driver.
> > Is it enough to make NCI virtual device at tools/nfc for some test?
>
> I'm not sure if I understand. Are you asking if it's okay for the test
> or have a dependency on neard?

Sorry for confusing you.
There is no dependency between neard and a NCI virtual device.
But, To test the NCI module, it is necessary to make an application like neard.
Is it okay to just make a NCI virtual device as a tool at tools/nfc
without the application?


[PATCH 3/4] media: vidtv: use a simpler name in platform_{device|driver}

2021-01-05 Thread Daniel W. S. Almeida
From: "Daniel W. S. Almeida" 

Change from "vidtv_bridge" to simply "vidtv" so that vidtv looks
more similar to the other media virtual drivers in /sys/bus/platform.

Signed-off-by: Daniel W. S. Almeida 
---
 drivers/media/test-drivers/vidtv/vidtv_bridge.c | 4 ++--
 drivers/media/test-drivers/vidtv/vidtv_bridge.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c 
b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
index 4ccaa0f00639..11ee87399375 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
@@ -562,13 +562,13 @@ static void vidtv_bridge_dev_release(struct device *dev)
 }
 
 static struct platform_device vidtv_bridge_dev = {
-   .name   = "vidtv_bridge",
+   .name   = VIDTV_PDEV_NAME,
.dev.release= vidtv_bridge_dev_release,
 };
 
 static struct platform_driver vidtv_bridge_driver = {
.driver = {
-   .name= "vidtv_bridge",
+   .name = VIDTV_PDEV_NAME,
},
.probe= vidtv_bridge_probe,
.remove   = vidtv_bridge_remove,
diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.h 
b/drivers/media/test-drivers/vidtv/vidtv_bridge.h
index d42899a31295..101a26a4415f 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.h
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.h
@@ -16,6 +16,7 @@
  * For now, only one frontend is supported. See vidtv_start_streaming()
  */
 #define NUM_FE 1
+#define VIDTV_PDEV_NAME "vidtv"
 
 #include 
 #include 
-- 
2.30.0



[PATCH v8 00/20] dlb: introduce DLB device driver

2021-01-04 Thread Mike Ximing Chen
Introduce a new misc device driver for the Intel(r) Dynamic Load Balancer
(Intel(r) DLB). The Intel DLB is a PCIe device that provides
load-balanced, prioritized scheduling of core-to-core communication.

Intel DLB is an accelerator for the event-driven programming model of
DPDK's Event Device Library[2]. The library is used in packet processing
pipelines that arrange for multi-core scalability, dynamic load-balancing,
and variety of packet distribution and synchronization schemes

These distribution schemes include "parallel" (packets are load-balanced
across multiple cores and processed in parallel), "ordered" (similar to
"parallel" but packets are reordered into ingress order by the device), and
"atomic" (packet flows are scheduled to a single core at a time such that
locks are not required to access per-flow data, and dynamically migrated to
ensure load-balance).

This submission supports Intel DLB 2.0 only.

The Intel DLB consists of queues and arbiters that connect producer
cores and consumer cores. The device implements load-balanced queueing
features including:
- Lock-free multi-producer/multi-consumer operation.
- Multiple priority levels for varying traffic types.
- 'Direct' traffic (i.e. multi-producer/single-consumer)
- Simple unordered load-balanced distribution.
- Atomic lock free load balancing across multiple consumers.
- Queue element reordering feature allowing ordered load-balanced
  distribution.

The fundamental unit of communication through the device is a queue entry
(QE), which consists of 8B of data and 8B of metadata (destination queue,
priority, etc.). The data field can be any type that fits within 8B.

A core's interface to the device, a "port," consists of a memory-mappable
region through which the core enqueues a queue entry, and an in-memory
queue (the "consumer queue") to which the device schedules QEs. Each QE
is enqueued to a device-managed queue, and from there scheduled to a port.
Software specifies the "linking" of queues and ports; i.e. which ports the
device is allowed to schedule to for a given queue. The device uses a
credit scheme to prevent overflow of the on-device queue storage.

Applications can interface directly with the device by mapping the port's
memory and MMIO regions into the application's address space for enqueue
and dequeue operations, but call into the kernel driver for configuration
operations. An application can also be polling- or interrupt-driven;
Intel DLB supports both modes of operation.

Device resources -- i.e. ports, queues, and credits -- are contained within
a scheduling domain. Scheduling domains are isolated from one another; a
port can only enqueue to and dequeue from queues within its scheduling
domain. A scheduling domain's resources are configured through a scheduling
domain file, which is acquired through an ioctl.

Intel DLB supports SR-IOV and Scalable IOV, and allows for a flexible
division of its resources among the PF and its virtual devices. The virtual
devices are incapable of configuring the device directly; they use a
hardware mailbox to proxy configuration requests to the PF driver. This
driver supports both PF and virtual devices, as there is significant code
re-use between the two, with device-specific behavior handled through a
callback interface.  Virtualization support will be added in a later patch
set.

The dlb driver uses ioctls as its primary interface (it makes use of sysfs
as well, to a lesser extent). The dlb device file supports a different
ioctl interface than the scheduling domain file; the dlb device file
is used for device-wide operations (including scheduling domain creation),
and the scheduling domain file supports operations on the scheduling
domain's resources (primarily resource configuration). Scheduling domains
are created dynamically (using a dlb device file ioctl) by user-space
software, and the scheduling domain file is created from an anonymous file
that is installed in the ioctl's calling process's file descriptor table.

[1] 
https://builders.intel.com/docs/networkbuilders/SKU-343247-001US-queue-management-and-load-balancing-on-intel-architecture.pdf
[2] https://doc.dpdk.org/guides/prog_guide/eventdev.html

v8:
- Add a functional block diagram in dlb.rst 
- Modify change logs to reflect the links between patches and DPDK
  eventdev library.
- Add a check of power-of-2 for CQ depth.
- Move call to INIT_WORK() to dlb_open().
- Clean dlb workqueue by calling flush_scheduled_work().
- Add unmap_mapping_range() in dlb_port_close().

v7 (Intel internal version):
- Address all of Dan's feedback, including
-- Drop DLB 2.0 throughout the patch set, use DLB only.
-- Fix license and copyright statements
-- Use pcim_enable_device() and pcim_iomap_regions(), instead of
   unmanaged version.
-- Move cdev_add() to dlb_init() and add all devices at once.
-- Fix Makefile, using "+=" style.
-- Remove FLR description and 

Re: [PATCH net-next] nfc: Add a virtual nci device driver

2021-01-04 Thread Jakub Kicinski
On Thu, 31 Dec 2020 14:22:45 +0900 Bongsu Jeon wrote:
> On Tue, Dec 29, 2020 at 6:16 AM Jakub Kicinski  wrote:
> >
> > On Mon, 28 Dec 2020 18:45:07 +0900 Bongsu Jeon wrote:  
> > > From: Bongsu Jeon 
> > >
> > > A NCI virtual device can be made to simulate a NCI device in user space.
> > > Using the virtual NCI device, The NCI module and application can be
> > > validated. This driver supports to communicate between the virtual NCI
> > > device and NCI module.
> > >
> > > Signed-off-by: Bongsu Jeon   
> >
> > net-next is still closed:
> >
> > http://vger.kernel.org/~davem/net-next.html
> >
> > Please repost in a few days.
> >
> > As far as the patch goes - please include some tests for the NCI/NFC
> > subsystem based on this virtual device, best if they live in tree under
> > tools/testing/selftest.  
> 
> thank you for your answer.
> I think that neard(NFC deamon) is necessary to test the NCI subsystem
> meaningfully.
> The NCI virtual device in user space can communicate with neard
> through this driver.
> Is it enough to make NCI virtual device at tools/nfc for some test?

I'm not sure if I understand. Are you asking if it's okay for the test
or have a dependency on neard?


RE: [PATCH] MAINTAINERS: Update MCAN MMIO device driver maintainer

2021-01-04 Thread pankj.sharma
> From: Marc Kleine-Budde 
> Subject: Re: [PATCH] MAINTAINERS: Update MCAN MMIO device driver
> maintainer
> 
> On 1/4/21 1:31 PM, Sriram Dash wrote:
> > Update Pankaj Sharma as maintainer for mcan mmio device driver as I
> > will be moving to a different role.

Acked-by: Pankaj Sharma 

> >
> > Signed-off-by: Sriram Dash 
> > ---
> 
> Applied to linux-can/testing.
> 
> Tnx,
> Marc
> 
> --
> Pengutronix e.K. | Marc Kleine-Budde   |
> Embedded Linux   | 
> https://protect2.fireeye.com/v1/url?k=8b005a7e-
> d49b6343-8b01d131-0cc47a31309a-1e7ada642c78a62f=1=7d13a30c-
> d7d8-4a74-aa6c-6beb64121cd7=https%3A%2F%2Fwww.pengutronix.de%2F
> |
> Vertretung West/Dortmund | Phone: +49-231-2826-924 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917- |




Re: [PATCH] MAINTAINERS: Update MCAN MMIO device driver maintainer

2021-01-04 Thread Marc Kleine-Budde
On 1/4/21 1:31 PM, Sriram Dash wrote:
> Update Pankaj Sharma as maintainer for mcan mmio device driver as I
> will be moving to a different role.
> 
> Signed-off-by: Sriram Dash 
> ---

Applied to linux-can/testing.

Tnx,
Marc

-- 
Pengutronix e.K. | Marc Kleine-Budde   |
Embedded Linux   | https://www.pengutronix.de  |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917- |



signature.asc
Description: OpenPGP digital signature


[PATCH] MAINTAINERS: Update MCAN MMIO device driver maintainer

2021-01-04 Thread Sriram Dash
Update Pankaj Sharma as maintainer for mcan mmio device driver as I
will be moving to a different role.

Signed-off-by: Sriram Dash 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6eff4f7..45cea57 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10847,7 +10847,7 @@ F:  drivers/media/radio/radio-maxiradio*
 
 MCAN MMIO DEVICE DRIVER
 M: Dan Murphy 
-M: Sriram Dash 
+M: Pankaj Sharma 
 L: linux-...@vger.kernel.org
 S: Maintained
 F: Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
-- 
2.7.4



Re: [PATCH net-next] nfc: Add a virtual nci device driver

2020-12-30 Thread Bongsu Jeon
On Tue, Dec 29, 2020 at 6:16 AM Jakub Kicinski  wrote:
>
> On Mon, 28 Dec 2020 18:45:07 +0900 Bongsu Jeon wrote:
> > From: Bongsu Jeon 
> >
> > A NCI virtual device can be made to simulate a NCI device in user space.
> > Using the virtual NCI device, The NCI module and application can be
> > validated. This driver supports to communicate between the virtual NCI
> > device and NCI module.
> >
> > Signed-off-by: Bongsu Jeon 
>
> net-next is still closed:
>
> http://vger.kernel.org/~davem/net-next.html
>
> Please repost in a few days.
>
> As far as the patch goes - please include some tests for the NCI/NFC
> subsystem based on this virtual device, best if they live in tree under
> tools/testing/selftest.

thank you for your answer.
I think that neard(NFC deamon) is necessary to test the NCI subsystem
meaningfully.
The NCI virtual device in user space can communicate with neard
through this driver.
Is it enough to make NCI virtual device at tools/nfc for some test?


Re: [PATCH net-next] nfc: Add a virtual nci device driver

2020-12-28 Thread Jakub Kicinski
On Mon, 28 Dec 2020 18:45:07 +0900 Bongsu Jeon wrote:
> From: Bongsu Jeon 
> 
> A NCI virtual device can be made to simulate a NCI device in user space.
> Using the virtual NCI device, The NCI module and application can be
> validated. This driver supports to communicate between the virtual NCI
> device and NCI module.
> 
> Signed-off-by: Bongsu Jeon 

net-next is still closed:

http://vger.kernel.org/~davem/net-next.html

Please repost in a few days.

As far as the patch goes - please include some tests for the NCI/NFC
subsystem based on this virtual device, best if they live in tree under
tools/testing/selftest.


[PATCH 5.10 237/717] phy: tegra: xusb: Fix usb_phy device driver field

2020-12-28 Thread Greg Kroah-Hartman
From: JC Kuo 

[ Upstream commit 4ea0bf2a52f1eea76578eac5a9148d95f5e181c0 ]

In commit "phy: tegra: xusb: Add usb-phy support", an OTG capable PHY
device, such as phy-usb2.0 device of Jetson-TX1 platform, will be
bound to the tegra-xusb-padctl driver by the following line in
tegra_xusb_setup_usb_role_switch().

port->usb_phy.dev->driver = port->padctl->dev->driver;

With this, dev_pm_ops set of tegra-xusb-padctl driver will be invoked
for the OTG capable PHY incorrectly as below logs show.

This commit fixes the issue by assigning an empty driver to it.

[  153.451108] tegra-xusb-padctl phy-usb2.0: > 
tegra_xusb_padctl_suspend_noirq(dev=80917000)
[  153.460353] tegra-xusb-padctl phy-usb2.0:   driver: 8000114453e0 
(tegra_xusb_padctl_driver)
[  153.469245] tegra-xusb-padctl phy-usb2.0:   padctl: 829f6480
[  153.475772] tegra-xusb-padctl phy-usb2.0: soc: ef7bdd7f 
(0xef7bdd7f)
[  153.484061] Unable to handle kernel paging request at virtual address 
007bdd80004f
[  153.492132] Mem abort info:
[  153.495083]   ESR = 0x9604
[  153.498308]   EC = 0x25: DABT (current EL), IL = 32 bits
[  153.503771]   SET = 0, FnV = 0
[  153.506979]   EA = 0, S1PTW = 0
[  153.510260] Data abort info:
[  153.513200]   ISV = 0, ISS = 0x0004
[  153.517181]   CM = 0, WnR = 0
[  153.520302] [007bdd80004f] address between user and kernel address ranges
[  153.527600] Internal error: Oops: 9604 [#1] PREEMPT SMP
[  153.533231] Modules linked in: nouveau panel_simple tegra_video(C) tegra_drm 
drm_ttm_helper videobuf2_dma_contig ttm videobuf2_memops cec videobuf2_v4l2 
videobuf2_common drm_kms_helper v4l2_fwnode videodev drm mc snd_hda_codec_hdmi 
cdc_ether usbnet snd_hda_tegra r8152 crct10dif_ce snd_hda_codec snd_hda_core 
tegra_xudc host1x lp855x_bl at24 ip_tables x_tables ipv6
[  153.566417] CPU: 0 PID: 300 Comm: systemd-sleep Tainted: G C
5.10.0-rc3-next-20201113-00019-g5c064d5372b0-dirty #624
[  153.578283] Hardware name: NVIDIA Jetson TX1 Developer Kit (DT)
[  153.584281] pstate: 4005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
[  153.590381] pc : tegra_xusb_padctl_suspend_noirq+0x88/0x100
[  153.596016] lr : tegra_xusb_padctl_suspend_noirq+0x80/0x100
[  153.601632] sp : 8000120dbb60
[  153.604999] x29: 8000120dbb60 x28: 80a1df00
[  153.610430] x27: 0002 x26: 8000106f8540
[  153.615858] x25: 8000113ac4a4 x24: 80001148c198
[  153.621277] x23: 800010c4538c x22: 0002
[  153.626692] x21: 800010ccde80 x20: 829f6480
[  153.632107] x19: 80917000 x18: 0030
[  153.637521] x17:  x16: 
[  153.642933] x15: 80a1e380 x14: 74636461702d6273
[  153.648346] x13: 8000113ad058 x12: 0f39
[  153.653759] x11: 0513 x10: 800011405058
[  153.659176] x9 : f000 x8 : 8000113ad058
[  153.664590] x7 : 800011405058 x6 : 
[  153.670002] x5 :  x4 : fe908bc0
[  153.675414] x3 : fe910228 x2 : 162ef67e0581e700
[  153.680826] x1 : 162ef67e0581e700 x0 : ef7bdd7f
[  153.686241] Call trace:
[  153.688769]  tegra_xusb_padctl_suspend_noirq+0x88/0x100
[  153.694077]  __device_suspend_noirq+0x68/0x1cc
[  153.698594]  dpm_noirq_suspend_devices+0x10c/0x1d0
[  153.703456]  dpm_suspend_noirq+0x28/0xa0
[  153.707461]  suspend_devices_and_enter+0x234/0x4bc
[  153.712314]  pm_suspend+0x1e4/0x270
[  153.715868]  state_store+0x8c/0x110
[  153.719440]  kobj_attr_store+0x1c/0x30
[  153.723259]  sysfs_kf_write+0x4c/0x7c
[  153.726981]  kernfs_fop_write+0x124/0x240
[  153.731065]  vfs_write+0xe4/0x204
[  153.734449]  ksys_write+0x6c/0x100
[  153.737925]  __arm64_sys_write+0x20/0x30
[  153.741931]  el0_svc_common.constprop.0+0x78/0x1a0
[  153.746789]  do_el0_svc+0x24/0x90
[  153.750181]  el0_sync_handler+0x254/0x260
[  153.754251]  el0_sync+0x174/0x180
[  153.757663] Code: aa0303e2 94000f64 f9405680 b4e0 (f9402803)
[  153.763826] ---[ end trace 81543a3394cb409d ]---

Fixes: e8f7d2f409a1 ("phy: tegra: xusb: Add usb-phy support")

Signed-off-by: JC Kuo 
Acked-by: Thierry Reding 
Link: https://lore.kernel.org/r/20201117083803.185209-1-jc...@nvidia.com
Signed-off-by: Vinod Koul 
Signed-off-by: Sasha Levin 
---
 drivers/phy/tegra/xusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index ad88d74c18842..181a1be5f4917 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -688,7 +688,7 @@ static int tegra_xusb_setup_usb_role_switch(struct 
tegra_xusb_port *port)
 * reference to retrieve usb-phy details.
 */
port->usb_phy.dev = >pad->lanes[port->index]->dev;
-   port->usb_phy.dev->driver = port->padctl->dev->driver;
+   port->usb_phy.dev->driver = port->dev.driver;
port->usb_phy.otg->usb_phy = >usb_phy;
port->usb_phy.otg->set_peripheral = 

[PATCH net-next] nfc: Add a virtual nci device driver

2020-12-28 Thread Bongsu Jeon
From: Bongsu Jeon 

A NCI virtual device can be made to simulate a NCI device in user space.
Using the virtual NCI device, The NCI module and application can be
validated. This driver supports to communicate between the virtual NCI
device and NCI module.

Signed-off-by: Bongsu Jeon 
---
 MAINTAINERS  |   7 ++
 drivers/nfc/Kconfig  |  11 ++
 drivers/nfc/Makefile |   1 +
 drivers/nfc/virtual_ncidev.c | 216 +++
 4 files changed, 235 insertions(+)
 create mode 100644 drivers/nfc/virtual_ncidev.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a355db292486..6479a4754a1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12431,6 +12431,13 @@ F: include/net/nfc/
 F: include/uapi/linux/nfc.h
 F: net/nfc/
 
+NFC VIRTUAL NCI DEVICE DRIVER
+M: Bongsu Jeon 
+L: net...@vger.kernel.org
+L: linux-...@lists.01.org (moderated for non-subscribers)
+S: Supported
+F: drivers/nfc/virtual_ncidev.c
+
 NFS, SUNRPC, AND LOCKD CLIENTS
 M: Trond Myklebust 
 M: Anna Schumaker 
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 75c65d339018..d32c3a8937ed 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -49,6 +49,17 @@ config NFC_PORT100
 
  If unsure, say N.
 
+config NFC_VIRTUAL_NCI
+   tristate "NCI device simulator driver"
+   depends on NFC_NCI
+   help
+ A NCI virtual device can be made to simulate a NCI device in user
+ level. Using the virtual NCI device, The NCI module and application
+ can be validated. This driver supports to communicate between the
+ virtual NCI device and NCI module.
+
+ If unsure, say N.
+
 source "drivers/nfc/fdp/Kconfig"
 source "drivers/nfc/pn544/Kconfig"
 source "drivers/nfc/pn533/Kconfig"
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 5393ba59b17d..7b1bfde1d971 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_NFC_ST_NCI)  += st-nci/
 obj-$(CONFIG_NFC_NXP_NCI)  += nxp-nci/
 obj-$(CONFIG_NFC_S3FWRN5)  += s3fwrn5/
 obj-$(CONFIG_NFC_ST95HF)   += st95hf/
+obj-$(CONFIG_NFC_VIRTUAL_NCI)  += virtual_ncidev.o
diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
new file mode 100644
index ..163d0b2dda2e
--- /dev/null
+++ b/drivers/nfc/virtual_ncidev.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Virtual NCI device simulation driver
+ *
+ * Copyright (C) 2020 Samsung Electrnoics
+ * Bongsu Jeon 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum virtual_ncidev_mode {
+   virtual_ncidev_enabled,
+   virtual_ncidev_disabled,
+   virtual_ncidev_disabling,
+};
+
+#define VIRTUAL_NFC_PROTOCOLS  (NFC_PROTO_JEWEL_MASK | \
+NFC_PROTO_MIFARE_MASK | \
+NFC_PROTO_FELICA_MASK | \
+NFC_PROTO_ISO14443_MASK | \
+NFC_PROTO_ISO14443_B_MASK | \
+NFC_PROTO_ISO15693_MASK)
+
+static enum virtual_ncidev_mode state;
+static struct mutex nci_send_mutex;
+static struct miscdevice miscdev;
+static struct sk_buff *send_buff;
+static struct mutex nci_mutex;
+static struct nci_dev *ndev;
+static bool full_txbuff;
+
+static bool virtual_ncidev_check_enabled(void)
+{
+   bool ret = true;
+
+   mutex_lock(_mutex);
+   if (state != virtual_ncidev_enabled)
+   ret = false;
+   mutex_unlock(_mutex);
+
+   return ret;
+}
+
+static int virtual_nci_open(struct nci_dev *ndev)
+{
+   return 0;
+}
+
+static int virtual_nci_close(struct nci_dev *ndev)
+{
+   mutex_lock(_send_mutex);
+   if (full_txbuff)
+   kfree_skb(send_buff);
+   full_txbuff = false;
+   mutex_unlock(_send_mutex);
+
+   return 0;
+}
+
+static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+{
+   if (virtual_ncidev_check_enabled() == false)
+   return 0;
+
+   mutex_lock(_send_mutex);
+   if (full_txbuff) {
+   mutex_unlock(_send_mutex);
+   return -1;
+   }
+   send_buff = skb_copy(skb, GFP_KERNEL);
+   full_txbuff = true;
+   mutex_unlock(_send_mutex);
+
+   return 0;
+}
+
+static struct nci_ops virtual_nci_ops = {
+   .open = virtual_nci_open,
+   .close = virtual_nci_close,
+   .send = virtual_nci_send
+};
+
+static ssize_t virtual_ncidev_read(struct file *file, char __user *buf,
+  size_t count, loff_t *ppos)
+{
+   size_t actual_len;
+
+   mutex_lock(_send_mutex);
+   if (!full_txbuff) {
+   mutex_unlock(_send_mutex);
+   return 0;
+   }
+
+   actual_len = count > send_buff->len ? send_buff->len : count;
+
+   if (copy_to_user(buf, send_buff->data, actual_len)) {
+   mutex

[PATCH v7 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-14 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..c0df5088a6a1
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

Re: [PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-12-14 Thread Daniel Vetter
On Fri, Dec 11, 2020 at 06:27:05PM -0800, Jiaying Liang wrote:
> 
> On 12/9/20 4:47 AM, Daniel Vetter wrote:
> > On Tue, Dec 08, 2020 at 11:54:57AM -0800, Jiaying Liang wrote:
> > > On 12/8/20 9:12 AM, Nicolas Dufresne wrote:
> > > > Le mercredi 18 novembre 2020 à 00:06 -0800, Wendy Liang a écrit :
> > > > > Create AI engine device/partition hierarchical structure.
> > > > > 
> > > > > Each AI engine device can have multiple logical partitions(groups of 
> > > > > AI
> > > > > engine tiles). Each partition is column based and has its own node ID
> > > > > in the system. AI engine device driver manages its partitions.
> > > > > 
> > > > > Applications can access AI engine partition through the AI engine
> > > > > partition driver instance. AI engine registers write is moved to 
> > > > > kernel
> > > > > as there are registers in the AI engine array needs privilege
> > > > > permission.
> > > > Hi there, it's nice to see an effort to upstream an AI driver. I'm a 
> > > > little
> > > > worried this driver is not obvious to use from it's source code itself. 
> > > > So you
> > > > have reference to some Open Source code that demonstrate it's usage ?
> > > We have AI engine library which provides a cross platforms APIs for other
> > > 
> > > libraries/application to use the hardware. Here is the source code:
> > > 
> > > https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/drivers/aienginev2/src
> > > 
> > > The cross platforms AI engine library runs in LInux userspace it defines 
> > > how
> > > to
> > > 
> > > configure, and the kernel driver controls if what can be access and manage
> > > errors from device.
> > So I kinda ignored this driver submission because in the past all these AI
> > drivers had at best incomplete open source (usually the compiler is
> > closed, often also large parts of the runtime). I think yours would be the
> > first that breaks this trend, is that really the case? I.e. I could make
> > full use of this hw without any closed source bits to run DNN workloads
> > and things like that?
> AI engine can be used for signaling processing or high performance computing
> 
> the kernel driver works on the AI engine software library which I mentioned
> above,
> 
> which will be used by Xilinx runtime:
> https://xilinx.github.io/XRT/2020.2/html/index.html
> 
> Xilinx runtime is a layer for acceleration libraries or applications to use
> Xilinx accelerators.

Hm maybe I'm mixing things up, but it feels like there was a discussion
about the xilinx runtime in the past with a drm driver even. The hangup
was that the runtime is all open, but the offline compiler isn't. Is that
still the case, or am I mixing things up here a bit?

> e.g. it has OpenCL implementation
> > If that's the case then I think there's nothing stopping us from doing the
> > right thing and merging this driver into the right subsystem: The
> > subsystem for accelerators which their own memory and who want dma-buf
> > integration is drivers/gpu, not drivers/misc.
> 
> The AI engine kernel driver is used for device runtime configuration update,
> 
> and runtime monitoring, such as async errors detection. The buffer
> management
> 
> is out of the AI engine driver, but it is covered by Xilinx runtime:
> 
> https://github.com/Xilinx/XRT/tree/master/src/runtime_src/core/edge/drm/zocl
> 
> AI engine driver imports the DMA buf.
> 
> 
> The AI engine device is quite different to the GPU devices. The AI engine
> 
> operations are still needs driver specific ioctls.
> 
> We have more than 100 cores tiles, each tiles functions can be defined at
> compilation
> 
> time, at runtime, we load the configuration (application defined I/O
> commands) to
> 
> configure each tiles registers to set up routing, set up DMAs, configure
> local memories,
> 
> and enable the tiles.

Setting up DMA does sound like (buffer) memory management to me. Note that
the memory management that the kernel does does not necessarily translate
directly to client api buffers like opencl has. At least for gpu drivers
you have memory management in both the kernel and userspace.

> As the AI engine device hardware is different to the GPUs,
> 
> we are not able to make use of functions abstracted for GPUs, and we don't
> manage the
> 
> buffers in this driver. I am not sure if it is ok to add the driver to
> drivers/gpu but not
> 
> using abstractions from the GPU abst

Re: [PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-12-11 Thread Jiaying Liang



On 12/9/20 4:47 AM, Daniel Vetter wrote:

On Tue, Dec 08, 2020 at 11:54:57AM -0800, Jiaying Liang wrote:

On 12/8/20 9:12 AM, Nicolas Dufresne wrote:

Le mercredi 18 novembre 2020 à 00:06 -0800, Wendy Liang a écrit :

Create AI engine device/partition hierarchical structure.

Each AI engine device can have multiple logical partitions(groups of AI
engine tiles). Each partition is column based and has its own node ID
in the system. AI engine device driver manages its partitions.

Applications can access AI engine partition through the AI engine
partition driver instance. AI engine registers write is moved to kernel
as there are registers in the AI engine array needs privilege
permission.

Hi there, it's nice to see an effort to upstream an AI driver. I'm a little
worried this driver is not obvious to use from it's source code itself. So you
have reference to some Open Source code that demonstrate it's usage ?

We have AI engine library which provides a cross platforms APIs for other

libraries/application to use the hardware. Here is the source code:

https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/drivers/aienginev2/src

The cross platforms AI engine library runs in LInux userspace it defines how
to

configure, and the kernel driver controls if what can be access and manage
errors from device.

So I kinda ignored this driver submission because in the past all these AI
drivers had at best incomplete open source (usually the compiler is
closed, often also large parts of the runtime). I think yours would be the
first that breaks this trend, is that really the case? I.e. I could make
full use of this hw without any closed source bits to run DNN workloads
and things like that?
AI engine can be used for signaling processing or high performance 
computing


the kernel driver works on the AI engine software library which I 
mentioned above,


which will be used by Xilinx runtime: 
https://xilinx.github.io/XRT/2020.2/html/index.html


Xilinx runtime is a layer for acceleration libraries or applications to 
use Xilinx accelerators.


e.g. it has OpenCL implementation

If that's the case then I think there's nothing stopping us from doing the
right thing and merging this driver into the right subsystem: The
subsystem for accelerators which their own memory and who want dma-buf
integration is drivers/gpu, not drivers/misc.


The AI engine kernel driver is used for device runtime configuration update,

and runtime monitoring, such as async errors detection. The buffer 
management


is out of the AI engine driver, but it is covered by Xilinx runtime:

https://github.com/Xilinx/XRT/tree/master/src/runtime_src/core/edge/drm/zocl

AI engine driver imports the DMA buf.


The AI engine device is quite different to the GPU devices. The AI engine

operations are still needs driver specific ioctls.

We have more than 100 cores tiles, each tiles functions can be defined 
at compilation


time, at runtime, we load the configuration (application defined I/O 
commands) to


configure each tiles registers to set up routing, set up DMAs, configure 
local memories,


and enable the tiles.


As the AI engine device hardware is different to the GPUs,

we are not able to make use of functions abstracted for GPUs, and we 
don't manage the


buffers in this driver. I am not sure if it is ok to add the driver to 
drivers/gpu but not


using abstractions from the GPU abstraction.


There is another reply to the patch series to ask for clarification on 
the overview of the


driver, and I had some discussions with other team members. I will reply 
to that email


to provide more details on overall how this driver is used.

Any suggestions on how to fit the driver in the drivers/gpu or other 
drivers framework


will be much appreciated.


Thanks,

Wendy


Apologies that I'm jumping with the really big arch review when v3 is
already on the list. But last few times merging AI drivers to drivers/misc
was really just a way to avoid the merge criteria for drivers/gpu
acceleration drivers. I'd love to land the first real open AI driver in
upstream, properly.

Cheers, Daniel




Best Regards,

Wendy



Signed-off-by: Wendy Liang
Signed-off-by: Hyun Kwon
---
   MAINTAINERS    |   8 +
   drivers/misc/Kconfig   |  12 +
   drivers/misc/Makefile  |   1 +
   drivers/misc/xilinx-ai-engine/Makefile |  11 +
   drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
   drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 ++
   drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
   drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498
+
   drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
   include/uapi/linux/xlnx-ai-engine.h    | 107 +
   10 files changed, 1540 insertions(+)
   create mode 100644 drivers/misc/xilinx-ai-engine/Makefile

[PATCH v6 RESEND 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-11 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..ddf9b5d85a27
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v6 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-11 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..ddf9b5d85a27
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v6 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-11 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..ddf9b5d85a27
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

Re: [PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-12-09 Thread Daniel Vetter
On Tue, Dec 08, 2020 at 11:54:57AM -0800, Jiaying Liang wrote:
> 
> On 12/8/20 9:12 AM, Nicolas Dufresne wrote:
> > Le mercredi 18 novembre 2020 à 00:06 -0800, Wendy Liang a écrit :
> > > Create AI engine device/partition hierarchical structure.
> > > 
> > > Each AI engine device can have multiple logical partitions(groups of AI
> > > engine tiles). Each partition is column based and has its own node ID
> > > in the system. AI engine device driver manages its partitions.
> > > 
> > > Applications can access AI engine partition through the AI engine
> > > partition driver instance. AI engine registers write is moved to kernel
> > > as there are registers in the AI engine array needs privilege
> > > permission.
> > Hi there, it's nice to see an effort to upstream an AI driver. I'm a little
> > worried this driver is not obvious to use from it's source code itself. So 
> > you
> > have reference to some Open Source code that demonstrate it's usage ?
> 
> We have AI engine library which provides a cross platforms APIs for other
> 
> libraries/application to use the hardware. Here is the source code:
> 
> https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/drivers/aienginev2/src
> 
> The cross platforms AI engine library runs in LInux userspace it defines how
> to
> 
> configure, and the kernel driver controls if what can be access and manage
> errors from device.

So I kinda ignored this driver submission because in the past all these AI
drivers had at best incomplete open source (usually the compiler is
closed, often also large parts of the runtime). I think yours would be the
first that breaks this trend, is that really the case? I.e. I could make
full use of this hw without any closed source bits to run DNN workloads
and things like that?

If that's the case then I think there's nothing stopping us from doing the
right thing and merging this driver into the right subsystem: The
subsystem for accelerators which their own memory and who want dma-buf
integration is drivers/gpu, not drivers/misc.

Apologies that I'm jumping with the really big arch review when v3 is
already on the list. But last few times merging AI drivers to drivers/misc
was really just a way to avoid the merge criteria for drivers/gpu
acceleration drivers. I'd love to land the first real open AI driver in
upstream, properly.

Cheers, Daniel



> 
> 
> Best Regards,
> 
> Wendy
> 
> 
> > 
> > > Signed-off-by: Wendy Liang 
> > > Signed-off-by: Hyun Kwon 
> > > ---
> > >   MAINTAINERS    |   8 +
> > >   drivers/misc/Kconfig   |  12 +
> > >   drivers/misc/Makefile  |   1 +
> > >   drivers/misc/xilinx-ai-engine/Makefile |  11 +
> > >   drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
> > >   drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 
> > > ++
> > >   drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
> > >   drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498
> > > +
> > >   drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
> > >   include/uapi/linux/xlnx-ai-engine.h    | 107 +
> > >   10 files changed, 1540 insertions(+)
> > >   create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
> > >   create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
> > >   create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
> > >   create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
> > >   create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
> > >   create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
> > >   create mode 100644 include/uapi/linux/xlnx-ai-engine.h
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 5cc595a..40e3351 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -19283,6 +19283,14 @@ T: git 
> > > https://github.com/Xilinx/linux-xlnx.git
> > >   F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
> > >   F: drivers/phy/xilinx/phy-zynqmp.c
> > > +XILINX AI ENGINE DRIVER
> > > +M: Wendy Liang 
> > > +S: Supported
> > > +F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
> > > +F: drivers/misc/xilinx-ai-engine/
> > > +F: include/linux/xlnx-ai-engine.h
> > > +F: include/uapi/linux/xlnx-ai-engine.h
> > > +
>

Re: [PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-12-08 Thread Jiaying Liang



On 12/8/20 9:12 AM, Nicolas Dufresne wrote:

Le mercredi 18 novembre 2020 à 00:06 -0800, Wendy Liang a écrit :

Create AI engine device/partition hierarchical structure.

Each AI engine device can have multiple logical partitions(groups of AI
engine tiles). Each partition is column based and has its own node ID
in the system. AI engine device driver manages its partitions.

Applications can access AI engine partition through the AI engine
partition driver instance. AI engine registers write is moved to kernel
as there are registers in the AI engine array needs privilege
permission.

Hi there, it's nice to see an effort to upstream an AI driver. I'm a little
worried this driver is not obvious to use from it's source code itself. So you
have reference to some Open Source code that demonstrate it's usage ?


We have AI engine library which provides a cross platforms APIs for other

libraries/application to use the hardware. Here is the source code:

https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/drivers/aienginev2/src

The cross platforms AI engine library runs in LInux userspace it defines 
how to


configure, and the kernel driver controls if what can be access and 
manage errors from device.



Best Regards,

Wendy





Signed-off-by: Wendy Liang 
Signed-off-by: Hyun Kwon 
---
  MAINTAINERS    |   8 +
  drivers/misc/Kconfig   |  12 +
  drivers/misc/Makefile  |   1 +
  drivers/misc/xilinx-ai-engine/Makefile |  11 +
  drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
  drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 ++
  drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
  drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498
+
  drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
  include/uapi/linux/xlnx-ai-engine.h    | 107 +
  10 files changed, 1540 insertions(+)
  create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
  create mode 100644 include/uapi/linux/xlnx-ai-engine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5cc595a..40e3351 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19283,6 +19283,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
  F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
  F: drivers/phy/xilinx/phy-zynqmp.c
  
+XILINX AI ENGINE DRIVER

+M: Wendy Liang 
+S: Supported
+F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
+F: drivers/misc/xilinx-ai-engine/
+F: include/linux/xlnx-ai-engine.h
+F: include/uapi/linux/xlnx-ai-engine.h
+
  XILLYBUS DRIVER
  M: Eli Billauer 
  L: linux-kernel@vger.kernel.org
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index fafa8b0..0b8ce4d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -444,6 +444,18 @@ config XILINX_SDFEC
  
   If unsure, say N.
  
+config XILINX_AIE

+   tristate "Xilinx AI engine"
+   depends on ARM64 || COMPILE_TEST
+   help
+ This option enables support for the Xilinx AI engine driver.
+ One Xilinx AI engine device can have multiple partitions (groups of
+ AI engine tiles). Xilinx AI engine device driver instance manages
+ AI engine partitions. User application access its partitions through
+ AI engine partition instance file operations.
+
+ If unsure, say N
+
  config MISC_RTSX
 tristate
 default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d23231e..2176b18 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
  obj-$(CONFIG_UACCE)+= uacce/
  obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
  obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
+obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
diff --git a/drivers/misc/xilinx-ai-engine/Makefile b/drivers/misc/xilinx-ai-
engine/Makefile
new file mode 100644
index 000..7827a0a
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Xilinx AI engine device driver
+#
+
+obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
+
+xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
+  ai-engine-dev.o \
+  ai-engine-part.o \
+  ai-engine-res.o
diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
b/drivers/m

Re: [PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-12-08 Thread Jiaying Liang



On 12/8/20 9:12 AM, Nicolas Dufresne wrote:

Le mercredi 18 novembre 2020 à 00:06 -0800, Wendy Liang a écrit :

Create AI engine device/partition hierarchical structure.

Each AI engine device can have multiple logical partitions(groups of AI
engine tiles). Each partition is column based and has its own node ID
in the system. AI engine device driver manages its partitions.

Applications can access AI engine partition through the AI engine
partition driver instance. AI engine registers write is moved to kernel
as there are registers in the AI engine array needs privilege
permission.

Hi there, it's nice to see an effort to upstream an AI driver. I'm a little
worried this driver is not obvious to use from it's source code itself. So you
have reference to some Open Source code that demonstrate it's usage ?

We have AI engine library which provides a cross platforms APIs for other

libraries/application to use the hardware. Here is the source code:

https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/drivers/aienginev2/src 



The cross platforms AI engine library runs in LInux userspace it defines 
how to


configure, and the kernel driver controls if what can be access and 
manage errors from device.



Best Regards,

Wendy



Signed-off-by: Wendy Liang 
Signed-off-by: Hyun Kwon 
---
  MAINTAINERS    |   8 +
  drivers/misc/Kconfig   |  12 +
  drivers/misc/Makefile  |   1 +
  drivers/misc/xilinx-ai-engine/Makefile |  11 +
  drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
  drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 ++
  drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
  drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498
+
  drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
  include/uapi/linux/xlnx-ai-engine.h    | 107 +
  10 files changed, 1540 insertions(+)
  create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
  create mode 100644 include/uapi/linux/xlnx-ai-engine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5cc595a..40e3351 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19283,6 +19283,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
  F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
  F: drivers/phy/xilinx/phy-zynqmp.c
  
+XILINX AI ENGINE DRIVER

+M: Wendy Liang 
+S: Supported
+F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
+F: drivers/misc/xilinx-ai-engine/
+F: include/linux/xlnx-ai-engine.h
+F: include/uapi/linux/xlnx-ai-engine.h
+
  XILLYBUS DRIVER
  M: Eli Billauer 
  L: linux-kernel@vger.kernel.org
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index fafa8b0..0b8ce4d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -444,6 +444,18 @@ config XILINX_SDFEC
  
   If unsure, say N.
  
+config XILINX_AIE

+   tristate "Xilinx AI engine"
+   depends on ARM64 || COMPILE_TEST
+   help
+ This option enables support for the Xilinx AI engine driver.
+ One Xilinx AI engine device can have multiple partitions (groups of
+ AI engine tiles). Xilinx AI engine device driver instance manages
+ AI engine partitions. User application access its partitions through
+ AI engine partition instance file operations.
+
+ If unsure, say N
+
  config MISC_RTSX
 tristate
 default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d23231e..2176b18 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
  obj-$(CONFIG_UACCE)+= uacce/
  obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
  obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
+obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
diff --git a/drivers/misc/xilinx-ai-engine/Makefile b/drivers/misc/xilinx-ai-
engine/Makefile
new file mode 100644
index 000..7827a0a
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Xilinx AI engine device driver
+#
+
+obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
+
+xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
+  ai-engine-dev.o \
+  ai-engine-part.o \
+  ai-engine-res.o
diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
b/drivers/m

Re: [PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-12-08 Thread Nicolas Dufresne
Le mercredi 18 novembre 2020 à 00:06 -0800, Wendy Liang a écrit :
> Create AI engine device/partition hierarchical structure.
> 
> Each AI engine device can have multiple logical partitions(groups of AI
> engine tiles). Each partition is column based and has its own node ID
> in the system. AI engine device driver manages its partitions.
> 
> Applications can access AI engine partition through the AI engine
> partition driver instance. AI engine registers write is moved to kernel
> as there are registers in the AI engine array needs privilege
> permission.

Hi there, it's nice to see an effort to upstream an AI driver. I'm a little
worried this driver is not obvious to use from it's source code itself. So you
have reference to some Open Source code that demonstrate it's usage ?

> 
> Signed-off-by: Wendy Liang 
> Signed-off-by: Hyun Kwon 
> ---
>  MAINTAINERS    |   8 +
>  drivers/misc/Kconfig   |  12 +
>  drivers/misc/Makefile  |   1 +
>  drivers/misc/xilinx-ai-engine/Makefile |  11 +
>  drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
>  drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 ++
>  drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
>  drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498
> +
>  drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
>  include/uapi/linux/xlnx-ai-engine.h    | 107 +
>  10 files changed, 1540 insertions(+)
>  create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
>  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
>  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
>  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
>  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
>  create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
>  create mode 100644 include/uapi/linux/xlnx-ai-engine.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5cc595a..40e3351 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19283,6 +19283,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
>  F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
>  F: drivers/phy/xilinx/phy-zynqmp.c
>  
> +XILINX AI ENGINE DRIVER
> +M: Wendy Liang 
> +S: Supported
> +F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
> +F: drivers/misc/xilinx-ai-engine/
> +F: include/linux/xlnx-ai-engine.h
> +F: include/uapi/linux/xlnx-ai-engine.h
> +
>  XILLYBUS DRIVER
>  M: Eli Billauer 
>  L: linux-kernel@vger.kernel.org
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index fafa8b0..0b8ce4d 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -444,6 +444,18 @@ config XILINX_SDFEC
>  
>   If unsure, say N.
>  
> +config XILINX_AIE
> +   tristate "Xilinx AI engine"
> +   depends on ARM64 || COMPILE_TEST
> +   help
> +     This option enables support for the Xilinx AI engine driver.
> + One Xilinx AI engine device can have multiple partitions (groups of
> + AI engine tiles). Xilinx AI engine device driver instance manages
> + AI engine partitions. User application access its partitions through
> + AI engine partition instance file operations.
> +
> + If unsure, say N
> +
>  config MISC_RTSX
> tristate
> default MISC_RTSX_PCI || MISC_RTSX_USB
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index d23231e..2176b18 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
>  obj-$(CONFIG_UACCE)+= uacce/
>  obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
>  obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
> +obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
> diff --git a/drivers/misc/xilinx-ai-engine/Makefile b/drivers/misc/xilinx-ai-
> engine/Makefile
> new file mode 100644
> index 000..7827a0a
> --- /dev/null
> +++ b/drivers/misc/xilinx-ai-engine/Makefile
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Makefile for Xilinx AI engine device driver
> +#
> +
> +obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
> +
> +xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
> +  ai-engine-dev.o \
> +  ai-engine-part.o \
> +  ai-engine-res.o
> diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
> b/drivers/mis

Re: [PATCH v1] phy: tegra: xusb: Fix usb_phy device driver field

2020-11-30 Thread Vinod Koul
On 17-11-20, 16:38, JC Kuo wrote:
> In commit "phy: tegra: xusb: Add usb-phy support", an OTG capable PHY
> device, such as phy-usb2.0 device of Jetson-TX1 platform, will be
> bound to the tegra-xusb-padctl driver by the following line in
> tegra_xusb_setup_usb_role_switch().
> 
>   port->usb_phy.dev->driver = port->padctl->dev->driver;
> 
> With this, dev_pm_ops set of tegra-xusb-padctl driver will be invoked
> for the OTG capable PHY incorrectly as below logs show.
> 
> This commit fixes the issue by assigning an empty driver to it.

Applied, thanks

-- 
~Vinod


[PATCH v3 2/9] misc: Add Xilinx AI engine device driver

2020-11-29 Thread Wendy Liang
Create AI engine device/partition hierarchical structure.

Each AI engine device can have multiple logical partitions(groups of AI
engine tiles). Each partition is column based and has its own node ID
in the system. AI engine device driver manages its partitions.

Applications can access AI engine partition through the AI engine
partition driver instance. AI engine registers write is moved to kernel
as there are registers in the AI engine array needs privilege
permission.

Signed-off-by: Wendy Liang 
Signed-off-by: Hyun Kwon 
---
 MAINTAINERS|   8 +
 drivers/misc/Kconfig   |  12 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/xilinx-ai-engine/Makefile |  11 +
 drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
 drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 452 +++
 drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
 drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498 +
 drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
 include/uapi/linux/xlnx-ai-engine.h| 107 +
 10 files changed, 1544 insertions(+)
 create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
 create mode 100644 include/uapi/linux/xlnx-ai-engine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2daa6ee..1e36294 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19287,6 +19287,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
 F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
 F: drivers/phy/xilinx/phy-zynqmp.c
 
+XILINX AI ENGINE DRIVER
+M: Wendy Liang 
+S: Supported
+F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
+F: drivers/misc/xilinx-ai-engine/
+F: include/linux/xlnx-ai-engine.h
+F: include/uapi/linux/xlnx-ai-engine.h
+
 XILLYBUS DRIVER
 M: Eli Billauer 
 L: linux-kernel@vger.kernel.org
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index fafa8b0..0b8ce4d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -444,6 +444,18 @@ config XILINX_SDFEC
 
  If unsure, say N.
 
+config XILINX_AIE
+   tristate "Xilinx AI engine"
+   depends on ARM64 || COMPILE_TEST
+   help
+ This option enables support for the Xilinx AI engine driver.
+ One Xilinx AI engine device can have multiple partitions (groups of
+ AI engine tiles). Xilinx AI engine device driver instance manages
+ AI engine partitions. User application access its partitions through
+ AI engine partition instance file operations.
+
+ If unsure, say N
+
 config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d23231e..2176b18 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
 obj-$(CONFIG_UACCE)+= uacce/
 obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
+obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
diff --git a/drivers/misc/xilinx-ai-engine/Makefile 
b/drivers/misc/xilinx-ai-engine/Makefile
new file mode 100644
index 000..7827a0a
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Xilinx AI engine device driver
+#
+
+obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
+
+xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
+  ai-engine-dev.o \
+  ai-engine-part.o \
+  ai-engine-res.o
diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c 
b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
new file mode 100644
index 000..319260f
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx AI Engine driver AIE device specific implementation
+ *
+ * Copyright (C) 2020 Xilinx, Inc.
+ */
+
+#include 
+
+#include "ai-engine-internal.h"
+
+#define AIE_ARRAY_SHIFT30U
+#define AIE_COL_SHIFT  23U
+#define AIE_ROW_SHIFT  18U
+
+/*
+ * Registers offsets
+ */
+#define AIE_SHIMNOC_L2INTR_MASK_REGOFF 0x00015000U
+#define AIE_SHIMNOC_L2INTR_INTR_REGOFF 0x00015010U
+#define AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF 0x0001d000U
+#define AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF 0x0001d13cU
+#define AIE_SHIMNOC_AXIMM_REGOFF   

Re: [PATCH v1] phy: tegra: xusb: Fix usb_phy device driver field

2020-11-26 Thread Thierry Reding
On Tue, Nov 17, 2020 at 04:38:03PM +0800, JC Kuo wrote:
> In commit "phy: tegra: xusb: Add usb-phy support", an OTG capable PHY
> device, such as phy-usb2.0 device of Jetson-TX1 platform, will be
> bound to the tegra-xusb-padctl driver by the following line in
> tegra_xusb_setup_usb_role_switch().
> 
>   port->usb_phy.dev->driver = port->padctl->dev->driver;
> 
> With this, dev_pm_ops set of tegra-xusb-padctl driver will be invoked
> for the OTG capable PHY incorrectly as below logs show.
> 
> This commit fixes the issue by assigning an empty driver to it.
> 
> [  153.451108] tegra-xusb-padctl phy-usb2.0: > 
> tegra_xusb_padctl_suspend_noirq(dev=80917000)
> [  153.460353] tegra-xusb-padctl phy-usb2.0:   driver: 8000114453e0 
> (tegra_xusb_padctl_driver)
> [  153.469245] tegra-xusb-padctl phy-usb2.0:   padctl: 829f6480
> [  153.475772] tegra-xusb-padctl phy-usb2.0: soc: ef7bdd7f 
> (0xef7bdd7f)
> [  153.484061] Unable to handle kernel paging request at virtual address 
> 007bdd80004f
> [  153.492132] Mem abort info:
> [  153.495083]   ESR = 0x9604
> [  153.498308]   EC = 0x25: DABT (current EL), IL = 32 bits
> [  153.503771]   SET = 0, FnV = 0
> [  153.506979]   EA = 0, S1PTW = 0
> [  153.510260] Data abort info:
> [  153.513200]   ISV = 0, ISS = 0x0004
> [  153.517181]   CM = 0, WnR = 0
> [  153.520302] [007bdd80004f] address between user and kernel address 
> ranges
> [  153.527600] Internal error: Oops: 9604 [#1] PREEMPT SMP
> [  153.533231] Modules linked in: nouveau panel_simple tegra_video(C) 
> tegra_drm drm_ttm_helper videobuf2_dma_contig ttm videobuf2_memops cec 
> videobuf2_v4l2 videobuf2_common drm_kms_helper v4l2_fwnode videodev drm mc 
> snd_hda_codec_hdmi cdc_ether usbnet snd_hda_tegra r8152 crct10dif_ce 
> snd_hda_codec snd_hda_core tegra_xudc host1x lp855x_bl at24 ip_tables 
> x_tables ipv6
> [  153.566417] CPU: 0 PID: 300 Comm: systemd-sleep Tainted: G C   
>  5.10.0-rc3-next-20201113-00019-g5c064d5372b0-dirty #624
> [  153.578283] Hardware name: NVIDIA Jetson TX1 Developer Kit (DT)
> [  153.584281] pstate: 4005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
> [  153.590381] pc : tegra_xusb_padctl_suspend_noirq+0x88/0x100
> [  153.596016] lr : tegra_xusb_padctl_suspend_noirq+0x80/0x100
> [  153.601632] sp : 8000120dbb60
> [  153.604999] x29: 8000120dbb60 x28: 80a1df00
> [  153.610430] x27: 0002 x26: 8000106f8540
> [  153.615858] x25: 8000113ac4a4 x24: 80001148c198
> [  153.621277] x23: 800010c4538c x22: 0002
> [  153.626692] x21: 800010ccde80 x20: 829f6480
> [  153.632107] x19: 80917000 x18: 0030
> [  153.637521] x17:  x16: 
> [  153.642933] x15: 80a1e380 x14: 74636461702d6273
> [  153.648346] x13: 8000113ad058 x12: 0f39
> [  153.653759] x11: 0513 x10: 800011405058
> [  153.659176] x9 : f000 x8 : 8000113ad058
> [  153.664590] x7 : 800011405058 x6 : 
> [  153.670002] x5 :  x4 : fe908bc0
> [  153.675414] x3 : fe910228 x2 : 162ef67e0581e700
> [  153.680826] x1 : 162ef67e0581e700 x0 : ef7bdd7f
> [  153.686241] Call trace:
> [  153.688769]  tegra_xusb_padctl_suspend_noirq+0x88/0x100
> [  153.694077]  __device_suspend_noirq+0x68/0x1cc
> [  153.698594]  dpm_noirq_suspend_devices+0x10c/0x1d0
> [  153.703456]  dpm_suspend_noirq+0x28/0xa0
> [  153.707461]  suspend_devices_and_enter+0x234/0x4bc
> [  153.712314]  pm_suspend+0x1e4/0x270
> [  153.715868]  state_store+0x8c/0x110
> [  153.719440]  kobj_attr_store+0x1c/0x30
> [  153.723259]  sysfs_kf_write+0x4c/0x7c
> [  153.726981]  kernfs_fop_write+0x124/0x240
> [  153.731065]  vfs_write+0xe4/0x204
> [  153.734449]  ksys_write+0x6c/0x100
> [  153.737925]  __arm64_sys_write+0x20/0x30
> [  153.741931]  el0_svc_common.constprop.0+0x78/0x1a0
> [  153.746789]  do_el0_svc+0x24/0x90
> [  153.750181]  el0_sync_handler+0x254/0x260
> [  153.754251]  el0_sync+0x174/0x180
> [  153.757663] Code: aa0303e2 94000f64 f9405680 b4e0 (f9402803)
> [  153.763826] ---[ end trace 81543a3394cb409d ]---
> 
> Fixes: e8f7d2f409a1 ("phy: tegra: xusb: Add usb-phy support")
> 
> Signed-off-by: JC Kuo 
> ---
>  drivers/phy/tegra/xusb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Thierry Reding 


signature.asc
Description: PGP signature


Re: [PATCH v2 2/9] misc: Add Xilinx AI engine device driver

2020-11-19 Thread Dave Airlie
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5cc595a..40e3351 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19283,6 +19283,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
>  F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
>  F: drivers/phy/xilinx/phy-zynqmp.c
>
> +XILINX AI ENGINE DRIVER
> +M: Wendy Liang 
> +S: Supported
> +F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
> +F: drivers/misc/xilinx-ai-engine/
> +F: include/linux/xlnx-ai-engine.h
> +F: include/uapi/linux/xlnx-ai-engine.h
> +
>  XILLYBUS DRIVER
>  M: Eli Billauer 
>  L: linux-kernel@vger.kernel.org
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index fafa8b0..0b8ce4d 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -444,6 +444,18 @@ config XILINX_SDFEC
>
>   If unsure, say N.
>
> +config XILINX_AIE
> +   tristate "Xilinx AI engine"
> +   depends on ARM64 || COMPILE_TEST
> +   help
> + This option enables support for the Xilinx AI engine driver.
> + One Xilinx AI engine device can have multiple partitions (groups of
> + AI engine tiles). Xilinx AI engine device driver instance manages
> + AI engine partitions. User application access its partitions through
> + AI engine partition instance file operations.
> +
> + If unsure, say N
> +
>  config MISC_RTSX
> tristate
> default MISC_RTSX_PCI || MISC_RTSX_USB
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index d23231e..2176b18 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
>  obj-$(CONFIG_UACCE)+= uacce/
>  obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
>  obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
> +obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
> diff --git a/drivers/misc/xilinx-ai-engine/Makefile 
> b/drivers/misc/xilinx-ai-engine/Makefile
> new file mode 100644
> index 000..7827a0a
> --- /dev/null
> +++ b/drivers/misc/xilinx-ai-engine/Makefile
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Makefile for Xilinx AI engine device driver
> +#
> +
> +obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
> +
> +xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
> +  ai-engine-dev.o \
> +  ai-engine-part.o \
> +  ai-engine-res.o
> diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c 
> b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
> new file mode 100644
> index 000..319260f
> --- /dev/null
> +++ b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Xilinx AI Engine driver AIE device specific implementation
> + *
> + * Copyright (C) 2020 Xilinx, Inc.
> + */
> +
> +#include 
> +
> +#include "ai-engine-internal.h"
> +
> +#define AIE_ARRAY_SHIFT30U
> +#define AIE_COL_SHIFT  23U
> +#define AIE_ROW_SHIFT  18U
> +
> +/*
> + * Registers offsets
> + */
> +#define AIE_SHIMNOC_L2INTR_MASK_REGOFF 0x00015000U
> +#define AIE_SHIMNOC_L2INTR_INTR_REGOFF 0x00015010U
> +#define AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF 0x0001d000U
> +#define AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF 0x0001d13cU
> +#define AIE_SHIMNOC_AXIMM_REGOFF   0x0001e020U
> +#define AIE_SHIMPL_L1INTR_MASK_A_REGOFF0x00035000U
> +#define AIE_SHIMPL_L1INTR_BLOCK_NORTH_B_REGOFF 0x00035050U
> +#define AIE_SHIMPL_CLKCNTR_REGOFF  0x00036040U
> +#define AIE_SHIMPL_RESET_REGOFF0x0003604cU
> +#define AIE_TILE_CORE_CLKCNTR_REGOFF   0x00036040U
> +
> +static const struct aie_tile_regs aie_kernel_regs[] = {
> +   /* SHIM AXI MM Config */
> +   {.attribute = AIE_TILE_TYPE_SHIMNOC << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
> +.soff = AIE_SHIMNOC_AXIMM_REGOFF,
> +.eoff = AIE_SHIMNOC_AXIMM_REGOFF,
> +   },
> +   /* SHIM DMA ADDRESS range */
> +   {.attribute = AIE_TILE_TYPE_SHIMNOC << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
> +.soff = AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF,
> +.eoff = AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF,
> +   },
> +   /* SHIM 2nd level interrupt controller */
> +   {.attribute = AIE_TILE_TYPE_SHIMNOC << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
> +.soff = AIE_SHIMNOC_L2INTR_MASK_REGOFF,
> +.eoff = AIE_SHIMNOC_L2INTR_INTR_REGOFF,
> +   },
> + 

[PATCH v5 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-19 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1441 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1592 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..23814f3f2305
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v4 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-19 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1441 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1592 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..23814f3f2305
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v2 2/9] misc: Add Xilinx AI engine device driver

2020-11-18 Thread Wendy Liang
Create AI engine device/partition hierarchical structure.

Each AI engine device can have multiple logical partitions(groups of AI
engine tiles). Each partition is column based and has its own node ID
in the system. AI engine device driver manages its partitions.

Applications can access AI engine partition through the AI engine
partition driver instance. AI engine registers write is moved to kernel
as there are registers in the AI engine array needs privilege
permission.

Signed-off-by: Wendy Liang 
Signed-off-by: Hyun Kwon 
---
 MAINTAINERS|   8 +
 drivers/misc/Kconfig   |  12 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/xilinx-ai-engine/Makefile |  11 +
 drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
 drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 ++
 drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
 drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498 +
 drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
 include/uapi/linux/xlnx-ai-engine.h| 107 +
 10 files changed, 1540 insertions(+)
 create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
 create mode 100644 include/uapi/linux/xlnx-ai-engine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5cc595a..40e3351 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19283,6 +19283,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
 F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
 F: drivers/phy/xilinx/phy-zynqmp.c
 
+XILINX AI ENGINE DRIVER
+M: Wendy Liang 
+S: Supported
+F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
+F: drivers/misc/xilinx-ai-engine/
+F: include/linux/xlnx-ai-engine.h
+F: include/uapi/linux/xlnx-ai-engine.h
+
 XILLYBUS DRIVER
 M: Eli Billauer 
 L: linux-kernel@vger.kernel.org
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index fafa8b0..0b8ce4d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -444,6 +444,18 @@ config XILINX_SDFEC
 
  If unsure, say N.
 
+config XILINX_AIE
+   tristate "Xilinx AI engine"
+   depends on ARM64 || COMPILE_TEST
+   help
+ This option enables support for the Xilinx AI engine driver.
+ One Xilinx AI engine device can have multiple partitions (groups of
+ AI engine tiles). Xilinx AI engine device driver instance manages
+ AI engine partitions. User application access its partitions through
+ AI engine partition instance file operations.
+
+ If unsure, say N
+
 config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d23231e..2176b18 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
 obj-$(CONFIG_UACCE)+= uacce/
 obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
+obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
diff --git a/drivers/misc/xilinx-ai-engine/Makefile 
b/drivers/misc/xilinx-ai-engine/Makefile
new file mode 100644
index 000..7827a0a
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Xilinx AI engine device driver
+#
+
+obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
+
+xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
+  ai-engine-dev.o \
+  ai-engine-part.o \
+  ai-engine-res.o
diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c 
b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
new file mode 100644
index 000..319260f
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx AI Engine driver AIE device specific implementation
+ *
+ * Copyright (C) 2020 Xilinx, Inc.
+ */
+
+#include 
+
+#include "ai-engine-internal.h"
+
+#define AIE_ARRAY_SHIFT30U
+#define AIE_COL_SHIFT  23U
+#define AIE_ROW_SHIFT  18U
+
+/*
+ * Registers offsets
+ */
+#define AIE_SHIMNOC_L2INTR_MASK_REGOFF 0x00015000U
+#define AIE_SHIMNOC_L2INTR_INTR_REGOFF 0x00015010U
+#define AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF 0x0001d000U
+#define AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF 0x0001d13cU
+#define AIE_SHIMNOC_AXIMM_REGOFF   

[PATCH 2/9] misc: Add Xilinx AI engine device driver

2020-11-18 Thread Wendy Liang
Create AI engine device/partition hierarchical structure.

Each AI engine device can have multiple logical partitions(groups of AI
engine tiles). Each partition is column based and has its own node ID
in the system. AI engine device driver manages its partitions.

Applications can access AI engine partition through the AI engine
partition driver instance. AI engine registers write is moved to kernel
as there are registers in the AI engine array needs privilege
permission.

Signed-off-by: Wendy Liang 
Signed-off-by: Hyun Kwon 
---
 MAINTAINERS|   8 +
 drivers/misc/Kconfig   |  12 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/xilinx-ai-engine/Makefile |  11 +
 drivers/misc/xilinx-ai-engine/ai-engine-aie.c  | 115 +
 drivers/misc/xilinx-ai-engine/ai-engine-dev.c  | 448 ++
 drivers/misc/xilinx-ai-engine/ai-engine-internal.h | 226 ++
 drivers/misc/xilinx-ai-engine/ai-engine-part.c | 498 +
 drivers/misc/xilinx-ai-engine/ai-engine-res.c  | 114 +
 include/uapi/linux/xlnx-ai-engine.h| 107 +
 10 files changed, 1540 insertions(+)
 create mode 100644 drivers/misc/xilinx-ai-engine/Makefile
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-aie.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-dev.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-internal.h
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-part.c
 create mode 100644 drivers/misc/xilinx-ai-engine/ai-engine-res.c
 create mode 100644 include/uapi/linux/xlnx-ai-engine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5cc595a..40e3351 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19283,6 +19283,14 @@ T: git https://github.com/Xilinx/linux-xlnx.git
 F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
 F: drivers/phy/xilinx/phy-zynqmp.c
 
+XILINX AI ENGINE DRIVER
+M: Wendy Liang 
+S: Supported
+F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml
+F: drivers/misc/xilinx-ai-engine/
+F: include/linux/xlnx-ai-engine.h
+F: include/uapi/linux/xlnx-ai-engine.h
+
 XILLYBUS DRIVER
 M: Eli Billauer 
 L: linux-kernel@vger.kernel.org
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index fafa8b0..0b8ce4d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -444,6 +444,18 @@ config XILINX_SDFEC
 
  If unsure, say N.
 
+config XILINX_AIE
+   tristate "Xilinx AI engine"
+   depends on ARM64 || COMPILE_TEST
+   help
+ This option enables support for the Xilinx AI engine driver.
+ One Xilinx AI engine device can have multiple partitions (groups of
+ AI engine tiles). Xilinx AI engine device driver instance manages
+ AI engine partitions. User application access its partitions through
+ AI engine partition instance file operations.
+
+ If unsure, say N
+
 config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d23231e..2176b18 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_HABANA_AI)   += habanalabs/
 obj-$(CONFIG_UACCE)+= uacce/
 obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
 obj-$(CONFIG_HISI_HIKEY_USB)   += hisi_hikey_usb.o
+obj-$(CONFIG_XILINX_AIE)   += xilinx-ai-engine/
diff --git a/drivers/misc/xilinx-ai-engine/Makefile 
b/drivers/misc/xilinx-ai-engine/Makefile
new file mode 100644
index 000..7827a0a
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Xilinx AI engine device driver
+#
+
+obj-$(CONFIG_XILINX_AIE)   += xilinx-aie.o
+
+xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
+  ai-engine-dev.o \
+  ai-engine-part.o \
+  ai-engine-res.o
diff --git a/drivers/misc/xilinx-ai-engine/ai-engine-aie.c 
b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
new file mode 100644
index 000..319260f
--- /dev/null
+++ b/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx AI Engine driver AIE device specific implementation
+ *
+ * Copyright (C) 2020 Xilinx, Inc.
+ */
+
+#include 
+
+#include "ai-engine-internal.h"
+
+#define AIE_ARRAY_SHIFT30U
+#define AIE_COL_SHIFT  23U
+#define AIE_ROW_SHIFT  18U
+
+/*
+ * Registers offsets
+ */
+#define AIE_SHIMNOC_L2INTR_MASK_REGOFF 0x00015000U
+#define AIE_SHIMNOC_L2INTR_INTR_REGOFF 0x00015010U
+#define AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF 0x0001d000U
+#define AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF 0x0001d13cU
+#define AIE_SHIMNOC_AXIMM_REGOFF   

Re: [PATCH v2 1/2] watchdog: f71808e_wdt: refactor to platform device/driver pair

2020-11-17 Thread Ahmad Fatoum
Hello Guenter,

Thanks for the review. Comments inline.

On 11/8/20 6:26 PM, Guenter Roeck wrote:
> On Tue, Oct 20, 2020 at 08:21:11AM +0200, Ahmad Fatoum wrote:
>> Driver so far wasn't ported to the driver model and set up its
>> miscdevice out of the init after probing the I/O ports for a watchdog
>> with correct vendor and device revision.
>>
>> Keep the device detection part at init time, but move watchdog setup
>> to a platform driver probe function.
>>
>> While at it, refactor some of the driver code we have to now touch
>> anyway:
>>
>>  - platform_device_id is used instead of the two big switches mapping
>>hardware ID to an enum and then mapping it to a pinconf function
>>  - we rename f71808e_ and watchdog_data to fintek_wdt, to avoid mix up
>>of the generic parts up with the device specific parts
>>
>> Suggested-by: Guenter Roeck 
>> Signed-off-by: Ahmad Fatoum 
> 
> Sorry, I just found this. Sorry, it got lost.
> The changes you are making here go way beyond a conversion to a platform
> driver. I am not necessarily opposed to the changes, but they should be
> split into multiple patches to simlify (and to a large degree enable)
> a meaningful review. More comments inline.

Most code shuffling around was due to the use of platform_device_id.
I can look into splitting this up though.

> 
>> ---
>>  drivers/watchdog/f71808e_wdt.c | 377 +++--
>>  1 file changed, 215 insertions(+), 162 deletions(-)
>>
>> diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
>> index f60beec1bbae..4ff7a2509125 100644
>> --- a/drivers/watchdog/f71808e_wdt.c
>> +++ b/drivers/watchdog/f71808e_wdt.c
>> @@ -9,12 +9,15 @@
>>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>>  
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -110,22 +113,6 @@ module_param(start_withtimeout, uint, 0);
>>  MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load 
>> with"
>>  " given initial timeout. Zero (default) disables this feature.");
>>  
>> -enum chips { f71808fg, f71858fg, f71862fg, f71868, f71869, f71882fg, 
>> f71889fg,
>> - f81803, f81865, f81866};
>> -
>> -static const char *f71808e_names[] = {
>> -"f71808fg",
>> -"f71858fg",
>> -"f71862fg",
>> -"f71868",
>> -"f71869",
>> -"f71882fg",
>> -"f71889fg",
>> -"f81803",
>> -"f81865",
>> -"f81866",
>> -};
>> -
>>  /* Super-I/O Function prototypes */
>>  static inline int superio_inb(int base, int reg);
>>  static inline int superio_inw(int base, int reg);
>> @@ -136,9 +123,17 @@ static inline int superio_enter(int base);
>>  static inline void superio_select(int base, int ld);
>>  static inline void superio_exit(int base);
>>  
>> -struct watchdog_data {
>> +struct fintek_wdt;
>> +
>> +struct fintek_wdt_variant {
>> +u16 id;
>> +void (*pinconf)(struct fintek_wdt *wd);
>> +const char *identity_override;
>> +};
>> +
>> +struct fintek_wdt {
>>  unsigned short  sioaddr;
>> -enum chips  type;
>> +const struct fintek_wdt_variant *variant;
> 
> I'd rather have this all in here. Just add 
>   void (*pinconf)(struct fintek_wdt *wd);
> and assign it in the probe function, or call it
> from an array indexed with type.
> 
> This change is also independent of the conversion to a platform
> driver and should be done in a separate patch.

Ok.

>>  unsigned long   opened;
>>  struct mutexlock;
>>  charexpect_close;
>> @@ -152,10 +147,15 @@ struct watchdog_data {
>>  charcaused_reboot;  /* last reboot was by the watchdog */
>>  };
>>  
>> -static struct watchdog_data watchdog = {
>> +static struct fintek_wdt watchdog = {
>>  .lock = __MUTEX_INITIALIZER(watchdog.lock),
>>  };
>>  
>> +static inline bool has_f81865_wdo_conf(struct fintek_wdt *wd)
>> +{
>> +return wd->variant->id == SIO_F81865_ID || wd->variant->id == 
>> SIO_F81866_ID;
>> +}
>> +
> This change is independent of the conversion to a platform driver
> and should be a separate patch.

Ok.

>>  /* Super I/O functions */
>>  static inline int superio_inb(int base, int reg)
>>  {
>> @@ -247,7 +247,7 @@ static int watchdog_set_pulse_width(unsigned int pw)
>>  int err = 0;
>>  unsigned int t1 = 25, t2 = 125, t3 = 5000;
>>  
>> -if (watchdog.type == f71868) {
>> +if (watchdog.variant->id == SIO_F71868_ID) {
> 
> I am not sure if dropping watchdog.type and replacing it with SIO_F71868_ID
> is a good idea. In the current code, there is no 1:1 match of those,
> specifically for SIO_F71869_ID/SIO_F71869A_ID. Deviating from that only
> complicates the code.

We can have a 1:1 match if we drop some quirks. See below.

> 
>>  t1 = 30;
>>  t2 = 150;
>>  t3 = 6000;
>> @@ -309,7 +309,6 @@ static int watchdog_keepalive(void)
>>  static int watchdog_start(void)
>>  {

[PATCH v1] phy: tegra: xusb: Fix usb_phy device driver field

2020-11-17 Thread JC Kuo
In commit "phy: tegra: xusb: Add usb-phy support", an OTG capable PHY
device, such as phy-usb2.0 device of Jetson-TX1 platform, will be
bound to the tegra-xusb-padctl driver by the following line in
tegra_xusb_setup_usb_role_switch().

port->usb_phy.dev->driver = port->padctl->dev->driver;

With this, dev_pm_ops set of tegra-xusb-padctl driver will be invoked
for the OTG capable PHY incorrectly as below logs show.

This commit fixes the issue by assigning an empty driver to it.

[  153.451108] tegra-xusb-padctl phy-usb2.0: > 
tegra_xusb_padctl_suspend_noirq(dev=80917000)
[  153.460353] tegra-xusb-padctl phy-usb2.0:   driver: 8000114453e0 
(tegra_xusb_padctl_driver)
[  153.469245] tegra-xusb-padctl phy-usb2.0:   padctl: 829f6480
[  153.475772] tegra-xusb-padctl phy-usb2.0: soc: ef7bdd7f 
(0xef7bdd7f)
[  153.484061] Unable to handle kernel paging request at virtual address 
007bdd80004f
[  153.492132] Mem abort info:
[  153.495083]   ESR = 0x9604
[  153.498308]   EC = 0x25: DABT (current EL), IL = 32 bits
[  153.503771]   SET = 0, FnV = 0
[  153.506979]   EA = 0, S1PTW = 0
[  153.510260] Data abort info:
[  153.513200]   ISV = 0, ISS = 0x0004
[  153.517181]   CM = 0, WnR = 0
[  153.520302] [007bdd80004f] address between user and kernel address ranges
[  153.527600] Internal error: Oops: 9604 [#1] PREEMPT SMP
[  153.533231] Modules linked in: nouveau panel_simple tegra_video(C) tegra_drm 
drm_ttm_helper videobuf2_dma_contig ttm videobuf2_memops cec videobuf2_v4l2 
videobuf2_common drm_kms_helper v4l2_fwnode videodev drm mc snd_hda_codec_hdmi 
cdc_ether usbnet snd_hda_tegra r8152 crct10dif_ce snd_hda_codec snd_hda_core 
tegra_xudc host1x lp855x_bl at24 ip_tables x_tables ipv6
[  153.566417] CPU: 0 PID: 300 Comm: systemd-sleep Tainted: G C
5.10.0-rc3-next-20201113-00019-g5c064d5372b0-dirty #624
[  153.578283] Hardware name: NVIDIA Jetson TX1 Developer Kit (DT)
[  153.584281] pstate: 4005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
[  153.590381] pc : tegra_xusb_padctl_suspend_noirq+0x88/0x100
[  153.596016] lr : tegra_xusb_padctl_suspend_noirq+0x80/0x100
[  153.601632] sp : 8000120dbb60
[  153.604999] x29: 8000120dbb60 x28: 80a1df00
[  153.610430] x27: 0002 x26: 8000106f8540
[  153.615858] x25: 8000113ac4a4 x24: 80001148c198
[  153.621277] x23: 800010c4538c x22: 0002
[  153.626692] x21: 800010ccde80 x20: 829f6480
[  153.632107] x19: 80917000 x18: 0030
[  153.637521] x17:  x16: 
[  153.642933] x15: 80a1e380 x14: 74636461702d6273
[  153.648346] x13: 8000113ad058 x12: 0f39
[  153.653759] x11: 0513 x10: 800011405058
[  153.659176] x9 : f000 x8 : 8000113ad058
[  153.664590] x7 : 800011405058 x6 : 
[  153.670002] x5 :  x4 : fe908bc0
[  153.675414] x3 : fe910228 x2 : 162ef67e0581e700
[  153.680826] x1 : 162ef67e0581e700 x0 : ef7bdd7f
[  153.686241] Call trace:
[  153.688769]  tegra_xusb_padctl_suspend_noirq+0x88/0x100
[  153.694077]  __device_suspend_noirq+0x68/0x1cc
[  153.698594]  dpm_noirq_suspend_devices+0x10c/0x1d0
[  153.703456]  dpm_suspend_noirq+0x28/0xa0
[  153.707461]  suspend_devices_and_enter+0x234/0x4bc
[  153.712314]  pm_suspend+0x1e4/0x270
[  153.715868]  state_store+0x8c/0x110
[  153.719440]  kobj_attr_store+0x1c/0x30
[  153.723259]  sysfs_kf_write+0x4c/0x7c
[  153.726981]  kernfs_fop_write+0x124/0x240
[  153.731065]  vfs_write+0xe4/0x204
[  153.734449]  ksys_write+0x6c/0x100
[  153.737925]  __arm64_sys_write+0x20/0x30
[  153.741931]  el0_svc_common.constprop.0+0x78/0x1a0
[  153.746789]  do_el0_svc+0x24/0x90
[  153.750181]  el0_sync_handler+0x254/0x260
[  153.754251]  el0_sync+0x174/0x180
[  153.757663] Code: aa0303e2 94000f64 f9405680 b4e0 (f9402803)
[  153.763826] ---[ end trace 81543a3394cb409d ]---

Fixes: e8f7d2f409a1 ("phy: tegra: xusb: Add usb-phy support")

Signed-off-by: JC Kuo 
---
 drivers/phy/tegra/xusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index ad88d74c1884..181a1be5f491 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -688,7 +688,7 @@ static int tegra_xusb_setup_usb_role_switch(struct 
tegra_xusb_port *port)
 * reference to retrieve usb-phy details.
 */
port->usb_phy.dev = >pad->lanes[port->index]->dev;
-   port->usb_phy.dev->driver = port->padctl->dev->driver;
+   port->usb_phy.dev->driver = port->dev.driver;
port->usb_phy.otg->usb_phy = >usb_phy;
port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral;
port->usb_phy.otg->set_host = tegra_xusb_set_host;
-- 
2.25.1



Re: [PATCH 2/2] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-15 Thread kernel test robot
Hi Dongjiu,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on vkoul-dmaengine/next]
[also build test WARNING on robh/for-next pza/reset/next v5.10-rc3 
next-20201113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Dongjiu-Geng/dt-bindings-dma-Add-DT-bindings-for-HiSilicon-Hiedma-Controller/20201114-001353
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/bafd07a67a5daf6eefedcd050312e9ee307c255a
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Dongjiu-Geng/dt-bindings-dma-Add-DT-bindings-for-HiSilicon-Hiedma-Controller/20201114-001353
git checkout bafd07a67a5daf6eefedcd050312e9ee307c255a
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/dma/hiedmacv310.c:144:6: warning: no previous prototype for 
>> 'dump_lli' [-Wmissing-prototypes]
 144 | void dump_lli(u64 *llis_vaddr, unsigned int num)
 |  ^~~~
   drivers/dma/hiedmacv310.c: In function 'hiedmac_pause_phy_chan':
>> drivers/dma/hiedmacv310.c:527:28: warning: suggest braces around empty body 
>> in an 'if' statement [-Wempty-body]
 527 |   phychan->id, timeout);
 |^
   drivers/dma/hiedmacv310.c: At top level:
>> drivers/dma/hiedmacv310.c:650:23: warning: no previous prototype for 
>> 'hiedmac_init_tsf_desc' [-Wmissing-prototypes]
 650 | struct transfer_desc *hiedmac_init_tsf_desc(struct dma_chan *chan,
 |   ^
>> drivers/dma/hiedmacv310.c:1088:6: warning: no previous prototype for 
>> 'handle_irq' [-Wmissing-prototypes]
1088 | bool handle_irq(struct hiedmacv310_driver_data *hiedmac, int chan_id)
 |  ^~
>> drivers/dma/hiedmacv310.c:1210:6: warning: no previous prototype for 
>> 'hiedmac_free_virt_channels' [-Wmissing-prototypes]
1210 | void hiedmac_free_virt_channels(struct dma_device *dmadev)
 |  ^~

vim +/dump_lli +144 drivers/dma/hiedmacv310.c

   142  
   143  #else
 > 144  void dump_lli(u64 *llis_vaddr, unsigned int num)
   145  {
   146  }
   147  #endif
   148  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


[PATCH 2/2] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-13 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1452 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1603 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..cd1fe30538ee
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   unsigned int id;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "lli num = 0%d", num);
+  

[PATCH 2/2] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-13 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1452 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1603 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..cd1fe30538ee
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   unsigned int id;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "lli num = 0%d", num);
+  

Re: [PATCH v2 1/2] watchdog: f71808e_wdt: refactor to platform device/driver pair

2020-11-08 Thread Guenter Roeck
On Tue, Oct 20, 2020 at 08:21:11AM +0200, Ahmad Fatoum wrote:
> Driver so far wasn't ported to the driver model and set up its
> miscdevice out of the init after probing the I/O ports for a watchdog
> with correct vendor and device revision.
> 
> Keep the device detection part at init time, but move watchdog setup
> to a platform driver probe function.
> 
> While at it, refactor some of the driver code we have to now touch
> anyway:
> 
>  - platform_device_id is used instead of the two big switches mapping
>hardware ID to an enum and then mapping it to a pinconf function
>  - we rename f71808e_ and watchdog_data to fintek_wdt, to avoid mix up
>of the generic parts up with the device specific parts
> 
> Suggested-by: Guenter Roeck 
> Signed-off-by: Ahmad Fatoum 

Sorry, I just found this. Sorry, it got lost.
The changes you are making here go way beyond a conversion to a platform
driver. I am not necessarily opposed to the changes, but they should be
split into multiple patches to simlify (and to a large degree enable)
a meaningful review. More comments inline.

> ---
>  drivers/watchdog/f71808e_wdt.c | 377 +++--
>  1 file changed, 215 insertions(+), 162 deletions(-)
> 
> diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
> index f60beec1bbae..4ff7a2509125 100644
> --- a/drivers/watchdog/f71808e_wdt.c
> +++ b/drivers/watchdog/f71808e_wdt.c
> @@ -9,12 +9,15 @@
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -110,22 +113,6 @@ module_param(start_withtimeout, uint, 0);
>  MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load 
> with"
>   " given initial timeout. Zero (default) disables this feature.");
>  
> -enum chips { f71808fg, f71858fg, f71862fg, f71868, f71869, f71882fg, 
> f71889fg,
> -  f81803, f81865, f81866};
> -
> -static const char *f71808e_names[] = {
> - "f71808fg",
> - "f71858fg",
> - "f71862fg",
> - "f71868",
> - "f71869",
> - "f71882fg",
> - "f71889fg",
> - "f81803",
> - "f81865",
> - "f81866",
> -};
> -
>  /* Super-I/O Function prototypes */
>  static inline int superio_inb(int base, int reg);
>  static inline int superio_inw(int base, int reg);
> @@ -136,9 +123,17 @@ static inline int superio_enter(int base);
>  static inline void superio_select(int base, int ld);
>  static inline void superio_exit(int base);
>  
> -struct watchdog_data {
> +struct fintek_wdt;
> +
> +struct fintek_wdt_variant {
> + u16 id;
> + void (*pinconf)(struct fintek_wdt *wd);
> + const char *identity_override;
> +};
> +
> +struct fintek_wdt {
>   unsigned short  sioaddr;
> - enum chips  type;
> + const struct fintek_wdt_variant *variant;

I'd rather have this all in here. Just add 
void (*pinconf)(struct fintek_wdt *wd);
and assign it in the probe function, or call it
from an array indexed with type.

This change is also independent of the conversion to a platform
driver and should be done in a separate patch.

>   unsigned long   opened;
>   struct mutexlock;
>   charexpect_close;
> @@ -152,10 +147,15 @@ struct watchdog_data {
>   charcaused_reboot;  /* last reboot was by the watchdog */
>  };
>  
> -static struct watchdog_data watchdog = {
> +static struct fintek_wdt watchdog = {
>   .lock = __MUTEX_INITIALIZER(watchdog.lock),
>  };
>  
> +static inline bool has_f81865_wdo_conf(struct fintek_wdt *wd)
> +{
> + return wd->variant->id == SIO_F81865_ID || wd->variant->id == 
> SIO_F81866_ID;
> +}
> +
This change is independent of the conversion to a platform driver
and should be a separate patch.

>  /* Super I/O functions */
>  static inline int superio_inb(int base, int reg)
>  {
> @@ -247,7 +247,7 @@ static int watchdog_set_pulse_width(unsigned int pw)
>   int err = 0;
>   unsigned int t1 = 25, t2 = 125, t3 = 5000;
>  
> - if (watchdog.type == f71868) {
> + if (watchdog.variant->id == SIO_F71868_ID) {

I am not sure if dropping watchdog.type and replacing it with SIO_F71868_ID
is a good idea. In the current code, there is no 1:1 match of those,
specifically for SIO_F71869_ID/SIO_F71869A_ID. Deviating from that only
complicates the code.

>   t1 = 30;
>   t2 = 150;
>   t3 = 6000;
> @@ -309,7 +309,6 @@ static int watchdog_keepalive(void)
>  static int watchdog_start(void)
>  {
>   int err;
> - u8 tmp;
>  
>   /* Make sure we don't die as soon as the watchdog is enabled below */
>   err = watchdog_keepalive();
> @@ -323,81 +322,12 @@ static int watchdog_start(void)
>   superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
>  
>   /* Watchdog pin configuration */
> - switch (watchdog.type) {
> - case f71808fg:
> - /* Set pin 21 to 

[PATCH v2 1/2] watchdog: f71808e_wdt: refactor to platform device/driver pair

2020-10-20 Thread Ahmad Fatoum
Driver so far wasn't ported to the driver model and set up its
miscdevice out of the init after probing the I/O ports for a watchdog
with correct vendor and device revision.

Keep the device detection part at init time, but move watchdog setup
to a platform driver probe function.

While at it, refactor some of the driver code we have to now touch
anyway:

 - platform_device_id is used instead of the two big switches mapping
   hardware ID to an enum and then mapping it to a pinconf function
 - we rename f71808e_ and watchdog_data to fintek_wdt, to avoid mix up
   of the generic parts up with the device specific parts

Suggested-by: Guenter Roeck 
Signed-off-by: Ahmad Fatoum 
---
 drivers/watchdog/f71808e_wdt.c | 377 +++--
 1 file changed, 215 insertions(+), 162 deletions(-)

diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index f60beec1bbae..4ff7a2509125 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -9,12 +9,15 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -110,22 +113,6 @@ module_param(start_withtimeout, uint, 0);
 MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
" given initial timeout. Zero (default) disables this feature.");
 
-enum chips { f71808fg, f71858fg, f71862fg, f71868, f71869, f71882fg, f71889fg,
-f81803, f81865, f81866};
-
-static const char *f71808e_names[] = {
-   "f71808fg",
-   "f71858fg",
-   "f71862fg",
-   "f71868",
-   "f71869",
-   "f71882fg",
-   "f71889fg",
-   "f81803",
-   "f81865",
-   "f81866",
-};
-
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
@@ -136,9 +123,17 @@ static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
-struct watchdog_data {
+struct fintek_wdt;
+
+struct fintek_wdt_variant {
+   u16 id;
+   void (*pinconf)(struct fintek_wdt *wd);
+   const char *identity_override;
+};
+
+struct fintek_wdt {
unsigned short  sioaddr;
-   enum chips  type;
+   const struct fintek_wdt_variant *variant;
unsigned long   opened;
struct mutexlock;
charexpect_close;
@@ -152,10 +147,15 @@ struct watchdog_data {
charcaused_reboot;  /* last reboot was by the watchdog */
 };
 
-static struct watchdog_data watchdog = {
+static struct fintek_wdt watchdog = {
.lock = __MUTEX_INITIALIZER(watchdog.lock),
 };
 
+static inline bool has_f81865_wdo_conf(struct fintek_wdt *wd)
+{
+   return wd->variant->id == SIO_F81865_ID || wd->variant->id == 
SIO_F81866_ID;
+}
+
 /* Super I/O functions */
 static inline int superio_inb(int base, int reg)
 {
@@ -247,7 +247,7 @@ static int watchdog_set_pulse_width(unsigned int pw)
int err = 0;
unsigned int t1 = 25, t2 = 125, t3 = 5000;
 
-   if (watchdog.type == f71868) {
+   if (watchdog.variant->id == SIO_F71868_ID) {
t1 = 30;
t2 = 150;
t3 = 6000;
@@ -309,7 +309,6 @@ static int watchdog_keepalive(void)
 static int watchdog_start(void)
 {
int err;
-   u8 tmp;
 
/* Make sure we don't die as soon as the watchdog is enabled below */
err = watchdog_keepalive();
@@ -323,81 +322,12 @@ static int watchdog_start(void)
superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
 
/* Watchdog pin configuration */
-   switch (watchdog.type) {
-   case f71808fg:
-   /* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */
-   superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT2, 3);
-   superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 3);
-   break;
-
-   case f71862fg:
-   if (f71862fg_pin == 63) {
-   /* SPI must be disabled first to use this pin! */
-   superio_clear_bit(watchdog.sioaddr, 
SIO_REG_ROM_ADDR_SEL, 6);
-   superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 4);
-   } else if (f71862fg_pin == 56) {
-   superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 1);
-   }
-   break;
-
-   case f71868:
-   case f71869:
-   /* GPIO14 --> WDTRST# */
-   superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 4);
-   break;
-
-   case f71882fg:
-   /* Set pin 56 to WDTRST# */
-   superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 1);
-   break;
-
-   case f71889fg:
-   /* set pin 40 to WDTRST# */
-   superio_outb(watchdog.sioaddr, SIO_REG_MFUNCT3,
-

Re: [PATCH v8 1/6] PCI/ERR: get device before call device driver to avoid NULL pointer dereference

2020-10-07 Thread Ethan Zhao
On Thu, Oct 8, 2020 at 1:24 AM Kuppuswamy, Sathyanarayanan
 wrote:
>
>
> On 10/7/20 4:31 AM, Ethan Zhao wrote:
> > During DPC error injection test we found there is race condition between
> > pciehp and DPC driver, NULL pointer dereference caused panic as following
> >
> >   # setpci -s 64:02.0 0x196.w=000a
> >// 64:02.0 is rootport has DPC capability
> >   # setpci -s 65:00.0 0x04.w=0544
> >// 65:00.0 is NVMe SSD populated in above port
> >   # mount /dev/nvme0n1p1 nvme
> >
> >   (tested on stable 5.8 & ICS(Ice Lake SP platform, see
> >   https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))
> >
> >   BUG: kernel NULL pointer dereference, address: 0050
> >   ...
> >   CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 
> > 5.8.0-0.0.7.el8.x86_64+ #1
> >   RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
> >   Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 
> > 65 ff
> >   ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 
> > 3a 00
> >   41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
> >   RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
> >   RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
> >   RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
> >   RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
> >   R10: 00eb8ebeab53 R11: 93453258 R12: 0002
> >   R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
> >   FS:  () GS:ff4e3eab1fd0() 
> > knlGS:
> >   CS:  0010 DS:  ES:  CR0: 80050033
> >   CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
> >   DR0:  DR1:  DR2: 
> >   DR3:  DR6: fffe0ff0 DR7: 0400
> >   PKRU: 5554
> >   Call Trace:
> >   ? report_normal_detected+0x20/0x20
> >   report_frozen_detected+0x16/0x20
> >   pci_walk_bus+0x75/0x90
> >   ? dpc_irq+0x90/0x90
> >   pcie_do_recovery+0x157/0x201
> >   ? irq_finalize_oneshot.part.47+0xe0/0xe0
> >   dpc_handler+0x29/0x40
> >   irq_thread_fn+0x24/0x60
> >   ...
> >
> > Debug shows when port DPC feature was enabled and triggered by errors,
> > DLLSC/PDC/DPC interrupts will be sent to pciehp and DPC driver almost
> > at the same time, and no delay between them is required by specification.
> > so DPC driver and pciehp drivers may handle these interrupts cocurrently.
> >
> > While DPC driver is doing pci_walk_bus() and calling device driver's
> > callback without pci_dev_get() to increase device reference count, the
> > device and its driver instance are likely being freed by
> > pci_stop_and_removed_bus_device()
> > -> pci_dev_put().
> >
> > So does pci_dev_get() before using the device instance to avoid NULL
> > pointer dereference.
> Won't it be better if you get this in pcie_do_recovery()?

Don't think so, just like lock, we should keep the scope with lock
protected as small as possible.
Locking a big area unnecessarily isn't acceptable.

Thanks,
Ethan
> >
> > Signed-off-by: Ethan Zhao 
> > Tested-by: Wen Jin 
> > Tested-by: Shanshan Zhang 
> > ---
> > Changes:
> >   v2: revise doc according to Andy's suggestion.
> >   v3: no change.
> >   v4: no change.
> >   v5: no change.
> >   v6: moved to [1/5] from [3/5] and revised comment according to Lukas'
> >   suggestion.
> >   v7: no change.
> >   v8: no change.
> >
> >   drivers/pci/pcie/err.c | 12 
> >   1 file changed, 12 insertions(+)
> >
> > diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
> > index c543f419d8f9..e35c4480c86b 100644
> > --- a/drivers/pci/pcie/err.c
> > +++ b/drivers/pci/pcie/err.c
> > @@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
> >   pci_ers_result_t vote;
> >   const struct pci_error_handlers *err_handler;
> >
> > + if (!pci_dev_get(dev))
> > + return 0;
> >   device_lock(>dev);
> >   if (!pci_dev_set_io_state(dev, state) ||
> >   !dev->driver ||
> > @@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
> >   pci_uevent_ers(dev, vote);
> >   *result = merge_result(*result, vote);
> >   device_unlock(>dev);
> > + pci_dev_put(dev);
> >   return 0;
> >   }
> >
> > @@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
> > *data)
> >   pci_ers_result_t vote, *result = data;
> >   const struct pci_error_handlers *err_handler;
> >
> > + if (!pci_dev_get(dev))
> > + return 0;
> >   device_lock(>dev);
> >   if (!dev->driver ||
> >   !dev->driver->err_handler ||
> > @@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, 
> > void *data)
> >   *result = merge_result(*result, vote);
> >   out:
> >   device_unlock(>dev);
> > + pci_dev_put(dev);
> >   return 0;
> >   }
> >
> > @@ -113,6 +119,8 @@ static int report_slot_reset(struct pci_dev 

Re: [PATCH v8 1/6] PCI/ERR: get device before call device driver to avoid NULL pointer dereference

2020-10-07 Thread Kuppuswamy, Sathyanarayanan



On 10/7/20 4:31 AM, Ethan Zhao wrote:

During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer dereference caused panic as following

  # setpci -s 64:02.0 0x196.w=000a
   // 64:02.0 is rootport has DPC capability
  # setpci -s 65:00.0 0x04.w=0544
   // 65:00.0 is NVMe SSD populated in above port
  # mount /dev/nvme0n1p1 nvme

  (tested on stable 5.8 & ICS(Ice Lake SP platform, see
  https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

  BUG: kernel NULL pointer dereference, address: 0050
  ...
  CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
  RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
  Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
  ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 
00
  41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
  RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
  RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
  RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
  RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
  R10: 00eb8ebeab53 R11: 93453258 R12: 0002
  R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
  FS:  () GS:ff4e3eab1fd0() knlGS:
  CS:  0010 DS:  ES:  CR0: 80050033
  CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
  DR0:  DR1:  DR2: 
  DR3:  DR6: fffe0ff0 DR7: 0400
  PKRU: 5554
  Call Trace:
  ? report_normal_detected+0x20/0x20
  report_frozen_detected+0x16/0x20
  pci_walk_bus+0x75/0x90
  ? dpc_irq+0x90/0x90
  pcie_do_recovery+0x157/0x201
  ? irq_finalize_oneshot.part.47+0xe0/0xe0
  dpc_handler+0x29/0x40
  irq_thread_fn+0x24/0x60
  ...

Debug shows when port DPC feature was enabled and triggered by errors,
DLLSC/PDC/DPC interrupts will be sent to pciehp and DPC driver almost
at the same time, and no delay between them is required by specification.
so DPC driver and pciehp drivers may handle these interrupts cocurrently.

While DPC driver is doing pci_walk_bus() and calling device driver's
callback without pci_dev_get() to increase device reference count, the
device and its driver instance are likely being freed by
pci_stop_and_removed_bus_device()
-> pci_dev_put().

So does pci_dev_get() before using the device instance to avoid NULL
pointer dereference.

Won't it be better if you get this in pcie_do_recovery()?


Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
---
Changes:
  v2: revise doc according to Andy's suggestion.
  v3: no change.
  v4: no change.
  v5: no change.
  v6: moved to [1/5] from [3/5] and revised comment according to Lukas'
  suggestion.
  v7: no change.
  v8: no change.

  drivers/pci/pcie/err.c | 12 
  1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
  
+	if (!pci_dev_get(dev))

+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
  }
  
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data)

pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
  
+	if (!pci_dev_get(dev))

+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
  out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
  }
  
@@ -113,6 +119,8 @@ static int report_slot_reset(struct pci_dev *dev, void *data)

pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
  
+	if (!pci_dev_get(dev))

+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -124,6 +132,7 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
  out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
  }
  
@@ -131,6 +140,8 @@ static int report_resume(struct pci_dev *dev, void *data)

  {
const struct pci_error_handlers *err_handler;
  
+	if 

[PATCH v8 1/6] PCI/ERR: get device before call device driver to avoid NULL pointer dereference

2020-10-07 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer dereference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 BUG: kernel NULL pointer dereference, address: 0050
 ...
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 ...

Debug shows when port DPC feature was enabled and triggered by errors,
DLLSC/PDC/DPC interrupts will be sent to pciehp and DPC driver almost
at the same time, and no delay between them is required by specification.
so DPC driver and pciehp drivers may handle these interrupts cocurrently.

While DPC driver is doing pci_walk_bus() and calling device driver's 
callback without pci_dev_get() to increase device reference count, the
device and its driver instance are likely being freed by
pci_stop_and_removed_bus_device()
-> pci_dev_put().

So does pci_dev_get() before using the device instance to avoid NULL
pointer dereference.

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
---
Changes:
 v2: revise doc according to Andy's suggestion.
 v3: no change.
 v4: no change.
 v5: no change.
 v6: moved to [1/5] from [3/5] and revised comment according to Lukas'
 suggestion.
 v7: no change.
 v8: no change.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -113,6 +119,8 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -124,6 +132,7 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -131,6 +140,8 @@ static int report_resume(struct pci_dev *dev, void *data)
 {
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||

[PATCH v7 1/5] PCI/ERR: get device before call device driver to avoid NULL pointer dereference

2020-10-03 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer dereference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 BUG: kernel NULL pointer dereference, address: 0050
 ...
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 ...

Debug shows when port DPC feature was enabled and triggered by errors,
DLLSC/PDC/DPC interrupts will be sent to pciehp and DPC driver almost
at the same time, and no delay between them is required by specification.
so DPC driver and pciehp drivers may handle these interrupts cocurrently.

While DPC driver is doing pci_walk_bus() and calling device driver's callback
without pci_dev_get() to increase device reference count, the device and its
driver instance are likely being freed by pci_stop_and_removed_bus_device()
-> pci_dev_put().

So does pci_dev_get() before using the device instance to avoid NULL pointer
dereference.

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
---
Changes:
 v2: revise doc according to Andy's suggestion.
 v3: no change.
 v4: no change.
 v5: no change.
 v6: moved to [1/5] from [3/5] and revised comment according to Lukas'
 suggestion.
 v7: no change.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -113,6 +119,8 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -124,6 +132,7 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -131,6 +140,8 @@ static int report_resume(struct pci_dev *dev, void *data)
 {
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
!dev->driver ||
@@ 

[PATCH v6 1/5] PCI/ERR: get device before call device driver to avoid NULL pointer dereference

2020-09-30 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer dereference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 BUG: kernel NULL pointer dereference, address: 0050
 ...
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 ...

Debug shows when port DPC feature was enabled and triggered by errors,
DLLSC/PDC/DPC interrupts will be sent to pciehp and DPC driver almost
at the same time, and no delay between them is required by specification.
so DPC driver and pciehp drivers may handle these interrupts cocurrently.

While DPC driver is doing pci_walk_bus() and calling device driver's 
callback without pci_dev_get() to increase device reference count, the
device and its driver instance are likely being freed by 

pci_stop_and_removed_bus_device()
-> pci_dev_put().

So does pci_dev_get() before using the device instance to avoid NULL
pointer dereference.

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
---
 v2: revise doc according to Andy's suggestion.
 v3: no change.
 v4: no change.
 v5: no change.
 v6: moved to [1/5] from [3/5] and revised comment according to Lukas'
 suggestion.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -113,6 +119,8 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -124,6 +132,7 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -131,6 +140,8 @@ static int report_resume(struct pci_dev *dev, void *data)
 {
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
!dev->driver ||
@@ -143,6 +154,7 @@ 

Re: [PATCH 3/5] PCI/ERR: get device before call device driver to avoid null pointer reference

2020-09-29 Thread Ethan Zhao
On Tue, Sep 29, 2020 at 6:48 PM Andy Shevchenko
 wrote:
>
> On Tue, Sep 29, 2020 at 05:38:00PM +0800, Ethan Zhao wrote:
> > On Tue, Sep 29, 2020 at 4:51 PM Andy Shevchenko
> >  wrote:
> > > On Tue, Sep 29, 2020 at 10:35:14AM +0800, Ethan Zhao wrote:
> > > > Preferred style, there will be cleared comment in v6.
> > >
> > > Avoid top postings.
> > >
> > > > On Sat, Sep 26, 2020 at 12:42 AM Andy Shevchenko
> > > >  wrote:
> > > > > On Thu, Sep 24, 2020 at 10:34:21PM -0400, Ethan Zhao wrote:
>
> ...
>
> > > > > >  Buffer I/O error on dev nvme0n1p1, logical block 468843328,
> > > > > >  async page read
> > > > > >  BUG: kernel NULL pointer dereference, address: 0050
> > > > > >  #PF: supervisor read access in kernel mode
> > > > > >  #PF: error_code(0x) - not-present page
> > > > >
> > > > > Same comment about Oops.
> > >
> > > In another thread it was a good advice to move the full Oops (if you 
> > > think it's
> > > very useful to have) after the cutter '---' line, so it will be in email
> > > archives but Git history.
> >
> > So git history wouldn't give any of the Oops context, and he/she has
> > to access LKML,
> > if offline, then ...lost.
>
> Tell me, do you really think the line:
>#PF: error_code(0x) - not-present page
> makes any sense in the commit message?
>
> I do not think so. And so on, for almost 60% of the Oops.
> Really, to help one person you will make millions suffering. It's not okay.
>
If you and millions  feel so suffered,  why not try to simplify the
Oops code to not
output nonsense too much to console and log. :)

They might not be so important to old birds as you. but it is easy to cut off
the road for newcomers.

Anyway, it is not the focus of this patchset. help to take a look and
try the code.


Thanks,
Ethan

> --
> With Best Regards,
> Andy Shevchenko
>
>


Re: [PATCH 3/5] PCI/ERR: get device before call device driver to avoid null pointer reference

2020-09-29 Thread Andy Shevchenko
On Tue, Sep 29, 2020 at 05:38:00PM +0800, Ethan Zhao wrote:
> On Tue, Sep 29, 2020 at 4:51 PM Andy Shevchenko
>  wrote:
> > On Tue, Sep 29, 2020 at 10:35:14AM +0800, Ethan Zhao wrote:
> > > Preferred style, there will be cleared comment in v6.
> >
> > Avoid top postings.
> >
> > > On Sat, Sep 26, 2020 at 12:42 AM Andy Shevchenko
> > >  wrote:
> > > > On Thu, Sep 24, 2020 at 10:34:21PM -0400, Ethan Zhao wrote:

...

> > > > >  Buffer I/O error on dev nvme0n1p1, logical block 468843328,
> > > > >  async page read
> > > > >  BUG: kernel NULL pointer dereference, address: 0050
> > > > >  #PF: supervisor read access in kernel mode
> > > > >  #PF: error_code(0x) - not-present page
> > > >
> > > > Same comment about Oops.
> >
> > In another thread it was a good advice to move the full Oops (if you think 
> > it's
> > very useful to have) after the cutter '---' line, so it will be in email
> > archives but Git history.
> 
> So git history wouldn't give any of the Oops context, and he/she has
> to access LKML,
> if offline, then ...lost.

Tell me, do you really think the line:
   #PF: error_code(0x) - not-present page
makes any sense in the commit message?

I do not think so. And so on, for almost 60% of the Oops.
Really, to help one person you will make millions suffering. It's not okay.

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH 3/5] PCI/ERR: get device before call device driver to avoid null pointer reference

2020-09-29 Thread Ethan Zhao
Andy,

On Tue, Sep 29, 2020 at 4:51 PM Andy Shevchenko
 wrote:
>
> On Tue, Sep 29, 2020 at 10:35:14AM +0800, Ethan Zhao wrote:
> > Preferred style, there will be cleared comment in v6.
>
> Avoid top postings.
>
> > On Sat, Sep 26, 2020 at 12:42 AM Andy Shevchenko
> >  wrote:
> > >
> > > On Thu, Sep 24, 2020 at 10:34:21PM -0400, Ethan Zhao wrote:
> > > > During DPC error injection test we found there is race condition between
> > > > pciehp and DPC driver, null pointer reference caused panic as following
> > >
> > > null -> NULL
> > >
> > > >
> > > >  # setpci -s 64:02.0 0x196.w=000a
> > > >   // 64:02.0 is rootport has DPC capability
> > > >  # setpci -s 65:00.0 0x04.w=0544
> > > >   // 65:00.0 is NVMe SSD populated in above port
> > > >  # mount /dev/nvme0n1p1 nvme
> > > >
> > > >  (tested on stable 5.8 & ICX platform)
> > > >
> > > >  Buffer I/O error on dev nvme0n1p1, logical block 468843328,
> > > >  async page read
> > > >  BUG: kernel NULL pointer dereference, address: 0050
> > > >  #PF: supervisor read access in kernel mode
> > > >  #PF: error_code(0x) - not-present page
> > >
> > > Same comment about Oops.
>
> In another thread it was a good advice to move the full Oops (if you think 
> it's
> very useful to have) after the cutter '---' line, so it will be in email
> archives but Git history.

So git history wouldn't give any of the Oops context, and he/she has
to access LKML,
if offline, then ...lost.

Thanks,
Ethan
>
> --
> With Best Regards,
> Andy Shevchenko
>
>


Re: [PATCH 3/5] PCI/ERR: get device before call device driver to avoid null pointer reference

2020-09-29 Thread Andy Shevchenko
On Tue, Sep 29, 2020 at 10:35:14AM +0800, Ethan Zhao wrote:
> Preferred style, there will be cleared comment in v6.

Avoid top postings.

> On Sat, Sep 26, 2020 at 12:42 AM Andy Shevchenko
>  wrote:
> >
> > On Thu, Sep 24, 2020 at 10:34:21PM -0400, Ethan Zhao wrote:
> > > During DPC error injection test we found there is race condition between
> > > pciehp and DPC driver, null pointer reference caused panic as following
> >
> > null -> NULL
> >
> > >
> > >  # setpci -s 64:02.0 0x196.w=000a
> > >   // 64:02.0 is rootport has DPC capability
> > >  # setpci -s 65:00.0 0x04.w=0544
> > >   // 65:00.0 is NVMe SSD populated in above port
> > >  # mount /dev/nvme0n1p1 nvme
> > >
> > >  (tested on stable 5.8 & ICX platform)
> > >
> > >  Buffer I/O error on dev nvme0n1p1, logical block 468843328,
> > >  async page read
> > >  BUG: kernel NULL pointer dereference, address: 0050
> > >  #PF: supervisor read access in kernel mode
> > >  #PF: error_code(0x) - not-present page
> >
> > Same comment about Oops.

In another thread it was a good advice to move the full Oops (if you think it's
very useful to have) after the cutter '---' line, so it will be in email
archives but Git history.

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH 3/5] PCI/ERR: get device before call device driver to avoid null pointer reference

2020-09-28 Thread Ethan Zhao
Preferred style, there will be cleared comment in v6.

Thanks,
Ethan

On Sat, Sep 26, 2020 at 12:42 AM Andy Shevchenko
 wrote:
>
> On Thu, Sep 24, 2020 at 10:34:21PM -0400, Ethan Zhao wrote:
> > During DPC error injection test we found there is race condition between
> > pciehp and DPC driver, null pointer reference caused panic as following
>
> null -> NULL
>
> >
> >  # setpci -s 64:02.0 0x196.w=000a
> >   // 64:02.0 is rootport has DPC capability
> >  # setpci -s 65:00.0 0x04.w=0544
> >   // 65:00.0 is NVMe SSD populated in above port
> >  # mount /dev/nvme0n1p1 nvme
> >
> >  (tested on stable 5.8 & ICX platform)
> >
> >  Buffer I/O error on dev nvme0n1p1, logical block 468843328,
> >  async page read
> >  BUG: kernel NULL pointer dereference, address: 0050
> >  #PF: supervisor read access in kernel mode
> >  #PF: error_code(0x) - not-present page
>
> Same comment about Oops.
>
> --
> With Best Regards,
> Andy Shevchenko
>
>


Re: [PATCH 3/5 V55555] PCI/ERR: get device before call device driver to avoid NULL pointer reference

2020-09-28 Thread Ethan Zhao
On Mon, Sep 28, 2020 at 4:46 PM Andy Shevchenko
 wrote:
>
> On Mon, Sep 28, 2020 at 7:13 AM Ethan Zhao  wrote:
>
> Same comments as per v4.
> Also you have an issue in versioning here. Use -v parameter to `git
> format-patch`, it will do it for you nicely.

Aha, git has got this function. I thought it was still manual
work. great tip.!

Thanks,
Ethan

>
> --
> With Best Regards,
> Andy Shevchenko


Re: [PATCH 3/5 V55555] PCI/ERR: get device before call device driver to avoid NULL pointer reference

2020-09-28 Thread Andy Shevchenko
On Mon, Sep 28, 2020 at 7:13 AM Ethan Zhao  wrote:

Same comments as per v4.
Also you have an issue in versioning here. Use -v parameter to `git
format-patch`, it will do it for you nicely.

-- 
With Best Regards,
Andy Shevchenko


[PATCH 3/5 V55555] PCI/ERR: get device before call device driver to avoid NULL pointer reference

2020-09-27 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer reference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 Buffer I/O error on dev nvme0n1p1, logical block 468843328,
 async page read
 BUG: kernel NULL pointer dereference, address: 0050
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
 PGD 0
 Oops:  [#1] SMP NOPTI
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 irq_thread+0xea/0x170
 ? irq_forced_thread_fn+0x80/0x80
 ? irq_thread_check_affinity+0xf0/0xf0
 kthread+0x124/0x140
 ? kthread_park+0x90/0x90
 ret_from_fork+0x1f/0x30
 Modules linked in: nft_fib_inet.
 CR2: 0050

Though we partly close the race condition with patch 'PCI: pciehp: check
and wait port status out of DPC before handling DLLSC and PDC', but there
is no hardware spec or software sequence to guarantee the pcie_ist() run
into pci_wait_port_outdpc() first or DPC triggered status bits being set
first when errors triggered DPC containment procedure, so device still
could be removed by function pci_stop_and_removed_bus_device() then freed
by pci_dev_put() in pciehp driver first during pcie_do_recover()/
pci_walk_bus() is called by dpc_handler() in DPC driver.

Maybe unify pci_bus_sem and pci_rescan_remove_lock to serialize the
removal and walking operation is the right way, but here we use
pci_dev_get() to increase the reference count of device before using the
device to avoid it is freed in use.

With this patch and patch 'PCI: pciehp: check and wait port status out of
DPC before handling DLLSC and PDC', stable 5.9-rc6 could pass the error
injection test and no panic happened.

Brute DPC error injection script:

for i in {0..100}
do
setpci -s 64:02.0 0x196.w=000a
setpci -s 65:00.0 0x04.w=0544
mount /dev/nvme0n1p1 /root/nvme
sleep 1
done

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
---
Changes:
 V2: revise doc according to Andy's suggestion.
 V3: no change.
 V4: no change.
 V5: no change.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ 

[PATCH 3/5 V4] PCI/ERR: get device before call device driver to avoid NULL pointer reference

2020-09-27 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer reference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 Buffer I/O error on dev nvme0n1p1, logical block 468843328,
 async page read
 BUG: kernel NULL pointer dereference, address: 0050
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
 PGD 0
 Oops:  [#1] SMP NOPTI
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 irq_thread+0xea/0x170
 ? irq_forced_thread_fn+0x80/0x80
 ? irq_thread_check_affinity+0xf0/0xf0
 kthread+0x124/0x140
 ? kthread_park+0x90/0x90
 ret_from_fork+0x1f/0x30
 Modules linked in: nft_fib_inet.
 CR2: 0050

Though we partly close the race condition with patch 'PCI: pciehp: check
and wait port status out of DPC before handling DLLSC and PDC', but there
is no hardware spec or software sequence to guarantee the pcie_ist() run
into pci_wait_port_outdpc() first or DPC triggered status bits being set
first when errors triggered DPC containment procedure, so device still
could be removed by function pci_stop_and_removed_bus_device() then freed
by pci_dev_put() in pciehp driver first during pcie_do_recover()/
pci_walk_bus() is called by dpc_handler() in DPC driver.

Maybe unify pci_bus_sem and pci_rescan_remove_lock to serialize the
removal and walking operation is the right way, but here we use
pci_dev_get() to increase the reference count of device before using the
device to avoid it is freed in use.

With this patch and patch 'PCI: pciehp: check and wait port status out of
DPC before handling DLLSC and PDC', stable 5.9-rc6 could pass the error
injection test and no panic happened.

Brute DPC error injection script:

for i in {0..100}
do
setpci -s 64:02.0 0x196.w=000a
setpci -s 65:00.0 0x04.w=0544
mount /dev/nvme0n1p1 /root/nvme
sleep 1
done

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
Reviewed-by: Andy Shevchenko 
---
Changes:
 V2: revise doc according to Andy's suggestion.
 V3: no change.
 V4: no change.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;

[PATCH 3/5 V3] PCI/ERR: get device before call device driver to avoid NULL pointer reference

2020-09-26 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer reference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 Buffer I/O error on dev nvme0n1p1, logical block 468843328,
 async page read
 BUG: kernel NULL pointer dereference, address: 0050
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
 PGD 0
 Oops:  [#1] SMP NOPTI
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 irq_thread+0xea/0x170
 ? irq_forced_thread_fn+0x80/0x80
 ? irq_thread_check_affinity+0xf0/0xf0
 kthread+0x124/0x140
 ? kthread_park+0x90/0x90
 ret_from_fork+0x1f/0x30
 Modules linked in: nft_fib_inet.
 CR2: 0050

Though we partly close the race condition with patch 'PCI: pciehp: check
and wait port status out of DPC before handling DLLSC and PDC', but there
is no hardware spec or software sequence to guarantee the pcie_ist() run
into pci_wait_port_outdpc() first or DPC triggered status bits being set
first when errors triggered DPC containment procedure, so device still
could be removed by function pci_stop_and_removed_bus_device() then freed
by pci_dev_put() in pciehp driver first during pcie_do_recover()/
pci_walk_bus() is called by dpc_handler() in DPC driver.

Maybe unify pci_bus_sem and pci_rescan_remove_lock to serialize the
removal and walking operation is the right way, but here we use
pci_dev_get() to increase the reference count of device before using the
device to avoid it is freed in use.

With this patch and patch 'PCI: pciehp: check and wait port status out of
DPC before handling DLLSC and PDC', stable 5.9-rc6 could pass the error
injection test and no panic happened.

Brute DPC error injection script:

for i in {0..100}
do
setpci -s 64:02.0 0x196.w=000a
setpci -s 65:00.0 0x04.w=0544
mount /dev/nvme0n1p1 /root/nvme
sleep 1
done

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
Reviewed-by: Andy Shevchenko 
---
Changes:
 V2: revise doc according to Andy's suggestion.
 V3: no change.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -113,6 

[PATCH 3/5 V2] PCI/ERR: get device before call device driver to avoid NULL pointer reference

2020-09-26 Thread Ethan Zhao
During DPC error injection test we found there is race condition between
pciehp and DPC driver, NULL pointer reference caused panic as following

 # setpci -s 64:02.0 0x196.w=000a
  // 64:02.0 is rootport has DPC capability
 # setpci -s 65:00.0 0x04.w=0544
  // 65:00.0 is NVMe SSD populated in above port
 # mount /dev/nvme0n1p1 nvme

 (tested on stable 5.8 & ICS(Ice Lake SP platform, see
 https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server))

 Buffer I/O error on dev nvme0n1p1, logical block 468843328,
 async page read
 BUG: kernel NULL pointer dereference, address: 0050
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
 PGD 0
 Oops:  [#1] SMP NOPTI
 CPU: 12 PID: 513 Comm: irq/124-pcie-dp Not tainted 5.8.0-0.0.7.el8.x86_64+ #1
 RIP: 0010:report_error_detected.cold.4+0x7d/0xe6
 Code: b6 d0 e8 e8 fe 11 00 e8 16 c5 fb ff be 06 00 00 00 48 89 df e8 d3 65 ff
 ff b8 06 00 00 00 e9 75 fc ff ff 48 8b 43 68 45 31 c9 <48> 8b 50 50 48 83 3a 00
 41 0f 94 c1 45 31 c0 48 85 d2 41 0f 94 c0
 RSP: 0018:ff8e06cf8762fda8 EFLAGS: 00010246
 RAX:  RBX: ff4e3eaacf42a000 RCX: ff4e3eb31f223c01
 RDX: ff4e3eaacf42a140 RSI: ff4e3eb31f223c00 RDI: ff4e3eaacf42a138
 RBP: ff8e06cf8762fdd0 R08: 00bf R09: 
 R10: 00eb8ebeab53 R11: 93453258 R12: 0002
 R13: ff4e3eaacf42a130 R14: ff8e06cf8762fe2c R15: ff4e3eab44733828
 FS:  () GS:ff4e3eab1fd0() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0050 CR3: 000f8f80a004 CR4: 00761ee0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 PKRU: 5554
 Call Trace:
 ? report_normal_detected+0x20/0x20
 report_frozen_detected+0x16/0x20
 pci_walk_bus+0x75/0x90
 ? dpc_irq+0x90/0x90
 pcie_do_recovery+0x157/0x201
 ? irq_finalize_oneshot.part.47+0xe0/0xe0
 dpc_handler+0x29/0x40
 irq_thread_fn+0x24/0x60
 irq_thread+0xea/0x170
 ? irq_forced_thread_fn+0x80/0x80
 ? irq_thread_check_affinity+0xf0/0xf0
 kthread+0x124/0x140
 ? kthread_park+0x90/0x90
 ret_from_fork+0x1f/0x30
 Modules linked in: nft_fib_inet.
 CR2: 0050

Though we partly close the race condition with patch 'PCI: pciehp: check
and wait port status out of DPC before handling DLLSC and PDC', but there
is no hardware spec or software sequence to guarantee the pcie_ist() run
into pci_wait_port_outdpc() first or DPC triggered status bits being set
first when errors triggered DPC containment procedure, so device still
could be removed by function pci_stop_and_removed_bus_device() then freed
by pci_dev_put() in pciehp driver first during pcie_do_recover()/
pci_walk_bus() is called by dpc_handler() in DPC driver.

Maybe unify pci_bus_sem and pci_rescan_remove_lock to serialize the
removal and walking operation is the right way, but here we use
pci_dev_get() to increase the reference count of device before using the
device to avoid it is freed in use.

With this patch and patch 'PCI: pciehp: check and wait port status out of
DPC before handling DLLSC and PDC', stable 5.9-rc6 could pass the error
injection test and no panic happened.

Brute DPC error injection script:

for i in {0..100}
do
setpci -s 64:02.0 0x196.w=000a
setpci -s 65:00.0 0x04.w=0544
mount /dev/nvme0n1p1 /root/nvme
sleep 1
done

Signed-off-by: Ethan Zhao 
Tested-by: Wen Jin 
Tested-by: Shanshan Zhang 
Reviewed-by: Andy Shevchenko 
---
Changes:
 V2: revise doc according to Andy's suggestion.

 drivers/pci/pcie/err.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index c543f419d8f9..e35c4480c86b 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -52,6 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!pci_dev_set_io_state(dev, state) ||
!dev->driver ||
@@ -76,6 +78,7 @@ static int report_error_detected(struct pci_dev *dev,
pci_uevent_ers(dev, vote);
*result = merge_result(*result, vote);
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -94,6 +97,8 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
 
+   if (!pci_dev_get(dev))
+   return 0;
device_lock(>dev);
if (!dev->driver ||
!dev->driver->err_handler ||
@@ -105,6 +110,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
*result = merge_result(*result, vote);
 out:
device_unlock(>dev);
+   pci_dev_put(dev);
return 0;
 }
 
@@ -113,6 +119,8 @@ static 

Re: [PATCH 3/5] PCI/ERR: get device before call device driver to avoid null pointer reference

2020-09-25 Thread Andy Shevchenko
On Thu, Sep 24, 2020 at 10:34:21PM -0400, Ethan Zhao wrote:
> During DPC error injection test we found there is race condition between
> pciehp and DPC driver, null pointer reference caused panic as following

null -> NULL

> 
>  # setpci -s 64:02.0 0x196.w=000a
>   // 64:02.0 is rootport has DPC capability
>  # setpci -s 65:00.0 0x04.w=0544
>   // 65:00.0 is NVMe SSD populated in above port
>  # mount /dev/nvme0n1p1 nvme
> 
>  (tested on stable 5.8 & ICX platform)
> 
>  Buffer I/O error on dev nvme0n1p1, logical block 468843328,
>  async page read
>  BUG: kernel NULL pointer dereference, address: 0050
>  #PF: supervisor read access in kernel mode
>  #PF: error_code(0x) - not-present page

Same comment about Oops.

-- 
With Best Regards,
Andy Shevchenko




[PATCH v10 04/18] nitro_enclaves: Init PCI device driver

2020-09-21 Thread Andra Paraschiv
The Nitro Enclaves PCI device is used by the kernel driver as a means of
communication with the hypervisor on the host where the primary VM and
the enclaves run. It handles requests with regard to enclave lifetime.

Setup the PCI device driver and add support for MSI-X interrupts.

Changelog

v9 -> v10

* Update commit message to include the changelog before the SoB tag(s).

v8 -> v9

* Init the reference to the ne_pci_dev in the ne_devs data structure.

v7 -> v8

* Add NE PCI driver shutdown logic.

v6 -> v7

* No changes.

v5 -> v6

* Update documentation to kernel-doc format.

v4 -> v5

* Remove sanity checks for situations that shouldn't happen, only if
  buggy system or broken logic at all.

v3 -> v4

* Use dev_err instead of custom NE log pattern.
* Update NE PCI driver name to "nitro_enclaves".

v2 -> v3

* Remove the GPL additional wording as SPDX-License-Identifier is
  already in place.
* Remove the WARN_ON calls.
* Remove linux/bug include that is not needed.
* Update static calls sanity checks.
* Remove "ratelimited" from the logs that are not in the ioctl call
  paths.
* Update kzfree() calls to kfree().

v1 -> v2

* Add log pattern for NE.
* Update PCI device setup functions to receive PCI device data structure and
  then get private data from it inside the functions logic.
* Remove the BUG_ON calls.
* Add teardown function for MSI-X setup.
* Update goto labels to match their purpose.
* Implement TODO for NE PCI device disable state check.
* Update function name for NE PCI device probe / remove.

Signed-off-by: Alexandru-Catalin Vasile 
Signed-off-by: Alexandru Ciobotaru 
Signed-off-by: Andra Paraschiv 
Reviewed-by: Alexander Graf 
---
 drivers/virt/nitro_enclaves/ne_pci_dev.c | 304 +++
 1 file changed, 304 insertions(+)
 create mode 100644 drivers/virt/nitro_enclaves/ne_pci_dev.c

diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.c 
b/drivers/virt/nitro_enclaves/ne_pci_dev.c
new file mode 100644
index ..32f07345c3b5
--- /dev/null
+++ b/drivers/virt/nitro_enclaves/ne_pci_dev.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ */
+
+/**
+ * DOC: Nitro Enclaves (NE) PCI device driver.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ne_misc_dev.h"
+#include "ne_pci_dev.h"
+
+/**
+ * NE_DEFAULT_TIMEOUT_MSECS - Default timeout to wait for a reply from
+ *   the NE PCI device.
+ */
+#define NE_DEFAULT_TIMEOUT_MSECS   (12) /* 120 sec */
+
+static const struct pci_device_id ne_pci_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, PCI_DEVICE_ID_NE) },
+   { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, ne_pci_ids);
+
+/**
+ * ne_setup_msix() - Setup MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to setup the MSI-X for.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_setup_msix(struct pci_dev *pdev)
+{
+   int nr_vecs = 0;
+   int rc = -EINVAL;
+
+   nr_vecs = pci_msix_vec_count(pdev);
+   if (nr_vecs < 0) {
+   rc = nr_vecs;
+
+   dev_err(>dev, "Error in getting vec count [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   rc = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX);
+   if (rc < 0) {
+   dev_err(>dev, "Error in alloc MSI-X vecs [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_teardown_msix() - Teardown MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to teardown the MSI-X for.
+ *
+ * Context: Process context.
+ */
+static void ne_teardown_msix(struct pci_dev *pdev)
+{
+   pci_free_irq_vectors(pdev);
+}
+
+/**
+ * ne_pci_dev_enable() - Select the PCI device version and enable it.
+ * @pdev:  PCI device to select version for and then enable.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_pci_dev_enable(struct pci_dev *pdev)
+{
+   u8 dev_enable_reply = 0;
+   u16 dev_version_reply = 0;
+   struct ne_pci_dev *ne_pci_dev = pci_get_drvdata(pdev);
+
+   iowrite16(NE_VERSION_MAX, ne_pci_dev->iomem_base + NE_VERSION);
+
+   dev_version_reply = ioread16(ne_pci_dev->iomem_base + NE_VERSION);
+   if (dev_version_reply != NE_VERSION_MAX) {
+   dev_err(>dev, "Error in pci dev version cmd\n");
+
+   return -EIO;
+   }
+
+   iowrite8(NE_ENABLE_ON, ne_pci_dev->iomem_base + NE_ENABLE);
+
+   dev_enable_reply = ioread8(ne_pci_dev->iomem_base + NE_ENABLE);
+   if (dev_enable_reply != NE_ENABLE_ON) {
+   dev_err(>dev, "Error in pci dev enable cmd\n");
+
+

[PATCH] MAINTAINERS: TPM DEVICE DRIVER: Update GIT

2020-09-18 Thread Jarkko Sakkinen
Update Git URL to

git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git

This is done for availability reasons, i.e. better infrastructure.

Cc: Mauro Carvalho Chehab 
Cc: "David S. Miller" 
Cc: Rob Herring 
Signed-off-by: Jarkko Sakkinen 
---
I'm happy to include this to my next PR, if that is fine for you.
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0d0862b19ce5..7b083b8f0c3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17593,7 +17593,7 @@ L:  linux-integr...@vger.kernel.org
 S: Maintained
 W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
 Q: https://patchwork.kernel.org/project/linux-integrity/list/
-T: git git://git.infradead.org/users/jjs/linux-tpmdd.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
 F: drivers/char/tpm/
 
 TRACING
-- 
2.25.1



Re: [PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device driver

2020-09-15 Thread Harald Freudenberger
And here is now my part for the remove set_fs() branch:
The difference to the 1st version is only as Christoph suggested
to break the long lines of the function declaration into smaller
ones.



>From 38b328bfb1b88787eb0e4cc68875c681de5e32a6 Mon Sep 17 00:00:00 2001
From: Harald Freudenberger 
Date: Thu, 10 Sep 2020 11:32:43 +0200
Subject: [PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device
 driver

This patch reworks the zcrypt device driver so that the set_fs()
invocation is not needed any more. Instead there is a new flag bool
userspace passed through all the functions which tells if the pointer
arguments are userspace or kernelspace. Together with the two new
inline functions z_copy_from_user() and z_copy_to_user() which either
invoke copy_from_user (userspace is true) or memcpy (userspace is
false) the zcrypt dd and the AP bus now has no requirement for
the set_fs() functionality any more.

Signed-off-by: Harald Freudenberger 
Reviewed-by: Ingo Franzki 
Reviewed-by: Christoph Hellwig 
---
 drivers/s390/crypto/zcrypt_api.c  | 30 +--
 drivers/s390/crypto/zcrypt_api.h  | 26 -
 drivers/s390/crypto/zcrypt_ccamisc.c  | 32 +++
 drivers/s390/crypto/zcrypt_ep11misc.c | 28 ++
 drivers/s390/crypto/zcrypt_msgtype6.c | 78 +--
 drivers/s390/crypto/zcrypt_msgtype6.h |  4 +-
 6 files changed, 92 insertions(+), 106 deletions(-)

diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 4dbbfd88262c..a711728c3857 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -797,7 +797,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
 return rc;
 }
 
-static long _zcrypt_send_cprb(struct ap_perms *perms,
+static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
           struct ica_xcRB *xcRB)
 {
 struct zcrypt_card *zc, *pref_zc;
@@ -813,7 +813,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 
 xcRB->status = 0;
 ap_init_message(_msg);
-    rc = get_cprb_fc(xcRB, _msg, _code, );
+    rc = get_cprb_fc(userspace, xcRB, _msg, _code, );
 if (rc)
     goto out;
 
@@ -878,7 +878,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 if (*domain == AUTOSEL_DOM)
     *domain = AP_QID_QUEUE(qid);
 
-    rc = pref_zq->ops->send_cprb(pref_zq, xcRB, _msg);
+    rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcRB, _msg);
 
 spin_lock(_list_lock);
 zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);
@@ -893,7 +893,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 
 long zcrypt_send_cprb(struct ica_xcRB *xcRB)
 {
-    return _zcrypt_send_cprb(_perms, xcRB);
+    return _zcrypt_send_cprb(false, _perms, xcRB);
 }
 EXPORT_SYMBOL(zcrypt_send_cprb);
 
@@ -924,7 +924,7 @@ static bool is_desired_ep11_queue(unsigned int dev_qid,
 return false;
 }
 
-static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
+static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
                struct ep11_urb *xcrb)
 {
 struct zcrypt_card *zc, *pref_zc;
@@ -956,7 +956,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
     }
 
     uptr = (struct ep11_target_dev __force __user *) xcrb->targets;
-        if (copy_from_user(targets, uptr,
+        if (z_copy_from_user(userspace, targets, uptr,
                target_num * sizeof(*targets))) {
         func_code = 0;
         rc = -EFAULT;
@@ -964,7 +964,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
     }
 }
 
-    rc = get_ep11cprb_fc(xcrb, _msg, _code);
+    rc = get_ep11cprb_fc(userspace, xcrb, _msg, _code);
 if (rc)
     goto out_free;
 
@@ -1015,7 +1015,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
 }
 
 qid = pref_zq->queue->qid;
-    rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, _msg);
+    rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb, _msg);
 
 spin_lock(_list_lock);
 zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);
@@ -1032,7 +1032,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
 
 long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
 {
-    return _zcrypt_send_ep11_cprb(_perms, xcrb);
+    return _zcrypt_send_ep11_cprb(false, _perms, xcrb);
 }
 EXPORT_SYMBOL(zcrypt_send_ep11_cprb);
 
@@ -1353,12 +1353,12 @@ static int zsecsendcprb_ioctl(struct ap_perms *perms, 
unsigned long arg)
 if (copy_from_user(, uxcRB, sizeof(xcRB)))
     return -EFAULT;
 do {
-        rc = _zcrypt_send_cprb(perms, );
+        rc = _zcrypt_send_cprb(true, perms, );
 } while (rc == -EAGAIN);
 /* on failure: retry once again after a requested rescan */
 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
     do {
-            rc = _zcrypt_send_cprb(perms, );
+            rc = _zcrypt_send_cprb(true, perms, );
     } while (r

Re: [PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device driver

2020-09-15 Thread Christoph Hellwig
On Mon, Sep 14, 2020 at 09:36:07AM +0200, Harald Freudenberger wrote:
> Christoph, maybe you have a greater idea on how to solve this. So don't 
> hesitate and tell me.
> Otherwise how to we provide this fix then ? My recommendation would be to go 
> the 'usual' way:
> Commit this s390 internal and then let this go out with the next kernel merge 
> window when
> next time Linus is pulling patches from the s390 subsystem for the 5.10 
> kernel development cycle.

What I did for the networking code is to add a new structure that
contains a union of the kernel and userspace pointer and a flag for
which one to use.  That is pretty much the same as what you did, just
a little more structured and type safe.  The other alternative would
be to use the iov_iter infrastructure, but that has some overhead.


Re: [PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device driver

2020-09-14 Thread Heiko Carstens
On Mon, Sep 14, 2020 at 09:36:07AM +0200, Harald Freudenberger wrote:
> Otherwise how to we provide this fix then ? My recommendation would
> be to go the 'usual' way: Commit this s390 internal and then let
> this go out with the next kernel merge window when next time Linus
> is pulling patches from the s390 subsystem for the 5.10 kernel
> development cycle.

I will create a "set_fs" topic branch on kernel.org based on
vfs.git/base.set_fs and add your patch there and also the rest of
s390 set_fs related patches on top of that as soon as things are
ready.


Re: [PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device driver

2020-09-14 Thread Harald Freudenberger
On 11.09.20 08:21, Christoph Hellwig wrote:
> On Thu, Sep 10, 2020 at 12:28:38PM +0200, Harald Freudenberger wrote:
>> +static inline unsigned long z_copy_from_user(bool userspace,
>> + void *to, const void __user *from, 
>> unsigned long n)
> Can you avoid the pointless long lines in the function declaration?
Yes, will do.
>
>> +{
>> +if (likely(userspace))
>> +return copy_from_user(to, from, n);
>> +memcpy(to, (void __force *) from, n);
>> +return 0;
>> +}
>> +
>> +static inline unsigned long z_copy_to_user(bool userspace,
>> +   void __user *to, const void *from, 
>> unsigned long n)
>> +{
>> +if (likely(userspace))
>> +return copy_to_user(to, from, n);
>> +memcpy((void __force *) to, from, n);
>> +return 0;
> Otherwise this doesn't look great, but also not horrible and gets rid
> of the set_fs while reducing the lines of code, so:
>
> Reviewed-by: Christoph Hellwig 
Christoph, maybe you have a greater idea on how to solve this. So don't 
hesitate and tell me.
Otherwise how to we provide this fix then ? My recommendation would be to go 
the 'usual' way:
Commit this s390 internal and then let this go out with the next kernel merge 
window when
next time Linus is pulling patches from the s390 subsystem for the 5.10 kernel 
development cycle.



Re: [PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device driver

2020-09-11 Thread Christoph Hellwig
On Thu, Sep 10, 2020 at 12:28:38PM +0200, Harald Freudenberger wrote:
> +static inline unsigned long z_copy_from_user(bool userspace,
> +  void *to, const void __user *from, 
> unsigned long n)

Can you avoid the pointless long lines in the function declaration?

> +{
> + if (likely(userspace))
> + return copy_from_user(to, from, n);
> + memcpy(to, (void __force *) from, n);
> + return 0;
> +}
> +
> +static inline unsigned long z_copy_to_user(bool userspace,
> +void __user *to, const void *from, 
> unsigned long n)
> +{
> + if (likely(userspace))
> + return copy_to_user(to, from, n);
> + memcpy((void __force *) to, from, n);
> + return 0;

Otherwise this doesn't look great, but also not horrible and gets rid
of the set_fs while reducing the lines of code, so:

Reviewed-by: Christoph Hellwig 


[PATCH] s390/zcrypt: remove set_fs() invocation in zcrypt device driver

2020-09-10 Thread Harald Freudenberger
This patch reworks the zcrypt device driver so that the set_fs()
invocation is not needed any more. Instead there is a new flag bool
userspace passed through all the functions which tells if the pointer
arguments are userspace or kernelspace. Together with the two new
inline functions z_copy_from_user() and z_copy_to_user() which either
invoke copy_from_user (userspace is true) or memcpy (userspace is
false) the zcrypt dd and the AP bus now has no requirement for
the set_fs() functionality any more.

Signed-off-by: Harald Freudenberger 
---
 drivers/s390/crypto/zcrypt_api.c  | 30 +--
 drivers/s390/crypto/zcrypt_api.h  | 22 +++-
 drivers/s390/crypto/zcrypt_ccamisc.c  | 32 +++
 drivers/s390/crypto/zcrypt_ep11misc.c | 28 ++
 drivers/s390/crypto/zcrypt_msgtype6.c | 78 +--
 drivers/s390/crypto/zcrypt_msgtype6.h |  4 +-
 6 files changed, 88 insertions(+), 106 deletions(-)

diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 4dbbfd88262c..a711728c3857 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -797,7 +797,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
return rc;
 }
 
-static long _zcrypt_send_cprb(struct ap_perms *perms,
+static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
  struct ica_xcRB *xcRB)
 {
struct zcrypt_card *zc, *pref_zc;
@@ -813,7 +813,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 
xcRB->status = 0;
ap_init_message(_msg);
-   rc = get_cprb_fc(xcRB, _msg, _code, );
+   rc = get_cprb_fc(userspace, xcRB, _msg, _code, );
if (rc)
goto out;
 
@@ -878,7 +878,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
if (*domain == AUTOSEL_DOM)
*domain = AP_QID_QUEUE(qid);
 
-   rc = pref_zq->ops->send_cprb(pref_zq, xcRB, _msg);
+   rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcRB, _msg);
 
spin_lock(_list_lock);
zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);
@@ -893,7 +893,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 
 long zcrypt_send_cprb(struct ica_xcRB *xcRB)
 {
-   return _zcrypt_send_cprb(_perms, xcRB);
+   return _zcrypt_send_cprb(false, _perms, xcRB);
 }
 EXPORT_SYMBOL(zcrypt_send_cprb);
 
@@ -924,7 +924,7 @@ static bool is_desired_ep11_queue(unsigned int dev_qid,
return false;
 }
 
-static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
+static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
   struct ep11_urb *xcrb)
 {
struct zcrypt_card *zc, *pref_zc;
@@ -956,7 +956,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
}
 
uptr = (struct ep11_target_dev __force __user *) xcrb->targets;
-   if (copy_from_user(targets, uptr,
+   if (z_copy_from_user(userspace, targets, uptr,
   target_num * sizeof(*targets))) {
func_code = 0;
rc = -EFAULT;
@@ -964,7 +964,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
}
}
 
-   rc = get_ep11cprb_fc(xcrb, _msg, _code);
+   rc = get_ep11cprb_fc(userspace, xcrb, _msg, _code);
if (rc)
goto out_free;
 
@@ -1015,7 +1015,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
}
 
qid = pref_zq->queue->qid;
-   rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, _msg);
+   rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb, _msg);
 
spin_lock(_list_lock);
zcrypt_drop_queue(pref_zc, pref_zq, mod, weight);
@@ -1032,7 +1032,7 @@ static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
 
 long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
 {
-   return _zcrypt_send_ep11_cprb(_perms, xcrb);
+   return _zcrypt_send_ep11_cprb(false, _perms, xcrb);
 }
 EXPORT_SYMBOL(zcrypt_send_ep11_cprb);
 
@@ -1353,12 +1353,12 @@ static int zsecsendcprb_ioctl(struct ap_perms *perms, 
unsigned long arg)
if (copy_from_user(, uxcRB, sizeof(xcRB)))
return -EFAULT;
do {
-   rc = _zcrypt_send_cprb(perms, );
+   rc = _zcrypt_send_cprb(true, perms, );
} while (rc == -EAGAIN);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
-   rc = _zcrypt_send_cprb(perms, );
+   rc = _zcrypt_send_cprb(true, perms, );
} while (rc == -EAGAIN);
if (rc)
ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDCPRB rc=%d status=0x%x\n",
@@ -1377,12 +1377,12 @@ static int zsendep11cprb_ioctl(struct ap_perms *perms, 
unsigned long arg)
if (copy_from_user(

[PATCH v8 04/18] nitro_enclaves: Init PCI device driver

2020-09-04 Thread Andra Paraschiv
The Nitro Enclaves PCI device is used by the kernel driver as a means of
communication with the hypervisor on the host where the primary VM and
the enclaves run. It handles requests with regard to enclave lifetime.

Setup the PCI device driver and add support for MSI-X interrupts.

Signed-off-by: Alexandru-Catalin Vasile 
Signed-off-by: Alexandru Ciobotaru 
Signed-off-by: Andra Paraschiv 
Reviewed-by: Alexander Graf 
---
Changelog

v7 -> v8

* Add NE PCI driver shutdown logic.

v6 -> v7

* No changes.

v5 -> v6

* Update documentation to kernel-doc format.

v4 -> v5

* Remove sanity checks for situations that shouldn't happen, only if
  buggy system or broken logic at all.

v3 -> v4

* Use dev_err instead of custom NE log pattern.
* Update NE PCI driver name to "nitro_enclaves".

v2 -> v3

* Remove the GPL additional wording as SPDX-License-Identifier is
  already in place.
* Remove the WARN_ON calls.
* Remove linux/bug include that is not needed.
* Update static calls sanity checks.
* Remove "ratelimited" from the logs that are not in the ioctl call
  paths.
* Update kzfree() calls to kfree().

v1 -> v2

* Add log pattern for NE.
* Update PCI device setup functions to receive PCI device data structure and
  then get private data from it inside the functions logic.
* Remove the BUG_ON calls.
* Add teardown function for MSI-X setup.
* Update goto labels to match their purpose.
* Implement TODO for NE PCI device disable state check.
* Update function name for NE PCI device probe / remove.
---
 drivers/virt/nitro_enclaves/ne_pci_dev.c | 298 +++
 1 file changed, 298 insertions(+)
 create mode 100644 drivers/virt/nitro_enclaves/ne_pci_dev.c

diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.c 
b/drivers/virt/nitro_enclaves/ne_pci_dev.c
new file mode 100644
index ..daf8b36383f1
--- /dev/null
+++ b/drivers/virt/nitro_enclaves/ne_pci_dev.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ */
+
+/**
+ * DOC: Nitro Enclaves (NE) PCI device driver.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ne_misc_dev.h"
+#include "ne_pci_dev.h"
+
+/**
+ * NE_DEFAULT_TIMEOUT_MSECS - Default timeout to wait for a reply from
+ *   the NE PCI device.
+ */
+#define NE_DEFAULT_TIMEOUT_MSECS   (12) /* 120 sec */
+
+static const struct pci_device_id ne_pci_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, PCI_DEVICE_ID_NE) },
+   { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, ne_pci_ids);
+
+/**
+ * ne_setup_msix() - Setup MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to setup the MSI-X for.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_setup_msix(struct pci_dev *pdev)
+{
+   int nr_vecs = 0;
+   int rc = -EINVAL;
+
+   nr_vecs = pci_msix_vec_count(pdev);
+   if (nr_vecs < 0) {
+   rc = nr_vecs;
+
+   dev_err(>dev, "Error in getting vec count [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   rc = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX);
+   if (rc < 0) {
+   dev_err(>dev, "Error in alloc MSI-X vecs [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_teardown_msix() - Teardown MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to teardown the MSI-X for.
+ *
+ * Context: Process context.
+ */
+static void ne_teardown_msix(struct pci_dev *pdev)
+{
+   pci_free_irq_vectors(pdev);
+}
+
+/**
+ * ne_pci_dev_enable() - Select the PCI device version and enable it.
+ * @pdev:  PCI device to select version for and then enable.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_pci_dev_enable(struct pci_dev *pdev)
+{
+   u8 dev_enable_reply = 0;
+   u16 dev_version_reply = 0;
+   struct ne_pci_dev *ne_pci_dev = pci_get_drvdata(pdev);
+
+   iowrite16(NE_VERSION_MAX, ne_pci_dev->iomem_base + NE_VERSION);
+
+   dev_version_reply = ioread16(ne_pci_dev->iomem_base + NE_VERSION);
+   if (dev_version_reply != NE_VERSION_MAX) {
+   dev_err(>dev, "Error in pci dev version cmd\n");
+
+   return -EIO;
+   }
+
+   iowrite8(NE_ENABLE_ON, ne_pci_dev->iomem_base + NE_ENABLE);
+
+   dev_enable_reply = ioread8(ne_pci_dev->iomem_base + NE_ENABLE);
+   if (dev_enable_reply != NE_ENABLE_ON) {
+   dev_err(>dev, "Error in pci dev enable cmd\n");
+
+   return -EIO;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_pci_dev_disable() - Disable the PCI device.
+ * @pdev:  PCI device to disable.
+ *
+ * Context: Process

[PATCH v3 00/19] dlb2: introduce DLB 2.0 device driver

2020-09-01 Thread Gage Eads
This commit introduces a new misc device driver for the Intel(r) Dynamic
Load Balancer 2.0 (Intel(r) DLB 2.0). The Intel DLB 2.0 is a PCIe device that
provides load-balanced, prioritized scheduling of core-to-core communication.

The Intel DLB 2.0 consists of queues and arbiters that connect producer cores
and consumer cores. The device implements load-balanced queueing features
including:
- Lock-free multi-producer/multi-consumer operation.
- Multiple priority levels for varying traffic types.
- 'Direct' traffic (i.e. multi-producer/single-consumer)
- Simple unordered load-balanced distribution.
- Atomic lock free load balancing across multiple consumers.
- Queue element reordering feature allowing ordered load-balanced
  distribution.

Intel DLB 2.0 can be used in an event-driven programming model, such as DPDK's
Event Device Library[2]. Such frameworks are commonly used in packet processing
pipelines that benefit from the framework's multi-core scalability, dynamic
load-balancing, and variety of packet distribution and synchronization schemes.

These distribution schemes include "parallel" (packets are load-balanced
across multiple cores and processed in parallel), "ordered" (similar to
"parallel" but packets are reordered into ingress order by the device), and
"atomic" (packet flows are scheduled to a single core at a time such that
locks are not required to access per-flow data, and dynamically migrated to
ensure load-balance).

The fundamental unit of communication through the device is a queue entry
(QE), which consists of 8B of data and 8B of metadata (destination queue,
priority, etc.). The data field can be any type that fits within 8B.

A core's interface to the device, a "port," consists of a memory-mappable
region through which the core enqueues a queue entry, and an in-memory
queue (the "consumer queue") to which the device schedules QEs. Each QE
is enqueued to a device-managed queue, and from there scheduled to a port.
Software specifies the "linking" of queues and ports; i.e. which ports the
device is allowed to schedule to for a given queue. The device uses a
credit scheme to prevent overflow of the on-device queue storage.

Applications can interface directly with the device by mapping the port's
memory and MMIO regions into the application's address space for enqueue
and dequeue operations, but call into the kernel driver for configuration
operations. An application can also be polling- or interrupt-driven;
Intel DLB 2.0 supports both modes of operation.

Device resources -- i.e. ports, queues, and credits -- are contained within
a scheduling domain. Scheduling domains are isolated from one another; a
port can only enqueue to and dequeue from queues within its scheduling
domain. A scheduling domain's resources are configured through a scheduling
domain file, which is acquired through an ioctl.

Intel DLB 2.0 supports SR-IOV and Scalable IOV, and allows for a flexible
division of its resources among the PF and its virtual devices. The virtual
devices are incapable of configuring the device directly; they use a hardware
mailbox to proxy configuration requests to the PF driver. This driver supports
both PF and virtual devices, as there is significant code re-use between the
two, with device-specific behavior handled through a callback interface.
Virtualization support will be added in a later patch set.

The dlb driver uses ioctls as its primary interface (it makes use of sysfs
as well, to a lesser extent). The dlb device file supports a different
ioctl interface than the scheduling domain file; the dlb device file
is used for device-wide operations (including scheduling domain creation),
and the scheduling domain file supports operations on the scheduling
domain's resources (primarily resource configuration).

[1] 
https://builders.intel.com/docs/networkbuilders/SKU-343247-001US-queue-management-and-load-balancing-on-intel-architecture.pdf
[2] https://doc.dpdk.org/guides/prog_guide/eventdev.html

v3:
- Remove DLB2_PCI_REG_READ/WRITE macros

v2:
- Change driver license to GPLv2 only
- Expand Kconfig help text and remove unnecessary (R)s
- Remove unnecessary prints
- Add a new entry in ioctl-number.rst
- Convert the ioctl handler into a switch statement
- Correct some instances of IOWR that should have been IOR
- Align macro blocks
- Don't break ioctl ABI when introducing new commands
- Remove indirect pointers from ioctl data structures
- Remove the get-sched-domain-fd ioctl command

Gage Eads (19):
  dlb2: add skeleton for DLB 2.0 driver
  dlb2: initialize PF device
  dlb2: add resource and device initialization
  dlb2: add device ioctl layer and first three ioctls
  dlb2: add sched domain config and reset support
  dlb2: add runtime power-management support
  dlb2: add queue create and queue-depth-get ioctls
  dlb2: add ioctl to configure ports, query poll mode
  dlb2: add port mmap support
  dlb2: add start domai

[PATCH 5.8 237/255] USB: Fix device driver race

2020-09-01 Thread Greg Kroah-Hartman
From: Bastien Nocera 

commit d5643d2249b279077427b2c2b2ffae9b70c95b0b upstream.

When a new device with a specialised device driver is plugged in, the
new driver will be modprobe()'d but the driver core will attach the
"generic" driver to the device.

After that, nothing will trigger a reprobe when the modprobe()'d device
driver has finished initialising, as the device has the "generic"
driver attached to it.

Trigger a reprobe ourselves when new specialised drivers get registered.

Fixes: 88b7381a939d ("USB: Select better matching USB drivers when available")
Signed-off-by: Bastien Nocera 
Cc: stable 
Acked-by: Alan Stern 
Link: https://lore.kernel.org/r/20200818110445.509668-3-had...@hadess.net
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/usb/core/driver.c |   40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -905,6 +905,35 @@ static int usb_uevent(struct device *dev
return 0;
 }
 
+static bool is_dev_usb_generic_driver(struct device *dev)
+{
+   struct usb_device_driver *udd = dev->driver ?
+   to_usb_device_driver(dev->driver) : NULL;
+
+   return udd == _generic_driver;
+}
+
+static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
+{
+   struct usb_device_driver *new_udriver = data;
+   struct usb_device *udev;
+   int ret;
+
+   if (!is_dev_usb_generic_driver(dev))
+   return 0;
+
+   udev = to_usb_device(dev);
+   if (usb_device_match_id(udev, new_udriver->id_table) == NULL &&
+   (!new_udriver->match || new_udriver->match(udev) != 0))
+   return 0;
+
+   ret = device_reprobe(dev);
+   if (ret && ret != -EPROBE_DEFER)
+   dev_err(dev, "Failed to reprobe device (error %d)\n", ret);
+
+   return 0;
+}
+
 /**
  * usb_register_device_driver - register a USB device (not interface) driver
  * @new_udriver: USB operations for the device driver
@@ -934,13 +963,20 @@ int usb_register_device_driver(struct us
 
retval = driver_register(_udriver->drvwrap.driver);
 
-   if (!retval)
+   if (!retval) {
pr_info("%s: registered new device driver %s\n",
usbcore_name, new_udriver->name);
-   else
+   /*
+* Check whether any device could be better served with
+* this new driver
+*/
+   bus_for_each_dev(_bus_type, NULL, new_udriver,
+__usb_bus_reprobe_drivers);
+   } else {
printk(KERN_ERR "%s: error %d registering device "
"   driver %s\n",
usbcore_name, retval, new_udriver->name);
+   }
 
return retval;
 }




[PATCH v7 04/18] nitro_enclaves: Init PCI device driver

2020-08-17 Thread Andra Paraschiv
The Nitro Enclaves PCI device is used by the kernel driver as a means of
communication with the hypervisor on the host where the primary VM and
the enclaves run. It handles requests with regard to enclave lifetime.

Setup the PCI device driver and add support for MSI-X interrupts.

Signed-off-by: Alexandru-Catalin Vasile 
Signed-off-by: Alexandru Ciobotaru 
Signed-off-by: Andra Paraschiv 
Reviewed-by: Alexander Graf 
---
Changelog

v6 -> v7

* No changes.

v5 -> v6

* Update documentation to kernel-doc format.

v4 -> v5

* Remove sanity checks for situations that shouldn't happen, only if
  buggy system or broken logic at all.

v3 -> v4

* Use dev_err instead of custom NE log pattern.
* Update NE PCI driver name to "nitro_enclaves".

v2 -> v3

* Remove the GPL additional wording as SPDX-License-Identifier is
  already in place.
* Remove the WARN_ON calls.
* Remove linux/bug include that is not needed.
* Update static calls sanity checks.
* Remove "ratelimited" from the logs that are not in the ioctl call
  paths.
* Update kzfree() calls to kfree().

v1 -> v2

* Add log pattern for NE.
* Update PCI device setup functions to receive PCI device data structure and
  then get private data from it inside the functions logic.
* Remove the BUG_ON calls.
* Add teardown function for MSI-X setup.
* Update goto labels to match their purpose.
* Implement TODO for NE PCI device disable state check.
* Update function name for NE PCI device probe / remove.
---
 drivers/virt/nitro_enclaves/ne_pci_dev.c | 269 +++
 1 file changed, 269 insertions(+)
 create mode 100644 drivers/virt/nitro_enclaves/ne_pci_dev.c

diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.c 
b/drivers/virt/nitro_enclaves/ne_pci_dev.c
new file mode 100644
index ..31650dcd592e
--- /dev/null
+++ b/drivers/virt/nitro_enclaves/ne_pci_dev.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ */
+
+/**
+ * DOC: Nitro Enclaves (NE) PCI device driver.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ne_misc_dev.h"
+#include "ne_pci_dev.h"
+
+/**
+ * NE_DEFAULT_TIMEOUT_MSECS - Default timeout to wait for a reply from
+ *   the NE PCI device.
+ */
+#define NE_DEFAULT_TIMEOUT_MSECS   (12) /* 120 sec */
+
+static const struct pci_device_id ne_pci_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, PCI_DEVICE_ID_NE) },
+   { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, ne_pci_ids);
+
+/**
+ * ne_setup_msix() - Setup MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to setup the MSI-X for.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_setup_msix(struct pci_dev *pdev)
+{
+   int nr_vecs = 0;
+   int rc = -EINVAL;
+
+   nr_vecs = pci_msix_vec_count(pdev);
+   if (nr_vecs < 0) {
+   rc = nr_vecs;
+
+   dev_err(>dev, "Error in getting vec count [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   rc = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX);
+   if (rc < 0) {
+   dev_err(>dev, "Error in alloc MSI-X vecs [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_teardown_msix() - Teardown MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to teardown the MSI-X for.
+ *
+ * Context: Process context.
+ */
+static void ne_teardown_msix(struct pci_dev *pdev)
+{
+   pci_free_irq_vectors(pdev);
+}
+
+/**
+ * ne_pci_dev_enable() - Select the PCI device version and enable it.
+ * @pdev:  PCI device to select version for and then enable.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_pci_dev_enable(struct pci_dev *pdev)
+{
+   u8 dev_enable_reply = 0;
+   u16 dev_version_reply = 0;
+   struct ne_pci_dev *ne_pci_dev = pci_get_drvdata(pdev);
+
+   iowrite16(NE_VERSION_MAX, ne_pci_dev->iomem_base + NE_VERSION);
+
+   dev_version_reply = ioread16(ne_pci_dev->iomem_base + NE_VERSION);
+   if (dev_version_reply != NE_VERSION_MAX) {
+   dev_err(>dev, "Error in pci dev version cmd\n");
+
+   return -EIO;
+   }
+
+   iowrite8(NE_ENABLE_ON, ne_pci_dev->iomem_base + NE_ENABLE);
+
+   dev_enable_reply = ioread8(ne_pci_dev->iomem_base + NE_ENABLE);
+   if (dev_enable_reply != NE_ENABLE_ON) {
+   dev_err(>dev, "Error in pci dev enable cmd\n");
+
+   return -EIO;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_pci_dev_disable() - Disable the PCI device.
+ * @pdev:  PCI device to disable.
+ *
+ * Context: Process context.
+ */
+static void ne_pci_dev

[PATCH v2 00/19] dlb2: introduce DLB 2.0 device driver

2020-08-11 Thread Gage Eads
This commit introduces a new misc device driver for the Intel(r) Dynamic
Load Balancer 2.0 (Intel(r) DLB 2.0). The Intel DLB 2.0 is a PCIe device that
provides load-balanced, prioritized scheduling of core-to-core communication.

The Intel DLB 2.0 consists of queues and arbiters that connect producer cores
and consumer cores. The device implements load-balanced queueing features
including:
- Lock-free multi-producer/multi-consumer operation.
- Multiple priority levels for varying traffic types.
- 'Direct' traffic (i.e. multi-producer/single-consumer)
- Simple unordered load-balanced distribution.
- Atomic lock free load balancing across multiple consumers.
- Queue element reordering feature allowing ordered load-balanced
  distribution.

Intel DLB 2.0 can be used in an event-driven programming model, such as DPDK's
Event Device Library[2]. Such frameworks are commonly used in packet processing
pipelines that benefit from the framework's multi-core scalability, dynamic
load-balancing, and variety of packet distribution and synchronization schemes.

These distribution schemes include "parallel" (packets are load-balanced
across multiple cores and processed in parallel), "ordered" (similar to
"parallel" but packets are reordered into ingress order by the device), and
"atomic" (packet flows are scheduled to a single core at a time such that
locks are not required to access per-flow data, and dynamically migrated to
ensure load-balance).

The fundamental unit of communication through the device is a queue entry
(QE), which consists of 8B of data and 8B of metadata (destination queue,
priority, etc.). The data field can be any type that fits within 8B.

A core's interface to the device, a "port," consists of a memory-mappable
region through which the core enqueues a queue entry, and an in-memory
queue (the "consumer queue") to which the device schedules QEs. Each QE
is enqueued to a device-managed queue, and from there scheduled to a port.
Software specifies the "linking" of queues and ports; i.e. which ports the
device is allowed to schedule to for a given queue. The device uses a
credit scheme to prevent overflow of the on-device queue storage.

Applications can interface directly with the device by mapping the port's
memory and MMIO regions into the application's address space for enqueue
and dequeue operations, but call into the kernel driver for configuration
operations. An application can also be polling- or interrupt-driven;
Intel DLB 2.0 supports both modes of operation.

Device resources -- i.e. ports, queues, and credits -- are contained within
a scheduling domain. Scheduling domains are isolated from one another; a
port can only enqueue to and dequeue from queues within its scheduling
domain. A scheduling domain's resources are configured through a scheduling
domain file, which is acquired through an ioctl.

Intel DLB 2.0 supports SR-IOV and Scalable IOV, and allows for a flexible
division of its resources among the PF and its virtual devices. The virtual
devices are incapable of configuring the device directly; they use a hardware
mailbox to proxy configuration requests to the PF driver. This driver supports
both PF and virtual devices, as there is significant code re-use between the
two, with device-specific behavior handled through a callback interface.
Virtualization support will be added in a later patch set.

The dlb driver uses ioctls as its primary interface (it makes use of sysfs
as well, to a lesser extent). The dlb device file supports a different
ioctl interface than the scheduling domain file; the dlb device file
is used for device-wide operations (including scheduling domain creation),
and the scheduling domain file supports operations on the scheduling
domain's resources (primarily resource configuration).

[1] 
https://builders.intel.com/docs/networkbuilders/SKU-343247-001US-queue-management-and-load-balancing-on-intel-architecture.pdf
[2] https://doc.dpdk.org/guides/prog_guide/eventdev.html

v2:
- Change driver license to GPLv2 only
- Expand Kconfig help text and remove unnecessary (R)s
- Remove unnecessary prints
- Add a new entry in ioctl-number.rst
- Convert the ioctl handler into a switch statement
- Correct some instances of IOWR that should have been IOR
- Align macro blocks
- Don't break ioctl ABI when introducing new commands
- Remove indirect pointers from ioctl data structures
- Remove the get-sched-domain-fd ioctl command

Gage Eads (19):
  dlb2: add skeleton for DLB 2.0 driver
  dlb2: initialize PF device
  dlb2: add resource and device initialization
  dlb2: add device ioctl layer and first three ioctls
  dlb2: add sched domain config and reset support
  dlb2: add runtime power-management support
  dlb2: add queue create and queue-depth-get ioctls
  dlb2: add ioctl to configure ports, query poll mode
  dlb2: add port mmap support
  dlb2: add start domain ioctl
  dlb2: add queue map and unmap ioctls
 

[PATCH v6 04/18] nitro_enclaves: Init PCI device driver

2020-08-05 Thread Andra Paraschiv
The Nitro Enclaves PCI device is used by the kernel driver as a means of
communication with the hypervisor on the host where the primary VM and
the enclaves run. It handles requests with regard to enclave lifetime.

Setup the PCI device driver and add support for MSI-X interrupts.

Signed-off-by: Alexandru-Catalin Vasile 
Signed-off-by: Alexandru Ciobotaru 
Signed-off-by: Andra Paraschiv 
Reviewed-by: Alexander Graf 
---
Changelog

v5 -> v6

* Update documentation to kernel-doc format.

v4 -> v5

* Remove sanity checks for situations that shouldn't happen, only if
  buggy system or broken logic at all.

v3 -> v4

* Use dev_err instead of custom NE log pattern.
* Update NE PCI driver name to "nitro_enclaves".

v2 -> v3

* Remove the GPL additional wording as SPDX-License-Identifier is
  already in place.
* Remove the WARN_ON calls.
* Remove linux/bug include that is not needed.
* Update static calls sanity checks.
* Remove "ratelimited" from the logs that are not in the ioctl call
  paths.
* Update kzfree() calls to kfree().

v1 -> v2

* Add log pattern for NE.
* Update PCI device setup functions to receive PCI device data structure and
  then get private data from it inside the functions logic.
* Remove the BUG_ON calls.
* Add teardown function for MSI-X setup.
* Update goto labels to match their purpose.
* Implement TODO for NE PCI device disable state check.
* Update function name for NE PCI device probe / remove.
---
 drivers/virt/nitro_enclaves/ne_pci_dev.c | 269 +++
 1 file changed, 269 insertions(+)
 create mode 100644 drivers/virt/nitro_enclaves/ne_pci_dev.c

diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.c 
b/drivers/virt/nitro_enclaves/ne_pci_dev.c
new file mode 100644
index ..31650dcd592e
--- /dev/null
+++ b/drivers/virt/nitro_enclaves/ne_pci_dev.c
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ */
+
+/**
+ * DOC: Nitro Enclaves (NE) PCI device driver.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ne_misc_dev.h"
+#include "ne_pci_dev.h"
+
+/**
+ * NE_DEFAULT_TIMEOUT_MSECS - Default timeout to wait for a reply from
+ *   the NE PCI device.
+ */
+#define NE_DEFAULT_TIMEOUT_MSECS   (12) /* 120 sec */
+
+static const struct pci_device_id ne_pci_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, PCI_DEVICE_ID_NE) },
+   { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, ne_pci_ids);
+
+/**
+ * ne_setup_msix() - Setup MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to setup the MSI-X for.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_setup_msix(struct pci_dev *pdev)
+{
+   int nr_vecs = 0;
+   int rc = -EINVAL;
+
+   nr_vecs = pci_msix_vec_count(pdev);
+   if (nr_vecs < 0) {
+   rc = nr_vecs;
+
+   dev_err(>dev, "Error in getting vec count [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   rc = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX);
+   if (rc < 0) {
+   dev_err(>dev, "Error in alloc MSI-X vecs [rc=%d]\n", rc);
+
+   return rc;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_teardown_msix() - Teardown MSI-X vectors for the PCI device.
+ * @pdev:  PCI device to teardown the MSI-X for.
+ *
+ * Context: Process context.
+ */
+static void ne_teardown_msix(struct pci_dev *pdev)
+{
+   pci_free_irq_vectors(pdev);
+}
+
+/**
+ * ne_pci_dev_enable() - Select the PCI device version and enable it.
+ * @pdev:  PCI device to select version for and then enable.
+ *
+ * Context: Process context.
+ * Return:
+ * * 0 on success.
+ * * Negative return value on failure.
+ */
+static int ne_pci_dev_enable(struct pci_dev *pdev)
+{
+   u8 dev_enable_reply = 0;
+   u16 dev_version_reply = 0;
+   struct ne_pci_dev *ne_pci_dev = pci_get_drvdata(pdev);
+
+   iowrite16(NE_VERSION_MAX, ne_pci_dev->iomem_base + NE_VERSION);
+
+   dev_version_reply = ioread16(ne_pci_dev->iomem_base + NE_VERSION);
+   if (dev_version_reply != NE_VERSION_MAX) {
+   dev_err(>dev, "Error in pci dev version cmd\n");
+
+   return -EIO;
+   }
+
+   iowrite8(NE_ENABLE_ON, ne_pci_dev->iomem_base + NE_ENABLE);
+
+   dev_enable_reply = ioread8(ne_pci_dev->iomem_base + NE_ENABLE);
+   if (dev_enable_reply != NE_ENABLE_ON) {
+   dev_err(>dev, "Error in pci dev enable cmd\n");
+
+   return -EIO;
+   }
+
+   return 0;
+}
+
+/**
+ * ne_pci_dev_disable() - Disable the PCI device.
+ * @pdev:  PCI device to disable.
+ *
+ * Context: Process context.
+ */
+static void ne_pci_dev_disable(struct pci_dev *pdev)
+{
+   u

  1   2   3   4   5   6   7   8   9   10   >