* [PATCH net-next 1/5] virtio: Add support for SCTP checksum offloading
From: Vladislav Yasevich @ 2018-04-02 13:40 UTC (permalink / raw)
To: netdev
Cc: linux-sctp, virtualization, mst, jasowang, nhorman,
Vladislav Yasevich
In-Reply-To: <20180402134006.10111-1-vyasevic@redhat.com>
To support SCTP checksum offloading, we need to add a new feature
to virtio_net, so we can negotiate support between the hypervisor
and the guest.
The signalling to the guest that an alternate checksum needs to
be used is done via a new flag in the virtio_net_hdr. If the
flag is set, the host will know to perform an alternate checksum
calculation, which right now is only CRC32c.
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
drivers/net/virtio_net.c | 11 ++++++++---
include/linux/virtio_net.h | 6 ++++++
include/uapi/linux/virtio_net.h | 2 ++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7b187ec..b601294 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2724,9 +2724,14 @@ static int virtnet_probe(struct virtio_device *vdev)
/* Do we support "hardware" checksums? */
if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
/* This opens up the world of extra features. */
- dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+ netdev_features_t sctp = 0;
+
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_SCTP_CSUM))
+ sctp |= NETIF_F_SCTP_CRC;
+
+ dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_SG | sctp;
if (csum)
- dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG | sctp;
if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
dev->hw_features |= NETIF_F_TSO
@@ -2952,7 +2957,7 @@ static struct virtio_device_id id_table[] = {
};
#define VIRTNET_FEATURES \
- VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, \
+ VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_SCTP_CSUM, \
VIRTIO_NET_F_MAC, \
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \
VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index f144216..2e7a64a 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -39,6 +39,9 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
if (!skb_partial_csum_set(skb, start, off))
return -EINVAL;
+
+ if (hdr->flags & VIRTIO_NET_HDR_F_CSUM_NOT_INET)
+ skb->csum_not_inet = 1;
}
if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
@@ -96,6 +99,9 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
} /* else everything is zero */
+ if (skb->csum_not_inet)
+ hdr->flags &= VIRTIO_NET_HDR_F_CSUM_NOT_INET;
+
return 0;
}
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index 5de6ed3..3f279c8 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -36,6 +36,7 @@
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
#define VIRTIO_NET_F_MTU 3 /* Initial MTU advice */
+#define VIRTIO_NET_F_SCTP_CSUM 4 /* SCTP checksum offload support */
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
@@ -101,6 +102,7 @@ struct virtio_net_config {
struct virtio_net_hdr_v1 {
#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start, csum_offset */
#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */
+#define VIRTIO_NET_HDR_F_CSUM_NOT_INET 4 /* Checksum is not inet */
__u8 flags;
#define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */
#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */
--
2.9.5
^ permalink raw reply related
* [PATCH net-next 0/5] virtio-net: Add SCTP checksum offload support
From: Vladislav Yasevich @ 2018-04-02 13:40 UTC (permalink / raw)
To: netdev; +Cc: nhorman, mst, virtualization, linux-sctp
Now that we have SCTP offload capabilities in the kernel, we can add
them to virtio as well. First step is SCTP checksum.
We need a new freature in virtio to negotiate this support since
SCTP is excluded with the stardard checksum and requires a little
bit extra. This series proposes VIRTIO_NET_F_SCTP_CSUM feature bit.
As the "little bit extra", the kernel uses a new bit in the skb
(skb->csum_not_inet) to determine whether to use standard inet checksum
or the SCTP CRC32c checksum. This bit has to be communicated between
the host and the guest. This bit is carried in the vnet header.
Tap and macvtap support is added through an extra feature for the
TUNSETOFFLOAD ioctl. Additionally macvtap will no correctly
do sctp checksumming if the receive doesn't support SCTP offload.
This also turns on sctp offloading for macvlan devices.
As for the perf numbers, I am seeing about a 5% increase in vm-to-vm
and vm-to-hos throughput which is the same as manually disabling
sctp checksumming,since this is exactly what we are emulatting.
Sending outside the host, the increase about 2.5-3%.
As for GSO, the way sctp GSO is currently implemented buys us nothing
in added support to virtio. To add true GSO, would require a lot of
re-work inside of SCTP and would require extensions to the virtio
net header to carry extra sctp data.
Vladislav Yasevich (5):
virtio: Add support for SCTP checksum offloading
sctp: Handle sctp packets with CHECKSUM_PARTIAL
sctp: Build sctp offload support into the base kernel
tun: Add support for SCTP checksum offload
macvlan/macvtap: Add support for SCTP checksum offload.
drivers/net/macvlan.c | 5 +++--
drivers/net/tap.c | 8 +++++---
drivers/net/tun.c | 5 +++++
drivers/net/virtio_net.c | 10 +++++++---
include/linux/virtio_net.h | 6 ++++++
include/net/sctp/sctp.h | 5 -----
include/uapi/linux/if_tun.h | 1 +
include/uapi/linux/virtio_net.h | 2 ++
net/Kconfig | 1 +
net/sctp/Kconfig | 1 -
net/sctp/Makefile | 3 ++-
net/sctp/input.c | 11 ++++++++++-
net/sctp/offload.c | 4 +++-
net/sctp/protocol.c | 3 ---
14 files changed, 45 insertions(+), 20 deletions(-)
--
2.9.5
^ permalink raw reply
* RE: [PATCH v3 2/4] bus: fsl-mc: add restool userspace support
From: Ioana Ciornei @ 2018-04-02 13:24 UTC (permalink / raw)
To: Andrew Lunn, Arnd Bergmann
Cc: gregkh, Laurentiu Tudor, Linux Kernel Mailing List, Stuart Yoder,
Ruxandra Ioana Ciocoi Radulescu, Razvan Stefanescu, Roy Pledge,
Networking
In-Reply-To: <20180328162811.GB15827@lunn.ch>
>
> > I'm still not convinced either way (high-level or low-level
> > interface), but I think this needs to be discussed with the networking
> > maintainers. Given the examples on the github page you linked to, the
> > high-level user space commands based on these ioctls
> >
> > ls-addni # adds a network interface
> > ls-addmux # adds a dpdmux
> > ls-addsw # adds an l2switch
> > ls-listmac # lists MACs and their connections
> > ls-listni # lists network interfaces and their connections
> >
> > and I see that you also support the switchdev interface in
> > drivers/staging/fsl-dpaa2, which I think does some of the same things,
> > presumably by implementing the switchdev API using fsl_mc_command
> > low-level interfaces in the kernel.
>
> Hi Arnd
>
> I agree that switchdev and devlink should be the correct way to handle this. The
> low level plumbing of the hardware should all be hidden. There should not be
> any user space commands needed other than the usual network configuration
> tools and devlink.
>
Hi,
The commands listed above are for creating/destroying DPAA2 objects in Management Complex and not for runtime configuration where standard userspace tools are used.
Restool is responsible for creating objects in Management complex and this process can be seen as the equivalent of hotplugging a peripheral rather than configuring it, thus there is no standard userspace tool to handle that.
* The Management Complex is configured to create a specific set of DPAA2 objects dynamically through Restool (by sending create commands) or statically, at boot time, through a configuration file (Data Path Layout file)
* The objects are then probed and configured by the corresponding drivers
* The objects are controlled at runtime by the user via standard tools (e.g. ethtool for network interfaces).
I hope this gives a better understanding on the DPAA2 hardware and software architecture. The fsl-mc bus documentation gives more details on this: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git/tree/Documentation/networking/dpaa2/overview.rst?h=staging-next
Ioana
^ permalink raw reply
* Re: RFC on writel and writel_relaxed
From: Sinan Kaya @ 2018-04-02 13:01 UTC (permalink / raw)
To: Benjamin Herrenschmidt, David Miller
Cc: torvalds, alexander.duyck, will.deacon, arnd, jgg, David.Laight,
oohall, linuxppc-dev, linux-rdma, alexander.h.duyck, paulmck,
netdev, linus971
In-Reply-To: <1522374027.21446.64.camel@kernel.crashing.org>
On 3/29/2018 9:40 PM, Benjamin Herrenschmidt wrote:
> On Thu, 2018-03-29 at 09:56 -0400, Sinan Kaya wrote:
>> On 3/28/2018 11:55 AM, David Miller wrote:
>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>> Date: Thu, 29 Mar 2018 02:13:16 +1100
>>>
>>>> Let's fix all archs, it's way easier than fixing all drivers. Half of
>>>> the archs are unused or dead anyway.
>>>
>>> Agreed.
>>>
>>
>> I pinged most of the maintainers yesterday.
>> Which arches do we care about these days?
>> I have not been paying attention any other architecture besides arm64.
>
> Thanks for going through that exercise !
>
> Once sparc, s390, microblaze and mips reply, I think we'll have a good
> coverage, maybe riscv is to put in that lot too.
I posted the following two patches for supporting microblaze and unicore32.
[PATCH v2 1/2] io: prevent compiler reordering on the default writeX() implementation
[PATCH v2 2/2] io: prevent compiler reordering on the default readX() implementation
The rest of the arches except mips and alpha seem OK.
I sent a question email on Friday to mips and alpha mailing lists. I'll follow up with
an actual patch today.
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [PATCH net-next] net: ipv6/gre: Add GRO support
From: Eran Ben Elisha @ 2018-04-02 12:40 UTC (permalink / raw)
To: Eric Dumazet
Cc: Tariq Toukan, David S. Miller, Linux Netdev List, Eran Ben Elisha,
Eric Dumazet
In-Reply-To: <8dd7220e-e536-f89b-e5d4-27e57f319e0f@gmail.com>
On Sun, Apr 1, 2018 at 7:35 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
>
> On 04/01/2018 06:17 AM, Tariq Toukan wrote:
>> From: Eran Ben Elisha <eranbe@mellanox.com>
>>
>> Add GRO capability for IPv6 GRE tunnel and ip6erspan tap, via gro_cells
>> infrastructure.
>>
>> Performance testing: 55% higher badwidth.
>> Measuring bandwidth of 1 thread IPv4 TCP traffic over IPv6 GRE tunnel
>> while GRO on the physical interface is disabled.
>> CPU: Intel Xeon E312xx (Sandy Bridge)
>> NIC: Mellanox Technologies MT27700 Family [ConnectX-4]
>> Before (GRO not working in tunnel) : 2.47 Gbits/sec
>> After (GRO working in tunnel) : 3.85 Gbits/sec
>>
>> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
>> Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
>> CC: Eric Dumazet <edumazet@google.com>
>> ---
>
>
> Seems good, but why isn't this handled directly in GRO native layer ?
ip6_tunnel and ip6_gre do not share initialization flow functions (unlike ipv4).
Changing the ipv6 init infrastructure should not be part of this
patch. we prefer to keep this one minimal, simple and safe.
>
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] fs/crashdd: add API to collect hardware dump in second kernel
From: Rahul Lakkireddy @ 2018-04-02 12:30 UTC (permalink / raw)
To: Jiri Pirko
Cc: Indranil Choudhury,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Nirranjan Kirubaharan,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org,
Ganesh GR, Eric W. Biederman,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org
In-Reply-To: <20180402091143.GD3313@nanopsycho>
On Monday, April 04/02/18, 2018 at 14:41:43 +0530, Jiri Pirko wrote:
> Fri, Mar 30, 2018 at 08:42:00PM CEST, ebiederm@xmission.com wrote:
> >Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> writes:
> >
> >> On Friday, March 03/30/18, 2018 at 16:09:07 +0530, Jiri Pirko wrote:
> >>> Sat, Mar 24, 2018 at 11:56:33AM CET, rahul.lakkireddy@chelsio.com wrote:
> >>> >Add a new module crashdd that exports the /sys/kernel/crashdd/
> >>> >directory in second kernel, containing collected hardware/firmware
> >>> >dumps.
> >>> >
> >>> >The sequence of actions done by device drivers to append their device
> >>> >specific hardware/firmware logs to /sys/kernel/crashdd/ directory are
> >>> >as follows:
> >>> >
> >>> >1. During probe (before hardware is initialized), device drivers
> >>> >register to the crashdd module (via crashdd_add_dump()), with
> >>> >callback function, along with buffer size and log name needed for
> >>> >firmware/hardware log collection.
> >>> >
> >>> >2. Crashdd creates a driver's directory under
> >>> >/sys/kernel/crashdd/<driver>. Then, it allocates the buffer with
> >>>
> >>> This smells. I need to identify the exact ASIC instance that produced
> >>> the dump. To identify by driver name does not help me if I have multiple
> >>> instances of the same driver. This looks wrong to me. This looks like
> >>> a job for devlink where you have 1 devlink instance per 1 ASIC instance.
> >>>
> >>> Please see:
> >>> http://patchwork.ozlabs.org/project/netdev/list/?series=36524
> >>>
> >>> I bevieve that the solution in the patchset could be used for
> >>> your usecase too.
> >>>
> >>>
> >>
> >> The sysfs approach proposed here had been dropped in favour exporting
> >> the dumps as ELF notes in /proc/vmcore.
> >>
> >> Will be posting the new patches soon.
> >
> >The concern was actually how you identify which device that came from.
> >Where you read the identifier changes but sysfs or /proc/vmcore the
> >change remains valid.
>
> Yeah. I still don't see how you link the dump and the device.
In our case, the dump and the device are being identified by the
driver’s name followed by its corresponding pci bus id. I’ve posted an
example in my v3 series:
https://www.spinics.net/lists/netdev/msg493781.html
Here’s an extract from the link above:
# readelf -n /proc/vmcore
Displaying notes found at file offset 0x00001000 with length 0x04003288:
Owner Data size Description
VMCOREDD_cxgb4_0000:02:00.4 0x02000fd8 Unknown note type:(0x00000700)
VMCOREDD_cxgb4_0000:04:00.4 0x02000fd8 Unknown note type:(0x00000700)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
CORE 0x00000150 NT_PRSTATUS (prstatus structure)
VMCOREINFO 0x0000074f Unknown note type: (0x00000000)
Here, for my two devices, the dump’s names are
VMCOREDD_cxgb4_0000:02:00.4 and VMCOREDD_cxgb4_0000:04:00.4.
It’s really up to the callers to write their own unique name for the
dump. The name is appended to “VMCOREDD_” string.
> Rahul, did you look at the patchset I pointed out?
For devlink, I think the dump name would be identified by
bus_type/device_name; i.e. “pci/0000:02:00.4” for my example.
Is my understanding correct?
Thanks,
Rahul
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] fs/crashdd: add API to collect hardware dump in second kernel
From: Andrew Lunn @ 2018-04-02 12:21 UTC (permalink / raw)
To: Jiri Pirko
Cc: Indranil Choudhury,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Nirranjan Kirubaharan,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org,
Ganesh GR, Rahul Lakkireddy, Eric W. Biederman,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org
In-Reply-To: <20180402091143.GD3313@nanopsycho>
> >> The sysfs approach proposed here had been dropped in favour exporting
> >> the dumps as ELF notes in /proc/vmcore.
> >>
> >> Will be posting the new patches soon.
> >
> >The concern was actually how you identify which device that came from.
> >Where you read the identifier changes but sysfs or /proc/vmcore the
> >change remains valid.
>
> Yeah. I still don't see how you link the dump and the device.
Hi Jiri
You can see in the third version the core code accept a free form
name. The driver builds a name using the driver name and the adaptor
name.
What i think would be good is to try to have one API to the driver
that can be used for both crash dumps and devlink snapshots. These are
used at different times, but have basically the same purpose, get
state from the device.
Andrew
^ permalink raw reply
* RE: [PATCH] net: bond: skip vlan header when do layer 3+4 hash policy
From: liujian (CE) @ 2018-04-02 10:53 UTC (permalink / raw)
To: Nikolay Aleksandrov, davem@davemloft.net, j.vosburgh@gmail.com,
vfalico@gmail.com, andy@greyhouse.net
Cc: netdev@vger.kernel.org, weiyongjun (A)
In-Reply-To: <3d49c6b6-def8-a58c-5eeb-ed9e7df3f289@cumulusnetworks.com>
> -----Original Message-----
> From: Nikolay Aleksandrov [mailto:nikolay@cumulusnetworks.com]
> Sent: Saturday, March 31, 2018 5:23 PM
> To: liujian (CE) <liujian56@huawei.com>; davem@davemloft.net;
> j.vosburgh@gmail.com; vfalico@gmail.com; andy@greyhouse.net
> Cc: netdev@vger.kernel.org; weiyongjun (A) <weiyongjun1@huawei.com>
> Subject: Re: [PATCH] net: bond: skip vlan header when do layer 3+4 hash policy
>
> On 31/03/18 12:14, liujian56@huawei.com wrote:
> > From: liujian <liujian56@huawei.com>
> >
> > When the hash policy is BOND_XMIT_POLICY_LAYER34 mode and skb
> protocol
> > is 802.1q VLAN, the policy will be degenerated to LAYER2 mode; Now,
> > change it to get the next layer protocol to ensure that it worked in
> > BOND_XMIT_POLICY_LAYER34 mode.
> >
> > Signed-off-by: liujian <liujian56@huawei.com>
> > ---
> > drivers/net/bonding/bond_main.c | 11 ++++++++---
> > 1 file changed, 8 insertions(+), 3 deletions(-)
>
>
> Nak
> Use BOND_XMIT_POLICY_ENCAP34 (encap3+4), that was one of the main
> reasons it was added.
Got it, thank you~
^ permalink raw reply
* Re: [PATCH v2 0/7] net: thunderx: implement DMAC filtering support
From: Vadim Lomovtsev @ 2018-04-02 10:40 UTC (permalink / raw)
To: David Miller
Cc: sgoutham, sunil.kovvuri, rric, linux-arm-kernel, netdev,
linux-kernel, dnelson, ynorov, Vadim.Lomovtsev
In-Reply-To: <20180331.220730.1991017148197107974.davem@davemloft.net>
On Sat, Mar 31, 2018 at 10:07:30PM -0400, David Miller wrote:
> From: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
> Date: Fri, 30 Mar 2018 04:59:46 -0700
>
> > From: Vadim Lomovtsev <Vadim.Lomovtsev@cavium.com>
> >
> > By default CN88XX BGX accepts all incoming multicast and broadcast
> > packets and filtering is disabled. The nic driver doesn't provide
> > an ability to change such behaviour.
> >
> > This series is to implement DMAC filtering management for CN88XX
> > nic driver allowing user to enable/disable filtering and configure
> > specific MAC addresses to filter traffic.
> >
> > Changes from v1:
> > build issues:
> > - update code in order to address compiler warnings;
> > checkpatch.pl reported issues:
> > - update code in order to fit 80 symbols length;
> > - update commit descriptions in order to fit 80 symbols length;
>
> Series applied.
Thank you.
WBR,
Vadim
^ permalink raw reply
* Re: [PATCH V5 net-next 06/14] net/tls: Add generic NIC offload infrastructure
From: Boris Pismenny @ 2018-04-02 10:37 UTC (permalink / raw)
To: Kirill Tkhai, Saeed Mahameed, David S. Miller
Cc: netdev, Dave Watson, Ilya Lesokhin, Aviad Yehezkel
In-Reply-To: <f2100699-3e3c-dc6e-b180-36aef1b7c31a@virtuozzo.com>
Hi Kirill,
On 3/28/2018 6:11 PM, Kirill Tkhai wrote:
> On 28.03.2018 02:56, Saeed Mahameed wrote:
>> From: Ilya Lesokhin <ilyal@mellanox.com>
>>
>> This patch adds a generic infrastructure to offload TLS crypto to a
>> network device. It enables the kernel TLS socket to skip encryption
>> and authentication operations on the transmit side of the data path.
>> Leaving those computationally expensive operations to the NIC.
>>
>> The NIC offload infrastructure builds TLS records and pushes them to
>> the TCP layer just like the SW KTLS implementation and using the same API.
>> TCP segmentation is mostly unaffected. Currently the only exception is
>> that we prevent mixed SKBs where only part of the payload requires
>> offload. In the future we are likely to add a similar restriction
>> following a change cipher spec record.
>>
>> The notable differences between SW KTLS and NIC offloaded TLS
>> implementations are as follows:
>> 1. The offloaded implementation builds "plaintext TLS record", those
>> records contain plaintext instead of ciphertext and place holder bytes
>> instead of authentication tags.
>> 2. The offloaded implementation maintains a mapping from TCP sequence
>> number to TLS records. Thus given a TCP SKB sent from a NIC offloaded
>> TLS socket, we can use the tls NIC offload infrastructure to obtain
>> enough context to encrypt the payload of the SKB.
>> A TLS record is released when the last byte of the record is ack'ed,
>> this is done through the new icsk_clean_acked callback.
>>
>> The infrastructure should be extendable to support various NIC offload
>> implementations. However it is currently written with the
>> implementation below in mind:
>> The NIC assumes that packets from each offloaded stream are sent as
>> plaintext and in-order. It keeps track of the TLS records in the TCP
>> stream. When a packet marked for offload is transmitted, the NIC
>> encrypts the payload in-place and puts authentication tags in the
>> relevant place holders.
>>
>> The responsibility for handling out-of-order packets (i.e. TCP
>> retransmission, qdisc drops) falls on the netdev driver.
>>
>> The netdev driver keeps track of the expected TCP SN from the NIC's
>> perspective. If the next packet to transmit matches the expected TCP
>> SN, the driver advances the expected TCP SN, and transmits the packet
>> with TLS offload indication.
>>
>> If the next packet to transmit does not match the expected TCP SN. The
>> driver calls the TLS layer to obtain the TLS record that includes the
>> TCP of the packet for transmission. Using this TLS record, the driver
>> posts a work entry on the transmit queue to reconstruct the NIC TLS
>> state required for the offload of the out-of-order packet. It updates
>> the expected TCP SN accordingly and transmits the now in-order packet.
>> The same queue is used for packet transmission and TLS context
>> reconstruction to avoid the need for flushing the transmit queue before
>> issuing the context reconstruction request.
>>
>> Signed-off-by: Ilya Lesokhin <ilyal@mellanox.com>
>> Signed-off-by: Boris Pismenny <borisp@mellanox.com>
>> Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
>> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
>> ---
>> include/net/tls.h | 120 +++++--
>> net/tls/Kconfig | 10 +
>> net/tls/Makefile | 2 +
>> net/tls/tls_device.c | 759 ++++++++++++++++++++++++++++++++++++++++++
>> net/tls/tls_device_fallback.c | 454 +++++++++++++++++++++++++
>> net/tls/tls_main.c | 120 ++++---
>> net/tls/tls_sw.c | 132 ++++----
>> 7 files changed, 1476 insertions(+), 121 deletions(-)
>> create mode 100644 net/tls/tls_device.c
>> create mode 100644 net/tls/tls_device_fallback.c
>>
>> diff --git a/include/net/tls.h b/include/net/tls.h
>> index 437a746300bf..0a8529e9ec21 100644
>> --- a/include/net/tls.h
>> +++ b/include/net/tls.h
>> @@ -57,21 +57,10 @@
>>
>> #define TLS_AAD_SPACE_SIZE 13
>>
>> -struct tls_sw_context {
>> +struct tls_sw_context_tx {
>
> What the reason splitting this into tx + rx does not go in separate patch?
>
Added a separate patch for this in V6.
>> struct crypto_aead *aead_send;
>> - struct crypto_aead *aead_recv;
>> struct crypto_wait async_wait;
>>
>> - /* Receive context */
>> - struct strparser strp;
>> - void (*saved_data_ready)(struct sock *sk);
>> - unsigned int (*sk_poll)(struct file *file, struct socket *sock,
>> - struct poll_table_struct *wait);
>> - struct sk_buff *recv_pkt;
>> - u8 control;
>> - bool decrypted;
>> -
>> - /* Sending context */
>> char aad_space[TLS_AAD_SPACE_SIZE];
>>
>> unsigned int sg_plaintext_size;
>> @@ -88,6 +77,50 @@ struct tls_sw_context {
>> struct scatterlist sg_aead_out[2];
>> };
>>
>> +struct tls_sw_context_rx {
>> + struct crypto_aead *aead_recv;
>> + struct crypto_wait async_wait;
>> +
>> + struct strparser strp;
>> + void (*saved_data_ready)(struct sock *sk);
>> + unsigned int (*sk_poll)(struct file *file, struct socket *sock,
>> + struct poll_table_struct *wait);
>> + struct sk_buff *recv_pkt;
>> + u8 control;
>> + bool decrypted;
>> +};
>> +
>> +struct tls_record_info {
>> + struct list_head list;
>> + u32 end_seq;
>> + int len;
>> + int num_frags;
>> + skb_frag_t frags[MAX_SKB_FRAGS];
>> +};
>> +
>> +struct tls_offload_context {
>> + struct crypto_aead *aead_send;
>> + spinlock_t lock; /* protects records list */
>> + struct list_head records_list;
>> + struct tls_record_info *open_record;
>> + struct tls_record_info *retransmit_hint;
>> + u64 hint_record_sn;
>> + u64 unacked_record_sn;
>> +
>> + struct scatterlist sg_tx_data[MAX_SKB_FRAGS];
>> + void (*sk_destruct)(struct sock *sk);
>> + u8 driver_state[];
>> + /* The TLS layer reserves room for driver specific state
>> + * Currently the belief is that there is not enough
>> + * driver specific state to justify another layer of indirection
>> + */
>> +#define TLS_DRIVER_STATE_SIZE (max_t(size_t, 8, sizeof(void *)))
>> +};
>> +
>> +#define TLS_OFFLOAD_CONTEXT_SIZE \
>> + (ALIGN(sizeof(struct tls_offload_context), sizeof(void *)) + \
>> + TLS_DRIVER_STATE_SIZE)
>> +
>> enum {
>> TLS_PENDING_CLOSED_RECORD
>> };
>> @@ -112,9 +145,15 @@ struct tls_context {
>> struct tls12_crypto_info_aes_gcm_128 crypto_recv_aes_gcm_128;
>> };
>>
>> - void *priv_ctx;
>> + struct list_head list;
>> + struct net_device *netdev;
>> + refcount_t refcount;
>> +
>> + void *priv_ctx_tx;
>> + void *priv_ctx_rx;
>>
>> - u8 conf:2;
>> + u8 tx_conf:2;
>> + u8 rx_conf:2;
>>
>> struct cipher_context tx;
>> struct cipher_context rx;
>> @@ -149,7 +188,8 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
>> int tls_sw_sendpage(struct sock *sk, struct page *page,
>> int offset, size_t size, int flags);
>> void tls_sw_close(struct sock *sk, long timeout);
>> -void tls_sw_free_resources(struct sock *sk);
>> +void tls_sw_free_resources_tx(struct sock *sk);
>> +void tls_sw_free_resources_rx(struct sock *sk);
>> int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>> int nonblock, int flags, int *addr_len);
>> unsigned int tls_sw_poll(struct file *file, struct socket *sock,
>> @@ -158,9 +198,28 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
>> struct pipe_inode_info *pipe,
>> size_t len, unsigned int flags);
>>
>> -void tls_sk_destruct(struct sock *sk, struct tls_context *ctx);
>> -void tls_icsk_clean_acked(struct sock *sk);
>
> You unexport this function, and it becomes static after this patch.
> Why this cleanup can't go in separate patch?
>
This function is essential for the completeness of this patch. It cannot
go separately. There was no implementation before and it was placed here
by mistake. This patch introduces the implementation for the first time.
It is unexported now due to the changes requested by DaveM to the
clean_acked_data static_key.
>> +int tls_set_device_offload(struct sock *sk, struct tls_context *ctx);
>> +int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
>> +int tls_device_sendpage(struct sock *sk, struct page *page,
>> + int offset, size_t size, int flags);
>> +void tls_device_sk_destruct(struct sock *sk);
>> +void tls_device_init(void);
>> +void tls_device_cleanup(void);
>>
>> +struct tls_record_info *tls_get_record(struct tls_offload_context *context,
>> + u32 seq, u64 *p_record_sn);
>> +
>> +static inline bool tls_record_is_start_marker(struct tls_record_info *rec)
>> +{
>> + return rec->len == 0;
>> +}
>> +
>> +static inline u32 tls_record_start_seq(struct tls_record_info *rec)
>> +{
>> + return rec->end_seq - rec->len;
>> +}
>> +
>> +void tls_sk_destruct(struct sock *sk, struct tls_context *ctx);
>> int tls_push_sg(struct sock *sk, struct tls_context *ctx,
>> struct scatterlist *sg, u16 first_offset,
>> int flags);
>> @@ -197,6 +256,13 @@ static inline bool tls_is_pending_open_record(struct tls_context *tls_ctx)
>> return tls_ctx->pending_open_record_frags;
>> }
>>
>> +static inline bool tls_is_sk_tx_device_offloaded(struct sock *sk)
>> +{
>> + return sk_fullsock(sk) &&
>> + /* matches smp_store_release in tls_set_device_offload */
>> + smp_load_acquire(&sk->sk_destruct) == &tls_device_sk_destruct;
>> +}
>> +
>> static inline void tls_err_abort(struct sock *sk, int err)
>> {
>> sk->sk_err = err;
>> @@ -269,19 +335,33 @@ static inline struct tls_context *tls_get_ctx(const struct sock *sk)
>> return icsk->icsk_ulp_data;
>> }
>>
>> -static inline struct tls_sw_context *tls_sw_ctx(
>> +static inline struct tls_sw_context_rx *tls_sw_ctx_rx(
>> const struct tls_context *tls_ctx)
>> {
>> - return (struct tls_sw_context *)tls_ctx->priv_ctx;
>> + return (struct tls_sw_context_rx *)tls_ctx->priv_ctx_rx;
>
> This is still splitting in tx + tx. Why can't this go in separate patch?
>
See comment above.
>> +}
>> +
>> +static inline struct tls_sw_context_tx *tls_sw_ctx_tx(
>> + const struct tls_context *tls_ctx)
>> +{
>> + return (struct tls_sw_context_tx *)tls_ctx->priv_ctx_tx;
>> }
>>
>> static inline struct tls_offload_context *tls_offload_ctx(
>> const struct tls_context *tls_ctx)
>> {
>> - return (struct tls_offload_context *)tls_ctx->priv_ctx;
>> + return (struct tls_offload_context *)tls_ctx->priv_ctx_tx;
>> }
>>
>> int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg,
>> unsigned char *record_type);
>>
>> +struct sk_buff *tls_validate_xmit_skb(struct sock *sk,
>> + struct net_device *dev,
>> + struct sk_buff *skb);
>> +
>> +int tls_sw_fallback_init(struct sock *sk,
>> + struct tls_offload_context *offload_ctx,
>> + struct tls_crypto_info *crypto_info);
>> +
>> #endif /* _TLS_OFFLOAD_H */
>> diff --git a/net/tls/Kconfig b/net/tls/Kconfig
>> index 89b8745a986f..7ad4ded9d7ac 100644
>> --- a/net/tls/Kconfig
>> +++ b/net/tls/Kconfig
>> @@ -14,3 +14,13 @@ config TLS
>> encryption handling of the TLS protocol to be done in-kernel.
>>
>> If unsure, say N.
>> +
>> +config TLS_DEVICE
>> + bool "Transport Layer Security HW offload"
>> + depends on TLS
>> + select SOCK_VALIDATE_XMIT
>> + default n
>> + ---help---
>> + Enable kernel support for HW offload of the TLS protocol.
>> +
>> + If unsure, say N.
>> diff --git a/net/tls/Makefile b/net/tls/Makefile
>> index a930fd1c4f7b..4d6b728a67d0 100644
>> --- a/net/tls/Makefile
>> +++ b/net/tls/Makefile
>> @@ -5,3 +5,5 @@
>> obj-$(CONFIG_TLS) += tls.o
>>
>> tls-y := tls_main.o tls_sw.o
>> +
>> +tls-$(CONFIG_TLS_DEVICE) += tls_device.o tls_device_fallback.o
>> diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
>> new file mode 100644
>> index 000000000000..f33cd65efa8a
>> --- /dev/null
>> +++ b/net/tls/tls_device.c
>> @@ -0,0 +1,759 @@
>> +/* Copyright (c) 2018, Mellanox Technologies All rights reserved.
>> + *
>> + * This software is available to you under a choice of one of two
>> + * licenses. You may choose to be licensed under the terms of the GNU
>> + * General Public License (GPL) Version 2, available from the file
>> + * COPYING in the main directory of this source tree, or the
>> + * OpenIB.org BSD license below:
>> + *
>> + * Redistribution and use in source and binary forms, with or
>> + * without modification, are permitted provided that the following
>> + * conditions are met:
>> + *
>> + * - Redistributions of source code must retain the above
>> + * copyright notice, this list of conditions and the following
>> + * disclaimer.
>> + *
>> + * - Redistributions in binary form must reproduce the above
>> + * copyright notice, this list of conditions and the following
>> + * disclaimer in the documentation and/or other materials
>> + * provided with the distribution.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
>> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
>> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
>> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
>> + * SOFTWARE.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <net/tcp.h>
>> +#include <net/inet_common.h>
>> +#include <linux/highmem.h>
>> +#include <linux/netdevice.h>
>> +
>> +#include <net/tls.h>
>> +#include <crypto/aead.h>
>> +
>> +/* device_offload_lock is used to synchronize tls_dev_add
>> + * against NETDEV_DOWN notifications.
>> + */
>> +static DECLARE_RWSEM(device_offload_lock);
>> +
>> +static void tls_device_gc_task(struct work_struct *work);
>> +
>> +static DECLARE_WORK(tls_device_gc_work, tls_device_gc_task);
>> +static LIST_HEAD(tls_device_gc_list);
>> +static LIST_HEAD(tls_device_list);
>> +static DEFINE_SPINLOCK(tls_device_lock);
>> +
>> +static void tls_device_free_ctx(struct tls_context *ctx)
>> +{
>> + struct tls_offload_context *offload_ctx = tls_offload_ctx(ctx);
>> +
>> + kfree(offload_ctx);
>> + kfree(ctx);
>> +}
>> +
>> +static void tls_device_gc_task(struct work_struct *work)
>> +{
>> + struct tls_context *ctx, *tmp;
>> + unsigned long flags;
>> + LIST_HEAD(gc_list);
>> +
>> + spin_lock_irqsave(&tls_device_lock, flags);
>> + list_splice_init(&tls_device_gc_list, &gc_list);
>> + spin_unlock_irqrestore(&tls_device_lock, flags);
>> +
>> + list_for_each_entry_safe(ctx, tmp, &gc_list, list) {
>> + struct net_device *netdev = ctx->netdev;
>> +
>> + if (netdev) {
>> + netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
>> + TLS_OFFLOAD_CTX_DIR_TX);
>> + dev_put(netdev);
>> + }
>> +
>> + list_del(&ctx->list);
>> + tls_device_free_ctx(ctx);
>> + }
>> +}
>> +
>> +static void tls_device_queue_ctx_destruction(struct tls_context *ctx)
>> +{
>> + unsigned long flags;
>> +
>> + spin_lock_irqsave(&tls_device_lock, flags);
>> + list_move_tail(&ctx->list, &tls_device_gc_list);
>> +
>> + /* schedule_work inside the spinlock
>> + * to make sure tls_device_down waits for that work.
>> + */
>> + schedule_work(&tls_device_gc_work);
>> +
>> + spin_unlock_irqrestore(&tls_device_lock, flags);
>> +}
>> +
>> +/* We assume that the socket is already connected */
>> +static struct net_device *get_netdev_for_sock(struct sock *sk)
>> +{
>> + struct inet_sock *inet = inet_sk(sk);
>> + struct net_device *netdev = NULL;
>> +
>> + netdev = dev_get_by_index(sock_net(sk), inet->cork.fl.flowi_oif);
>> +
>> + return netdev;
>> +}
>> +
>> +static void destroy_record(struct tls_record_info *record)
>> +{
>> + int nr_frags = record->num_frags;
>> + skb_frag_t *frag;
>> +
>> + while (nr_frags-- > 0) {
>> + frag = &record->frags[nr_frags];
>> + __skb_frag_unref(frag);
>> + }
>> + kfree(record);
>> +}
>> +
>> +static void delete_all_records(struct tls_offload_context *offload_ctx)
>> +{
>> + struct tls_record_info *info, *temp;
>> +
>> + list_for_each_entry_safe(info, temp, &offload_ctx->records_list, list) {
>> + list_del(&info->list);
>> + destroy_record(info);
>> + }
>> +
>> + offload_ctx->retransmit_hint = NULL;
>> +}
>> +
>> +static void tls_icsk_clean_acked(struct sock *sk, u32 acked_seq)
>> +{
>> + struct tls_context *tls_ctx = tls_get_ctx(sk);
>> + struct tls_record_info *info, *temp;
>> + struct tls_offload_context *ctx;
>> + u64 deleted_records = 0;
>> + unsigned long flags;
>> +
>> + if (!tls_ctx)
>> + return;
>> +
>> + ctx = tls_offload_ctx(tls_ctx);
>> +
>> + spin_lock_irqsave(&ctx->lock, flags);
>> + info = ctx->retransmit_hint;
>> + if (info && !before(acked_seq, info->end_seq)) {
>> + ctx->retransmit_hint = NULL;
>> + list_del(&info->list);
>> + destroy_record(info);
>> + deleted_records++;
>> + }
>> +
>> + list_for_each_entry_safe(info, temp, &ctx->records_list, list) {
>> + if (before(acked_seq, info->end_seq))
>> + break;
>> + list_del(&info->list);
>> +
>> + destroy_record(info);
>> + deleted_records++;
>> + }
>> +
>> + ctx->unacked_record_sn += deleted_records;
>> + spin_unlock_irqrestore(&ctx->lock, flags);
>> +}
>> +
>> +/* At this point, there should be no references on this
>> + * socket and no in-flight SKBs associated with this
>> + * socket, so it is safe to free all the resources.
>> + */
>> +void tls_device_sk_destruct(struct sock *sk)
>> +{
>> + struct tls_context *tls_ctx = tls_get_ctx(sk);
>> + struct tls_offload_context *ctx = tls_offload_ctx(tls_ctx);
>> +
>> + if (ctx->open_record)
>> + destroy_record(ctx->open_record);
>> +
>> + delete_all_records(ctx);
>> + crypto_free_aead(ctx->aead_send);
>> + ctx->sk_destruct(sk);
>> + clean_acked_data_disable(inet_csk(sk));
>> +
>> + if (refcount_dec_and_test(&tls_ctx->refcount))
>> + tls_device_queue_ctx_destruction(tls_ctx);
>> +}
>> +EXPORT_SYMBOL(tls_device_sk_destruct);
>> +
>> +static void tls_append_frag(struct tls_record_info *record,
>> + struct page_frag *pfrag,
>> + int size)
>> +{
>> + skb_frag_t *frag;
>> +
>> + frag = &record->frags[record->num_frags - 1];
>> + if (frag->page.p == pfrag->page &&
>> + frag->page_offset + frag->size == pfrag->offset) {
>> + frag->size += size;
>> + } else {
>> + ++frag;
>> + frag->page.p = pfrag->page;
>> + frag->page_offset = pfrag->offset;
>> + frag->size = size;
>> + ++record->num_frags;
>> + get_page(pfrag->page);
>> + }
>> +
>> + pfrag->offset += size;
>> + record->len += size;
>> +}
>> +
>> +static int tls_push_record(struct sock *sk,
>> + struct tls_context *ctx,
>> + struct tls_offload_context *offload_ctx,
>> + struct tls_record_info *record,
>> + struct page_frag *pfrag,
>> + int flags,
>> + unsigned char record_type)
>> +{
>> + struct tcp_sock *tp = tcp_sk(sk);
>> + struct page_frag dummy_tag_frag;
>> + skb_frag_t *frag;
>> + int i;
>> +
>> + /* fill prepend */
>> + frag = &record->frags[0];
>> + tls_fill_prepend(ctx,
>> + skb_frag_address(frag),
>> + record->len - ctx->tx.prepend_size,
>> + record_type);
>> +
>> + /* HW doesn't care about the data in the tag, because it fills it. */
>> + dummy_tag_frag.page = skb_frag_page(frag);
>> + dummy_tag_frag.offset = 0;
>> +
>> + tls_append_frag(record, &dummy_tag_frag, ctx->tx.tag_size);
>> + record->end_seq = tp->write_seq + record->len;
>> + spin_lock_irq(&offload_ctx->lock);
>> + list_add_tail(&record->list, &offload_ctx->records_list);
>> + spin_unlock_irq(&offload_ctx->lock);
>> + offload_ctx->open_record = NULL;
>> + set_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags);
>> + tls_advance_record_sn(sk, &ctx->tx);
>> +
>> + for (i = 0; i < record->num_frags; i++) {
>> + frag = &record->frags[i];
>> + sg_unmark_end(&offload_ctx->sg_tx_data[i]);
>> + sg_set_page(&offload_ctx->sg_tx_data[i], skb_frag_page(frag),
>> + frag->size, frag->page_offset);
>> + sk_mem_charge(sk, frag->size);
>> + get_page(skb_frag_page(frag));
>> + }
>> + sg_mark_end(&offload_ctx->sg_tx_data[record->num_frags - 1]);
>> +
>> + /* all ready, send */
>> + return tls_push_sg(sk, ctx, offload_ctx->sg_tx_data, 0, flags);
>> +}
>> +
>> +static int tls_create_new_record(struct tls_offload_context *offload_ctx,
>> + struct page_frag *pfrag,
>> + size_t prepend_size)
>> +{
>> + struct tls_record_info *record;
>> + skb_frag_t *frag;
>> +
>> + record = kmalloc(sizeof(*record), GFP_KERNEL);
>> + if (!record)
>> + return -ENOMEM;
>> +
>> + frag = &record->frags[0];
>> + __skb_frag_set_page(frag, pfrag->page);
>> + frag->page_offset = pfrag->offset;
>> + skb_frag_size_set(frag, prepend_size);
>> +
>> + get_page(pfrag->page);
>> + pfrag->offset += prepend_size;
>> +
>> + record->num_frags = 1;
>> + record->len = prepend_size;
>> + offload_ctx->open_record = record;
>> + return 0;
>> +}
>> +
>> +static int tls_do_allocation(struct sock *sk,
>> + struct tls_offload_context *offload_ctx,
>> + struct page_frag *pfrag,
>> + size_t prepend_size)
>> +{
>> + int ret;
>> +
>> + if (!offload_ctx->open_record) {
>> + if (unlikely(!skb_page_frag_refill(prepend_size, pfrag,
>> + sk->sk_allocation))) {
>> + sk->sk_prot->enter_memory_pressure(sk);
>> + sk_stream_moderate_sndbuf(sk);
>> + return -ENOMEM;
>> + }
>> +
>> + ret = tls_create_new_record(offload_ctx, pfrag, prepend_size);
>> + if (ret)
>> + return ret;
>> +
>> + if (pfrag->size > pfrag->offset)
>> + return 0;
>> + }
>> +
>> + if (!sk_page_frag_refill(sk, pfrag))
>> + return -ENOMEM;
>> +
>> + return 0;
>> +}
>> +
>> +static int tls_push_data(struct sock *sk,
>> + struct iov_iter *msg_iter,
>> + size_t size, int flags,
>> + unsigned char record_type)
>> +{
>> + struct tls_context *tls_ctx = tls_get_ctx(sk);
>> + struct tls_offload_context *ctx = tls_offload_ctx(tls_ctx);
>> + int tls_push_record_flags = flags | MSG_SENDPAGE_NOTLAST;
>> + int more = flags & (MSG_SENDPAGE_NOTLAST | MSG_MORE);
>> + struct tls_record_info *record = ctx->open_record;
>> + struct page_frag *pfrag;
>> + size_t orig_size = size;
>> + u32 max_open_record_len;
>> + int copy, rc = 0;
>> + bool done = false;
>> + long timeo;
>> +
>> + if (flags &
>> + ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST))
>> + return -ENOTSUPP;
>> +
>> + if (sk->sk_err)
>> + return -sk->sk_err;
>> +
>> + timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
>> + rc = tls_complete_pending_work(sk, tls_ctx, flags, &timeo);
>> + if (rc < 0)
>> + return rc;
>> +
>> + pfrag = sk_page_frag(sk);
>> +
>> + /* TLS_HEADER_SIZE is not counted as part of the TLS record, and
>> + * we need to leave room for an authentication tag.
>> + */
>> + max_open_record_len = TLS_MAX_PAYLOAD_SIZE +
>> + tls_ctx->tx.prepend_size;
>> + do {
>> + rc = tls_do_allocation(sk, ctx, pfrag,
>> + tls_ctx->tx.prepend_size);
>> + if (rc) {
>> + rc = sk_stream_wait_memory(sk, &timeo);
>> + if (!rc)
>> + continue;
>> +
>> + record = ctx->open_record;
>> + if (!record)
>> + break;
>> +handle_error:
>> + if (record_type != TLS_RECORD_TYPE_DATA) {
>> + /* avoid sending partial
>> + * record with type !=
>> + * application_data
>> + */
>> + size = orig_size;
>> + destroy_record(record);
>> + ctx->open_record = NULL;
>> + } else if (record->len > tls_ctx->tx.prepend_size) {
>> + goto last_record;
>> + }
>> +
>> + break;
>> + }
>> +
>> + record = ctx->open_record;
>> + copy = min_t(size_t, size, (pfrag->size - pfrag->offset));
>> + copy = min_t(size_t, copy, (max_open_record_len - record->len));
>> +
>> + if (copy_from_iter_nocache(page_address(pfrag->page) +
>> + pfrag->offset,
>> + copy, msg_iter) != copy) {
>> + rc = -EFAULT;
>> + goto handle_error;
>> + }
>> + tls_append_frag(record, pfrag, copy);
>> +
>> + size -= copy;
>> + if (!size) {
>> +last_record:
>> + tls_push_record_flags = flags;
>> + if (more) {
>> + tls_ctx->pending_open_record_frags =
>> + record->num_frags;
>> + break;
>> + }
>> +
>> + done = true;
>> + }
>> +
>> + if (done || record->len >= max_open_record_len ||
>> + (record->num_frags >= MAX_SKB_FRAGS - 1)) {
>> + rc = tls_push_record(sk,
>> + tls_ctx,
>> + ctx,
>> + record,
>> + pfrag,
>> + tls_push_record_flags,
>> + record_type);
>> + if (rc < 0)
>> + break;
>> + }
>> + } while (!done);
>> +
>> + if (orig_size - size > 0)
>> + rc = orig_size - size;
>> +
>> + return rc;
>> +}
>> +
>> +int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>> +{
>> + unsigned char record_type = TLS_RECORD_TYPE_DATA;
>> + int rc;
>> +
>> + lock_sock(sk);
>> +
>> + if (unlikely(msg->msg_controllen)) {
>> + rc = tls_proccess_cmsg(sk, msg, &record_type);
>> + if (rc)
>> + goto out;
>> + }
>> +
>> + rc = tls_push_data(sk, &msg->msg_iter, size,
>> + msg->msg_flags, record_type);
>> +
>> +out:
>> + release_sock(sk);
>> + return rc;
>> +}
>> +
>> +int tls_device_sendpage(struct sock *sk, struct page *page,
>> + int offset, size_t size, int flags)
>> +{
>> + struct iov_iter msg_iter;
>> + char *kaddr = kmap(page);
>> + struct kvec iov;
>> + int rc;
>> +
>> + if (flags & MSG_SENDPAGE_NOTLAST)
>> + flags |= MSG_MORE;
>> +
>> + lock_sock(sk);
>> +
>> + if (flags & MSG_OOB) {
>> + rc = -ENOTSUPP;
>> + goto out;
>> + }
>> +
>> + iov.iov_base = kaddr + offset;
>> + iov.iov_len = size;
>> + iov_iter_kvec(&msg_iter, WRITE | ITER_KVEC, &iov, 1, size);
>> + rc = tls_push_data(sk, &msg_iter, size,
>> + flags, TLS_RECORD_TYPE_DATA);
>> + kunmap(page);
>> +
>> +out:
>> + release_sock(sk);
>> + return rc;
>> +}
>> +
>> +struct tls_record_info *tls_get_record(struct tls_offload_context *context,
>> + u32 seq, u64 *p_record_sn)
>> +{
>> + u64 record_sn = context->hint_record_sn;
>> + struct tls_record_info *info;
>> +
>> + info = context->retransmit_hint;
>> + if (!info ||
>> + before(seq, info->end_seq - info->len)) {
>> + /* if retransmit_hint is irrelevant start
>> + * from the beggining of the list
>> + */
>> + info = list_first_entry(&context->records_list,
>> + struct tls_record_info, list);
>> + record_sn = context->unacked_record_sn;
>> + }
>> +
>> + list_for_each_entry_from(info, &context->records_list, list) {
>> + if (before(seq, info->end_seq)) {
>> + if (!context->retransmit_hint ||
>> + after(info->end_seq,
>> + context->retransmit_hint->end_seq)) {
>> + context->hint_record_sn = record_sn;
>> + context->retransmit_hint = info;
>> + }
>> + *p_record_sn = record_sn;
>> + return info;
>> + }
>> + record_sn++;
>> + }
>> +
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(tls_get_record);
>> +
>> +static int tls_device_push_pending_record(struct sock *sk, int flags)
>> +{
>> + struct iov_iter msg_iter;
>> +
>> + iov_iter_kvec(&msg_iter, WRITE | ITER_KVEC, NULL, 0, 0);
>> + return tls_push_data(sk, &msg_iter, 0, flags, TLS_RECORD_TYPE_DATA);
>> +}
>> +
>> +int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
>> +{
>> + u16 nonce_size, tag_size, iv_size, rec_seq_size;
>> + struct tls_record_info *start_marker_record;
>> + struct tls_offload_context *offload_ctx;
>> + struct tls_crypto_info *crypto_info;
>> + struct net_device *netdev;
>> + char *iv, *rec_seq;
>> + struct sk_buff *skb;
>> + int rc = -EINVAL;
>> + __be64 rcd_sn;
>> +
>> + if (!ctx)
>> + goto out;
>> +
>> + if (ctx->priv_ctx_tx) {
>> + rc = -EEXIST;
>> + goto out;
>> + }
>> +
>> + start_marker_record = kmalloc(sizeof(*start_marker_record), GFP_KERNEL);
>> + if (!start_marker_record) {
>> + rc = -ENOMEM;
>> + goto out;
>> + }
>> +
>> + offload_ctx = kzalloc(TLS_OFFLOAD_CONTEXT_SIZE, GFP_KERNEL);
>> + if (!offload_ctx) {
>> + rc = -ENOMEM;
>> + goto free_marker_record;
>> + }
>> +
>> + crypto_info = &ctx->crypto_send;
>> + switch (crypto_info->cipher_type) {
>> + case TLS_CIPHER_AES_GCM_128:
>> + nonce_size = TLS_CIPHER_AES_GCM_128_IV_SIZE;
>> + tag_size = TLS_CIPHER_AES_GCM_128_TAG_SIZE;
>> + iv_size = TLS_CIPHER_AES_GCM_128_IV_SIZE;
>> + iv = ((struct tls12_crypto_info_aes_gcm_128 *)crypto_info)->iv;
>> + rec_seq_size = TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE;
>> + rec_seq =
>> + ((struct tls12_crypto_info_aes_gcm_128 *)crypto_info)->rec_seq;
>> + break;
>> + default:
>> + rc = -EINVAL;
>> + goto free_offload_ctx;
>> + }
>> +
>> + ctx->tx.prepend_size = TLS_HEADER_SIZE + nonce_size;
>> + ctx->tx.tag_size = tag_size;
>> + ctx->tx.overhead_size = ctx->tx.prepend_size + ctx->tx.tag_size;
>> + ctx->tx.iv_size = iv_size;
>> + ctx->tx.iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
>> + GFP_KERNEL);
>> + if (!ctx->tx.iv) {
>> + rc = -ENOMEM;
>> + goto free_offload_ctx;
>> + }
>> +
>> + memcpy(ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size);
>> +
>> + ctx->tx.rec_seq_size = rec_seq_size;
>> + ctx->tx.rec_seq = kmalloc(rec_seq_size, GFP_KERNEL);
>> + if (!ctx->tx.rec_seq) {
>> + rc = -ENOMEM;
>> + goto free_iv;
>> + }
>> + memcpy(ctx->tx.rec_seq, rec_seq, rec_seq_size);
>> +
>> + rc = tls_sw_fallback_init(sk, offload_ctx, crypto_info);
>> + if (rc)
>> + goto free_rec_seq;
>> +
>> + /* start at rec_seq - 1 to account for the start marker record */
>> + memcpy(&rcd_sn, ctx->tx.rec_seq, sizeof(rcd_sn));
>> + offload_ctx->unacked_record_sn = be64_to_cpu(rcd_sn) - 1;
>> +
>> + start_marker_record->end_seq = tcp_sk(sk)->write_seq;
>> + start_marker_record->len = 0;
>> + start_marker_record->num_frags = 0;
>> +
>> + INIT_LIST_HEAD(&offload_ctx->records_list);
>> + list_add_tail(&start_marker_record->list, &offload_ctx->records_list);
>> + spin_lock_init(&offload_ctx->lock);
>> +
>> + clean_acked_data_enable(inet_csk(sk), &tls_icsk_clean_acked);
>> + ctx->push_pending_record = tls_device_push_pending_record;
>> + offload_ctx->sk_destruct = sk->sk_destruct;
>> +
>> + /* TLS offload is greatly simplified if we don't send
>> + * SKBs where only part of the payload needs to be encrypted.
>> + * So mark the last skb in the write queue as end of record.
>> + */
>> + skb = tcp_write_queue_tail(sk);
>> + if (skb)
>> + TCP_SKB_CB(skb)->eor = 1;
>> +
>> + refcount_set(&ctx->refcount, 1);
>> +
>> + /* We support starting offload on multiple sockets
>> + * concurrently, so we only need a read lock here.
>> + * This lock must preceed get_netdev_for_sock to prevent races between
>> + * NETDEV_DOWN and setsockopt.
>> + */
>> + down_read(&device_offload_lock);
>> + netdev = get_netdev_for_sock(sk);
>> + if (!netdev) {
>> + pr_err_ratelimited("%s: netdev not found\n", __func__);
>> + rc = -EINVAL;
>> + goto release_lock;
>> + }
>> +
>> + if (!(netdev->features & NETIF_F_HW_TLS_TX)) {
>> + rc = -ENOTSUPP;
>> + goto release_netdev;
>> + }
>> +
>> + /* Avoid offloading if the device is down
>> + * We don't want to offload new flows after
>> + * the NETDEV_DOWN event
>> + */
>> + if (!(netdev->flags & IFF_UP)) {
>> + rc = -EINVAL;
>> + goto release_netdev;
>> + }
>> +
>> + ctx->priv_ctx_tx = offload_ctx;
>> + rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_TX,
>> + &ctx->crypto_send,
>> + tcp_sk(sk)->write_seq);
>> + if (rc)
>> + goto release_netdev;
>> +
>> + ctx->netdev = netdev;
>> +
>> + spin_lock_irq(&tls_device_lock);
>> + list_add_tail(&ctx->list, &tls_device_list);
>> + spin_unlock_irq(&tls_device_lock);
>> +
>> + sk->sk_validate_xmit_skb = tls_validate_xmit_skb;
>> + /* following this assignment tls_is_sk_tx_device_offloaded
>> + * will return true and the context might be accessed
>> + * by the netdev's xmit function.
>> + */
>> + smp_store_release(&sk->sk_destruct,
>> + &tls_device_sk_destruct);
>> + up_read(&device_offload_lock);
>> + goto out;
>> +
>> +release_netdev:
>> + dev_put(netdev);
>> +release_lock:
>> + up_read(&device_offload_lock);
>> + clean_acked_data_disable(inet_csk(sk));
>> + crypto_free_aead(offload_ctx->aead_send);
>> +free_rec_seq:
>> + kfree(ctx->tx.rec_seq);
>> +free_iv:
>> + kfree(ctx->tx.iv);
>> +free_offload_ctx:
>> + kfree(offload_ctx);
>> + ctx->priv_ctx_tx = NULL;
>> +free_marker_record:
>> + kfree(start_marker_record);
>> +out:
>> + return rc;
>> +}
>> +
>> +static int tls_device_down(struct net_device *netdev)
>> +{
>> + struct tls_context *ctx, *tmp;
>> + unsigned long flags;
>> + LIST_HEAD(list);
>> +
>> + /* Request a write lock to block new offload attempts */
>> + down_write(&device_offload_lock);
>> +
>> + spin_lock_irqsave(&tls_device_lock, flags);
>> + list_for_each_entry_safe(ctx, tmp, &tls_device_list, list) {
>> + if (ctx->netdev != netdev ||
>> + !refcount_inc_not_zero(&ctx->refcount))
>> + continue;
>> +
>> + list_move(&ctx->list, &list);
>> + }
>> + spin_unlock_irqrestore(&tls_device_lock, flags);
>> +
>> + list_for_each_entry_safe(ctx, tmp, &list, list) {
>> + netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
>> + TLS_OFFLOAD_CTX_DIR_TX);
>> + ctx->netdev = NULL;
>> + dev_put(netdev);
>> + list_del_init(&ctx->list);
>> +
>> + if (refcount_dec_and_test(&ctx->refcount))
>> + tls_device_free_ctx(ctx);
>> + }
>> +
>> + up_write(&device_offload_lock);
>> +
>> + flush_work(&tls_device_gc_work);
>> +
>> + return NOTIFY_DONE;
>> +}
>> +
>> +static int tls_dev_event(struct notifier_block *this, unsigned long event,
>> + void *ptr)
>> +{
>> + struct net_device *dev = netdev_notifier_info_to_dev(ptr);
>> +
>> + if (!(dev->features & NETIF_F_HW_TLS_TX))
>> + return NOTIFY_DONE;
>> +
>> + switch (event) {
>> + case NETDEV_REGISTER:
>> + case NETDEV_FEAT_CHANGE:
>> + if (dev->tlsdev_ops &&
>> + dev->tlsdev_ops->tls_dev_add &&
>> + dev->tlsdev_ops->tls_dev_del)
>> + return NOTIFY_DONE;
>> + else
>> + return NOTIFY_BAD;
>> + case NETDEV_DOWN:
>> + return tls_device_down(dev);
>> + }
>> + return NOTIFY_DONE;
>> +}
>> +
>> +static struct notifier_block tls_dev_notifier = {
>> + .notifier_call = tls_dev_event,
>> +};
>> +
>> +void __init tls_device_init(void)
>> +{
>> + register_netdevice_notifier(&tls_dev_notifier);
>> +}
>> +
>> +void __exit tls_device_cleanup(void)
>> +{
>> + unregister_netdevice_notifier(&tls_dev_notifier);
>> + flush_work(&tls_device_gc_work);
>> +}
>> diff --git a/net/tls/tls_device_fallback.c b/net/tls/tls_device_fallback.c
>> new file mode 100644
>> index 000000000000..4e0f3d56b6dd
>> --- /dev/null
>> +++ b/net/tls/tls_device_fallback.c
>> @@ -0,0 +1,454 @@
>> +/* Copyright (c) 2018, Mellanox Technologies All rights reserved.
>> + *
>> + * This software is available to you under a choice of one of two
>> + * licenses. You may choose to be licensed under the terms of the GNU
>> + * General Public License (GPL) Version 2, available from the file
>> + * COPYING in the main directory of this source tree, or the
>> + * OpenIB.org BSD license below:
>> + *
>> + * Redistribution and use in source and binary forms, with or
>> + * without modification, are permitted provided that the following
>> + * conditions are met:
>> + *
>> + * - Redistributions of source code must retain the above
>> + * copyright notice, this list of conditions and the following
>> + * disclaimer.
>> + *
>> + * - Redistributions in binary form must reproduce the above
>> + * copyright notice, this list of conditions and the following
>> + * disclaimer in the documentation and/or other materials
>> + * provided with the distribution.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
>> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
>> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
>> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
>> + * SOFTWARE.
>> + */
>> +
>> +#include <net/tls.h>
>> +#include <crypto/aead.h>
>> +#include <crypto/scatterwalk.h>
>> +#include <net/ip6_checksum.h>
>> +
>> +static void chain_to_walk(struct scatterlist *sg, struct scatter_walk *walk)
>> +{
>> + struct scatterlist *src = walk->sg;
>> + int diff = walk->offset - src->offset;
>> +
>> + sg_set_page(sg, sg_page(src),
>> + src->length - diff, walk->offset);
>> +
>> + scatterwalk_crypto_chain(sg, sg_next(src), 0, 2);
>> +}
>> +
>> +static int tls_enc_record(struct aead_request *aead_req,
>> + struct crypto_aead *aead, char *aad,
>> + char *iv, __be64 rcd_sn,
>> + struct scatter_walk *in,
>> + struct scatter_walk *out, int *in_len)
>> +{
>> + unsigned char buf[TLS_HEADER_SIZE + TLS_CIPHER_AES_GCM_128_IV_SIZE];
>> + struct scatterlist sg_in[3];
>> + struct scatterlist sg_out[3];
>> + u16 len;
>> + int rc;
>> +
>> + len = min_t(int, *in_len, ARRAY_SIZE(buf));
>> +
>> + scatterwalk_copychunks(buf, in, len, 0);
>> + scatterwalk_copychunks(buf, out, len, 1);
>> +
>> + *in_len -= len;
>> + if (!*in_len)
>> + return 0;
>> +
>> + scatterwalk_pagedone(in, 0, 1);
>> + scatterwalk_pagedone(out, 1, 1);
>> +
>> + len = buf[4] | (buf[3] << 8);
>> + len -= TLS_CIPHER_AES_GCM_128_IV_SIZE;
>> +
>> + tls_make_aad(aad, len - TLS_CIPHER_AES_GCM_128_TAG_SIZE,
>> + (char *)&rcd_sn, sizeof(rcd_sn), buf[0]);
>> +
>> + memcpy(iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, buf + TLS_HEADER_SIZE,
>> + TLS_CIPHER_AES_GCM_128_IV_SIZE);
>> +
>> + sg_init_table(sg_in, ARRAY_SIZE(sg_in));
>> + sg_init_table(sg_out, ARRAY_SIZE(sg_out));
>> + sg_set_buf(sg_in, aad, TLS_AAD_SPACE_SIZE);
>> + sg_set_buf(sg_out, aad, TLS_AAD_SPACE_SIZE);
>> + chain_to_walk(sg_in + 1, in);
>> + chain_to_walk(sg_out + 1, out);
>> +
>> + *in_len -= len;
>> + if (*in_len < 0) {
>> + *in_len += TLS_CIPHER_AES_GCM_128_TAG_SIZE;
>> + /* the input buffer doesn't contain the entire record.
>> + * trim len accordingly. The resulting authentication tag
>> + * will contain garbage, but we don't care, so we won't
>> + * include any of it in the output skb
>> + * Note that we assume the output buffer length
>> + * is larger then input buffer length + tag size
>> + */
>> + if (*in_len < 0)
>> + len += *in_len;
>> +
>> + *in_len = 0;
>> + }
>> +
>> + if (*in_len) {
>> + scatterwalk_copychunks(NULL, in, len, 2);
>> + scatterwalk_pagedone(in, 0, 1);
>> + scatterwalk_copychunks(NULL, out, len, 2);
>> + scatterwalk_pagedone(out, 1, 1);
>> + }
>> +
>> + len -= TLS_CIPHER_AES_GCM_128_TAG_SIZE;
>> + aead_request_set_crypt(aead_req, sg_in, sg_out, len, iv);
>> +
>> + rc = crypto_aead_encrypt(aead_req);
>> +
>> + return rc;
>> +}
>> +
>> +static void tls_init_aead_request(struct aead_request *aead_req,
>> + struct crypto_aead *aead)
>> +{
>> + aead_request_set_tfm(aead_req, aead);
>> + aead_request_set_ad(aead_req, TLS_AAD_SPACE_SIZE);
>> +}
>> +
>> +static struct aead_request *tls_alloc_aead_request(struct crypto_aead *aead,
>> + gfp_t flags)
>> +{
>> + unsigned int req_size = sizeof(struct aead_request) +
>> + crypto_aead_reqsize(aead);
>> + struct aead_request *aead_req;
>> +
>> + aead_req = kzalloc(req_size, flags);
>> + if (aead_req)
>> + tls_init_aead_request(aead_req, aead);
>> + return aead_req;
>> +}
>> +
>> +static int tls_enc_records(struct aead_request *aead_req,
>> + struct crypto_aead *aead, struct scatterlist *sg_in,
>> + struct scatterlist *sg_out, char *aad, char *iv,
>> + u64 rcd_sn, int len)
>> +{
>> + struct scatter_walk out, in;
>> + int rc;
>> +
>> + scatterwalk_start(&in, sg_in);
>> + scatterwalk_start(&out, sg_out);
>> +
>> + do {
>> + rc = tls_enc_record(aead_req, aead, aad, iv,
>> + cpu_to_be64(rcd_sn), &in, &out, &len);
>> + rcd_sn++;
>> +
>> + } while (rc == 0 && len);
>> +
>> + scatterwalk_done(&in, 0, 0);
>> + scatterwalk_done(&out, 1, 0);
>> +
>> + return rc;
>> +}
>> +
>> +/* Can't use icsk->icsk_af_ops->send_check here because the ip addresses
>> + * might have been changed by NAT.
>> + */
>> +static void update_chksum(struct sk_buff *skb, int headln)
>> +{
>> + struct tcphdr *th = tcp_hdr(skb);
>> + int datalen = skb->len - headln;
>> + const struct ipv6hdr *ipv6h;
>> + const struct iphdr *iph;
>> +
>> + /* We only changed the payload so if we are using partial we don't
>> + * need to update anything.
>> + */
>> + if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
>> + return;
>> +
>> + skb->ip_summed = CHECKSUM_PARTIAL;
>> + skb->csum_start = skb_transport_header(skb) - skb->head;
>> + skb->csum_offset = offsetof(struct tcphdr, check);
>> +
>> + if (skb->sk->sk_family == AF_INET6) {
>> + ipv6h = ipv6_hdr(skb);
>> + th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
>> + datalen, IPPROTO_TCP, 0);
>> + } else {
>> + iph = ip_hdr(skb);
>> + th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, datalen,
>> + IPPROTO_TCP, 0);
>> + }
>> +}
>> +
>> +static void complete_skb(struct sk_buff *nskb, struct sk_buff *skb, int headln)
>> +{
>> + skb_copy_header(nskb, skb);
>> +
>> + skb_put(nskb, skb->len);
>> + memcpy(nskb->data, skb->data, headln);
>> + update_chksum(nskb, headln);
>> +
>> + nskb->destructor = skb->destructor;
>> + nskb->sk = skb->sk;
>> + skb->destructor = NULL;
>> + skb->sk = NULL;
>> + refcount_add(nskb->truesize - skb->truesize,
>> + &nskb->sk->sk_wmem_alloc);
>> +}
>> +
>> +/* This function may be called after the user socket is already
>> + * closed so make sure we don't use anything freed during
>> + * tls_sk_proto_close here
>> + */
>> +
>> +static int fill_sg_in(struct scatterlist *sg_in,
>> + struct sk_buff *skb,
>> + struct tls_offload_context *ctx,
>> + u64 *rcd_sn,
>> + s32 *sync_size,
>> + int *resync_sgs)
>> +{
>> + int tcp_payload_offset = skb_transport_offset(skb) + tcp_hdrlen(skb);
>> + int payload_len = skb->len - tcp_payload_offset;
>> + u32 tcp_seq = ntohl(tcp_hdr(skb)->seq);
>> + struct tls_record_info *record;
>> + unsigned long flags;
>> + int remaining;
>> + int i;
>> +
>> + spin_lock_irqsave(&ctx->lock, flags);
>> + record = tls_get_record(ctx, tcp_seq, rcd_sn);
>> + if (!record) {
>> + spin_unlock_irqrestore(&ctx->lock, flags);
>> + WARN(1, "Record not found for seq %u\n", tcp_seq);
>> + return -EINVAL;
>> + }
>> +
>> + *sync_size = tcp_seq - tls_record_start_seq(record);
>> + if (*sync_size < 0) {
>> + int is_start_marker = tls_record_is_start_marker(record);
>> +
>> + spin_unlock_irqrestore(&ctx->lock, flags);
>> + /* This should only occur if the relevant record was
>> + * already acked. In that case it should be ok
>> + * to drop the packet and avoid retransmission.
>> + *
>> + * There is a corner case where the packet contains
>> + * both an acked and a non-acked record.
>> + * We currently don't handle that case and rely
>> + * on TCP to retranmit a packet that doesn't contain
>> + * already acked payload.
>> + */
>> + if (!is_start_marker) {
>> + *sync_size = 0;
>> + }
>> + pr_err("err_sync %d\n", *sync_size);
>> + return -EINVAL;
>> + }
>> +
>> + remaining = *sync_size;
>> + for (i = 0; remaining > 0; i++) {
>> + skb_frag_t *frag = &record->frags[i];
>> +
>> + __skb_frag_ref(frag);
>> + sg_set_page(sg_in + i, skb_frag_page(frag),
>> + skb_frag_size(frag), frag->page_offset);
>> +
>> + remaining -= skb_frag_size(frag);
>> +
>> + if (remaining < 0)
>> + sg_in[i].length += remaining;
>> + }
>> + *resync_sgs = i;
>> +
>> + spin_unlock_irqrestore(&ctx->lock, flags);
>> + if (skb_to_sgvec(skb, &sg_in[i], tcp_payload_offset, payload_len) < 0)
>> + return -EINVAL;
>> +
>> + return 0;
>> +}
>> +
>> +static void fill_sg_out(struct scatterlist sg_out[3], void *buf,
>> + struct tls_context *tls_ctx,
>> + struct sk_buff *nskb,
>> + int tcp_payload_offset,
>> + int payload_len,
>> + int sync_size,
>> + void *dummy_buf)
>> +{
>> +
>> +
>> + sg_set_buf(&sg_out[0], dummy_buf, sync_size);
>> + sg_set_buf(&sg_out[1], nskb->data + tcp_payload_offset, payload_len);
>> + /* Add room for authentication tag produced by crypto */
>> + dummy_buf += sync_size;
>> + sg_set_buf(&sg_out[2], dummy_buf, TLS_CIPHER_AES_GCM_128_TAG_SIZE);
>> +}
>> +
>> +static struct sk_buff *tls_enc_skb(struct tls_context *tls_ctx,
>> + struct scatterlist sg_out[3],
>> + struct scatterlist *sg_in,
>> + struct sk_buff *skb,
>> + s32 sync_size, u64 rcd_sn)
>> +{
>> + int tcp_payload_offset = skb_transport_offset(skb) + tcp_hdrlen(skb);
>> + struct tls_offload_context *ctx = tls_offload_ctx(tls_ctx);
>> + int payload_len = skb->len - tcp_payload_offset;
>> + void *buf, *iv, *aad, *dummy_buf;
>> + struct aead_request *aead_req;
>> + struct sk_buff *nskb = NULL;
>> + int buf_len;
>> +
>> + aead_req = tls_alloc_aead_request(ctx->aead_send, GFP_ATOMIC);
>> + if (!aead_req)
>> + return NULL;
>> +
>> + buf_len = TLS_CIPHER_AES_GCM_128_SALT_SIZE +
>> + TLS_CIPHER_AES_GCM_128_IV_SIZE +
>> + TLS_AAD_SPACE_SIZE +
>> + sync_size +
>> + TLS_CIPHER_AES_GCM_128_TAG_SIZE;
>> + buf = kmalloc(buf_len, GFP_ATOMIC);
>> + if (!buf)
>> + goto free_req;
>> +
>> + iv = buf;
>> + memcpy(iv, tls_ctx->crypto_send_aes_gcm_128.salt,
>> + TLS_CIPHER_AES_GCM_128_SALT_SIZE);
>> + aad = buf + TLS_CIPHER_AES_GCM_128_SALT_SIZE +
>> + TLS_CIPHER_AES_GCM_128_IV_SIZE;
>> + dummy_buf = aad + TLS_AAD_SPACE_SIZE;
>> +
>> + nskb = alloc_skb(skb_headroom(skb) + skb->len, GFP_ATOMIC);
>> + if (!nskb)
>> + goto free_buf;
>> +
>> + skb_reserve(nskb, skb_headroom(skb));
>> +
>> + fill_sg_out(sg_out, buf, tls_ctx, nskb, tcp_payload_offset,
>> + payload_len, sync_size, dummy_buf);
>> +
>> + if (tls_enc_records(aead_req, ctx->aead_send, sg_in, sg_out, aad, iv,
>> + rcd_sn, sync_size + payload_len) < 0)
>> + goto free_nskb;
>> +
>> + complete_skb(nskb, skb, tcp_payload_offset);
>> +
>> + /* validate_xmit_skb_list assumes that if the skb wasn't segmented
>> + * nskb->prev will point to the skb itself
>> + */
>> + nskb->prev = nskb;
>> +
>> +free_buf:
>> + kfree(buf);
>> +free_req:
>> + kfree(aead_req);
>> + return nskb;
>> +free_nskb:
>> + kfree_skb(nskb);
>> + nskb = NULL;
>> + goto free_buf;
>> +}
>> +
>> +static struct sk_buff *tls_sw_fallback(struct sock *sk, struct sk_buff *skb)
>> +{
>> + int tcp_payload_offset = skb_transport_offset(skb) + tcp_hdrlen(skb);
>> + struct tls_context *tls_ctx = tls_get_ctx(sk);
>> + struct tls_offload_context *ctx = tls_offload_ctx(tls_ctx);
>> + int payload_len = skb->len - tcp_payload_offset;
>> + struct scatterlist *sg_in, sg_out[3];
>> + struct sk_buff *nskb = NULL;
>> + int sg_in_max_elements;
>> + int resync_sgs = 0;
>> + s32 sync_size = 0;
>> + u64 rcd_sn;
>> +
>> + /* worst case is:
>> + * MAX_SKB_FRAGS in tls_record_info
>> + * MAX_SKB_FRAGS + 1 in SKB head and frags.
>> + */
>> + sg_in_max_elements = 2 * MAX_SKB_FRAGS + 1;
>> +
>> + if (!payload_len)
>> + return skb;
>> +
>> + sg_in = kmalloc_array(sg_in_max_elements, sizeof(*sg_in), GFP_ATOMIC);
>> + if (!sg_in)
>> + goto free_orig;
>> +
>> + sg_init_table(sg_in, sg_in_max_elements);
>> + sg_init_table(sg_out, ARRAY_SIZE(sg_out));
>> +
>> + if (fill_sg_in(sg_in, skb, ctx, &rcd_sn, &sync_size, &resync_sgs)) {
>> + /* bypass packets before kernel TLS socket option was set */
>> + if (sync_size < 0 && payload_len <= -sync_size)
>> + nskb = skb_get(skb);
>> + goto put_sg;
>> + }
>> +
>> + nskb = tls_enc_skb(tls_ctx, sg_out, sg_in, skb, sync_size, rcd_sn);
>> +
>> +put_sg:
>> + while (resync_sgs)
>> + put_page(sg_page(&sg_in[--resync_sgs]));
>> + kfree(sg_in);
>> +free_orig:
>> + kfree_skb(skb);
>> + return nskb;
>> +}
>> +
>> +struct sk_buff *tls_validate_xmit_skb(struct sock *sk,
>> + struct net_device *dev,
>> + struct sk_buff *skb)
>> +{
>> + if (dev == tls_get_ctx(sk)->netdev)
>> + return skb;
>> +
>> + return tls_sw_fallback(sk, skb);
>> +}
>> +
>> +int tls_sw_fallback_init(struct sock *sk,
>> + struct tls_offload_context *offload_ctx,
>> + struct tls_crypto_info *crypto_info)
>> +{
>> + const u8 *key;
>> + int rc;
>> +
>> + offload_ctx->aead_send =
>> + crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
>> + if (IS_ERR(offload_ctx->aead_send)) {
>> + rc = PTR_ERR(offload_ctx->aead_send);
>> + pr_err_ratelimited("crypto_alloc_aead failed rc=%d\n", rc);
>> + offload_ctx->aead_send = NULL;
>> + goto err_out;
>> + }
>> +
>> + key = ((struct tls12_crypto_info_aes_gcm_128 *)crypto_info)->key;
>> +
>> + rc = crypto_aead_setkey(offload_ctx->aead_send, key,
>> + TLS_CIPHER_AES_GCM_128_KEY_SIZE);
>> + if (rc)
>> + goto free_aead;
>> +
>> + rc = crypto_aead_setauthsize(offload_ctx->aead_send,
>> + TLS_CIPHER_AES_GCM_128_TAG_SIZE);
>> + if (rc)
>> + goto free_aead;
>> +
>> + return 0;
>> +free_aead:
>> + crypto_free_aead(offload_ctx->aead_send);
>> +err_out:
>> + return rc;
>> +}
>> diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
>> index 6f5c1146da4a..47ed1b72b3ca 100644
>> --- a/net/tls/tls_main.c
>> +++ b/net/tls/tls_main.c
>> @@ -50,25 +50,25 @@ enum {
>> TLSV6,
>> TLS_NUM_PROTS,
>> };
>> -
>> enum {
>> TLS_BASE,
>> - TLS_SW_TX,
>> - TLS_SW_RX,
>> - TLS_SW_RXTX,
>> + TLS_SW,
>> +#ifdef CONFIG_TLS_DEVICE
>> + TLS_HW,
>> +#endif
>> TLS_NUM_CONFIG,
>> };
>>
>> static struct proto *saved_tcpv6_prot;
>> static DEFINE_MUTEX(tcpv6_prot_mutex);
>> -static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG];
>> +static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG];
>> static struct proto_ops tls_sw_proto_ops;
>>
>> -static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
>> +static void update_sk_prot(struct sock *sk, struct tls_context *ctx)
>
> All cleanups have to go in separate patches.
>
>> {
>> int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
>>
>> - sk->sk_prot = &tls_prots[ip_ver][ctx->conf];
>> + sk->sk_prot = &tls_prots[ip_ver][ctx->tx_conf][ctx->rx_conf];
>> }
>>
>> int wait_on_pending_writer(struct sock *sk, long *timeo)
>> @@ -241,7 +241,7 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
>> lock_sock(sk);
>> sk_proto_close = ctx->sk_proto_close;
>>
>> - if (ctx->conf == TLS_BASE) {
>> + if (ctx->tx_conf == TLS_BASE && ctx->rx_conf == TLS_BASE) {
>> kfree(ctx);
>> goto skip_tx_cleanup;
>> }
>> @@ -262,17 +262,25 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
>> }
>> }
>>
>> - kfree(ctx->tx.rec_seq);
>> - kfree(ctx->tx.iv);
>> - kfree(ctx->rx.rec_seq);
>> - kfree(ctx->rx.iv);
>> + /* We need these for tls_sw_fallback handling of other packets */
>> + if (ctx->tx_conf == TLS_SW) {
>> + kfree(ctx->tx.rec_seq);
>> + kfree(ctx->tx.iv);
>> + tls_sw_free_resources_tx(sk);
>> + }
>>
>> - if (ctx->conf == TLS_SW_TX ||
>> - ctx->conf == TLS_SW_RX ||
>> - ctx->conf == TLS_SW_RXTX) {
>> - tls_sw_free_resources(sk);
>> + if (ctx->rx_conf == TLS_SW) {
>> + kfree(ctx->rx.rec_seq);
>> + kfree(ctx->rx.iv);
>> + tls_sw_free_resources_rx(sk);
>> }
>>
>> +#ifdef CONFIG_TLS_DEVICE
>> + if (ctx->tx_conf != TLS_HW)
>> +#endif
>> + kfree(ctx);
>> +
>> +
>> skip_tx_cleanup:
>> release_sock(sk);
>> sk_proto_close(sk, timeout);
>> @@ -428,25 +436,29 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
>> goto err_crypto_info;
>> }
>>
>> - /* currently SW is default, we will have ethtool in future */
>> if (tx) {
>> - rc = tls_set_sw_offload(sk, ctx, 1);
>> - if (ctx->conf == TLS_SW_RX)
>> - conf = TLS_SW_RXTX;
>> - else
>> - conf = TLS_SW_TX;
>> +#ifdef CONFIG_TLS_DEVICE
>> + rc = tls_set_device_offload(sk, ctx);
>> + conf = TLS_HW;
>> + if (rc) {
>> +#else
>> + {
>> +#endif
>> + rc = tls_set_sw_offload(sk, ctx, 1);
>> + conf = TLS_SW;
>> + }
>> } else {
>> rc = tls_set_sw_offload(sk, ctx, 0);
>> - if (ctx->conf == TLS_SW_TX)
>> - conf = TLS_SW_RXTX;
>> - else
>> - conf = TLS_SW_RX;
>> + conf = TLS_SW;
>> }
>>
>> if (rc)
>> goto err_crypto_info;
>>
>> - ctx->conf = conf;
>> + if (tx)
>> + ctx->tx_conf = conf;
>> + else
>> + ctx->rx_conf = conf;
>> update_sk_prot(sk, ctx);
>> if (tx) {
>> ctx->sk_write_space = sk->sk_write_space;
>> @@ -493,24 +505,35 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
>> return do_tls_setsockopt(sk, optname, optval, optlen);
>> }
>>
>> -static void build_protos(struct proto *prot, struct proto *base)
>> +static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
>> + struct proto *base)
>> {
>> - prot[TLS_BASE] = *base;
>> - prot[TLS_BASE].setsockopt = tls_setsockopt;
>> - prot[TLS_BASE].getsockopt = tls_getsockopt;
>> - prot[TLS_BASE].close = tls_sk_proto_close;
>> -
>> - prot[TLS_SW_TX] = prot[TLS_BASE];
>> - prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
>> - prot[TLS_SW_TX].sendpage = tls_sw_sendpage;
>> -
>> - prot[TLS_SW_RX] = prot[TLS_BASE];
>> - prot[TLS_SW_RX].recvmsg = tls_sw_recvmsg;
>> - prot[TLS_SW_RX].close = tls_sk_proto_close;
>> -
>> - prot[TLS_SW_RXTX] = prot[TLS_SW_TX];
>> - prot[TLS_SW_RXTX].recvmsg = tls_sw_recvmsg;
>> - prot[TLS_SW_RXTX].close = tls_sk_proto_close;
>> + prot[TLS_BASE][TLS_BASE] = *base;
>> + prot[TLS_BASE][TLS_BASE].setsockopt = tls_setsockopt;
>> + prot[TLS_BASE][TLS_BASE].getsockopt = tls_getsockopt;
>> + prot[TLS_BASE][TLS_BASE].close = tls_sk_proto_close;
>> +
>> + prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE];
>> + prot[TLS_SW][TLS_BASE].sendmsg = tls_sw_sendmsg;
>> + prot[TLS_SW][TLS_BASE].sendpage = tls_sw_sendpage;
>> +
>> + prot[TLS_BASE][TLS_SW] = prot[TLS_BASE][TLS_BASE];
>> + prot[TLS_BASE][TLS_SW].recvmsg = tls_sw_recvmsg;
>> + prot[TLS_BASE][TLS_SW].close = tls_sk_proto_close;
>> +
>> + prot[TLS_SW][TLS_SW] = prot[TLS_SW][TLS_BASE];
>> + prot[TLS_SW][TLS_SW].recvmsg = tls_sw_recvmsg;
>> + prot[TLS_SW][TLS_SW].close = tls_sk_proto_close;
>> +
>> +#ifdef CONFIG_TLS_DEVICE
>> + prot[TLS_HW][TLS_BASE] = prot[TLS_BASE][TLS_BASE];
>> + prot[TLS_HW][TLS_BASE].sendmsg = tls_device_sendmsg;
>> + prot[TLS_HW][TLS_BASE].sendpage = tls_device_sendpage;
>> +
>> + prot[TLS_HW][TLS_SW] = prot[TLS_BASE][TLS_SW];
>> + prot[TLS_HW][TLS_SW].sendmsg = tls_device_sendmsg;
>> + prot[TLS_HW][TLS_SW].sendpage = tls_device_sendpage;
>> +#endif
>> }
>>
>> static int tls_init(struct sock *sk)
>> @@ -551,7 +574,8 @@ static int tls_init(struct sock *sk)
>> mutex_unlock(&tcpv6_prot_mutex);
>> }
>>
>> - ctx->conf = TLS_BASE;
>> + ctx->tx_conf = TLS_BASE;
>> + ctx->rx_conf = TLS_BASE;
>> update_sk_prot(sk, ctx);
>> out:
>> return rc;
>> @@ -573,6 +597,9 @@ static int __init tls_register(void)
>> tls_sw_proto_ops.poll = tls_sw_poll;
>> tls_sw_proto_ops.splice_read = tls_sw_splice_read;
>>
>> +#ifdef CONFIG_TLS_DEVICE
>> + tls_device_init();
>> +#endif
>> tcp_register_ulp(&tcp_tls_ulp_ops);
>>
>> return 0;
>> @@ -581,6 +608,9 @@ static int __init tls_register(void)
>> static void __exit tls_unregister(void)
>> {
>> tcp_unregister_ulp(&tcp_tls_ulp_ops);
>> +#ifdef CONFIG_TLS_DEVICE
>> + tls_device_cleanup();
>> +#endif
>> }
>>
>> module_init(tls_register);
>> diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
>> index 4dc766b03f00..498b86ab850a 100644
>> --- a/net/tls/tls_sw.c
>> +++ b/net/tls/tls_sw.c
>> @@ -50,7 +50,7 @@ static int tls_do_decryption(struct sock *sk,
>> gfp_t flags)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> struct strp_msg *rxm = strp_msg(skb);
>> struct aead_request *aead_req;
>>
>> @@ -120,7 +120,7 @@ static void trim_sg(struct sock *sk, struct scatterlist *sg,
>> static void trim_both_sgl(struct sock *sk, int target_size)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>>
>> trim_sg(sk, ctx->sg_plaintext_data,
>> &ctx->sg_plaintext_num_elem,
>> @@ -139,7 +139,7 @@ static void trim_both_sgl(struct sock *sk, int target_size)
>> static int alloc_encrypted_sg(struct sock *sk, int len)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>> int rc = 0;
>>
>> rc = sk_alloc_sg(sk, len,
>> @@ -153,7 +153,7 @@ static int alloc_encrypted_sg(struct sock *sk, int len)
>> static int alloc_plaintext_sg(struct sock *sk, int len)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>> int rc = 0;
>>
>> rc = sk_alloc_sg(sk, len, ctx->sg_plaintext_data, 0,
>> @@ -179,7 +179,7 @@ static void free_sg(struct sock *sk, struct scatterlist *sg,
>> static void tls_free_both_sg(struct sock *sk)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>>
>> free_sg(sk, ctx->sg_encrypted_data, &ctx->sg_encrypted_num_elem,
>> &ctx->sg_encrypted_size);
>> @@ -189,7 +189,7 @@ static void tls_free_both_sg(struct sock *sk)
>> }
>>
>> static int tls_do_encryption(struct tls_context *tls_ctx,
>> - struct tls_sw_context *ctx, size_t data_len,
>> + struct tls_sw_context_tx *ctx, size_t data_len,
>> gfp_t flags)
>> {
>> unsigned int req_size = sizeof(struct aead_request) +
>> @@ -225,7 +225,7 @@ static int tls_push_record(struct sock *sk, int flags,
>> unsigned char record_type)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>> int rc;
>>
>> sg_mark_end(ctx->sg_plaintext_data + ctx->sg_plaintext_num_elem - 1);
>> @@ -337,7 +337,7 @@ static int memcopy_from_iter(struct sock *sk, struct iov_iter *from,
>> int bytes)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>> struct scatterlist *sg = ctx->sg_plaintext_data;
>> int copy, i, rc = 0;
>>
>> @@ -365,7 +365,7 @@ static int memcopy_from_iter(struct sock *sk, struct iov_iter *from,
>> int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>> int ret = 0;
>> int required_size;
>> long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
>> @@ -520,7 +520,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page,
>> int offset, size_t size, int flags)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>> int ret = 0;
>> long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
>> bool eor;
>> @@ -634,7 +634,7 @@ static struct sk_buff *tls_wait_data(struct sock *sk, int flags,
>> long timeo, int *err)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> struct sk_buff *skb;
>> DEFINE_WAIT_FUNC(wait, woken_wake_function);
>>
>> @@ -672,7 +672,7 @@ static int decrypt_skb(struct sock *sk, struct sk_buff *skb,
>> struct scatterlist *sgout)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + tls_ctx->rx.iv_size];
>> struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
>> struct scatterlist *sgin = &sgin_arr[0];
>> @@ -722,7 +722,7 @@ static bool tls_sw_advance_skb(struct sock *sk, struct sk_buff *skb,
>> unsigned int len)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> struct strp_msg *rxm = strp_msg(skb);
>>
>> if (len < rxm->full_len) {
>> @@ -748,7 +748,7 @@ int tls_sw_recvmsg(struct sock *sk,
>> int *addr_len)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> unsigned char control;
>> struct strp_msg *rxm;
>> struct sk_buff *skb;
>> @@ -868,7 +868,7 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
>> size_t len, unsigned int flags)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sock->sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> struct strp_msg *rxm = NULL;
>> struct sock *sk = sock->sk;
>> struct sk_buff *skb;
>> @@ -921,7 +921,7 @@ unsigned int tls_sw_poll(struct file *file, struct socket *sock,
>> unsigned int ret;
>> struct sock *sk = sock->sk;
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>>
>> /* Grab POLLOUT and POLLHUP from the underlying socket */
>> ret = ctx->sk_poll(file, sock, wait);
>> @@ -937,7 +937,7 @@ unsigned int tls_sw_poll(struct file *file, struct socket *sock,
>> static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(strp->sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> char header[tls_ctx->rx.prepend_size];
>> struct strp_msg *rxm = strp_msg(skb);
>> size_t cipher_overhead;
>> @@ -986,7 +986,7 @@ static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
>> static void tls_queue(struct strparser *strp, struct sk_buff *skb)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(strp->sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>
> This is still splitting.
>
>> struct strp_msg *rxm;
>>
>> rxm = strp_msg(skb);
>> @@ -1002,18 +1002,28 @@ static void tls_queue(struct strparser *strp, struct sk_buff *skb)
>> static void tls_data_ready(struct sock *sk)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>
> And this.
>
See comment above.
>> strp_data_ready(&ctx->strp);
>> }
>>
>> -void tls_sw_free_resources(struct sock *sk)
>> +void tls_sw_free_resources_tx(struct sock *sk)
>> {
>> struct tls_context *tls_ctx = tls_get_ctx(sk);
>> - struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
>> + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
>>
>> if (ctx->aead_send)
>> crypto_free_aead(ctx->aead_send);
>> + tls_free_both_sg(sk);
>> +
>> + kfree(ctx);
>> +}
>> +
>> +void tls_sw_free_resources_rx(struct sock *sk)
>> +{
>> + struct tls_context *tls_ctx = tls_get_ctx(sk);
>> + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
>> +
>> if (ctx->aead_recv) {
>> if (ctx->recv_pkt) {
>> kfree_skb(ctx->recv_pkt);
>> @@ -1029,10 +1039,7 @@ void tls_sw_free_resources(struct sock *sk)
>> lock_sock(sk);
>> }
>>
>> - tls_free_both_sg(sk);
>> -
>> kfree(ctx);
>> - kfree(tls_ctx);
>> }
>>
>> int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
>> @@ -1040,7 +1047,8 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
>> char keyval[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
>> struct tls_crypto_info *crypto_info;
>> struct tls12_crypto_info_aes_gcm_128 *gcm_128_info;
>> - struct tls_sw_context *sw_ctx;
>> + struct tls_sw_context_tx *sw_ctx_tx;
>> + struct tls_sw_context_rx *sw_ctx_rx;
>> struct cipher_context *cctx;
>> struct crypto_aead **aead;
>> struct strp_callbacks cb;
>> @@ -1053,27 +1061,33 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
>> goto out;
>> }
>>
>> - if (!ctx->priv_ctx) {
>> - sw_ctx = kzalloc(sizeof(*sw_ctx), GFP_KERNEL);
>> - if (!sw_ctx) {
>> + if (tx) {
>> + sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL);
>> + if (!sw_ctx_tx) {
>> rc = -ENOMEM;
>> goto out;
>> }
>> - crypto_init_wait(&sw_ctx->async_wait);
>> + crypto_init_wait(&sw_ctx_tx->async_wait);
>> + ctx->priv_ctx_tx = sw_ctx_tx;
>> } else {
>> - sw_ctx = ctx->priv_ctx;
>> + sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL);
>> + if (!sw_ctx_rx) {
>> + rc = -ENOMEM;
>> + goto out;
>> + }
>> + crypto_init_wait(&sw_ctx_rx->async_wait);
>> + ctx->priv_ctx_rx = sw_ctx_rx;
>> }
>>
>> - ctx->priv_ctx = (struct tls_offload_context *)sw_ctx;
>>
>> if (tx) {
>> crypto_info = &ctx->crypto_send;
>> cctx = &ctx->tx;
>> - aead = &sw_ctx->aead_send;
>> + aead = &sw_ctx_tx->aead_send;
>> } else {
>> crypto_info = &ctx->crypto_recv;
>> cctx = &ctx->rx;
>> - aead = &sw_ctx->aead_recv;
>> + aead = &sw_ctx_rx->aead_recv;
>> }
>>
>> switch (crypto_info->cipher_type) {
>> @@ -1115,21 +1129,22 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
>> memcpy(cctx->rec_seq, rec_seq, rec_seq_size);
>>
>> if (tx) {
>> - sg_init_table(sw_ctx->sg_encrypted_data,
>> - ARRAY_SIZE(sw_ctx->sg_encrypted_data));
>> - sg_init_table(sw_ctx->sg_plaintext_data,
>> - ARRAY_SIZE(sw_ctx->sg_plaintext_data));
>> -
>> - sg_init_table(sw_ctx->sg_aead_in, 2);
>> - sg_set_buf(&sw_ctx->sg_aead_in[0], sw_ctx->aad_space,
>> - sizeof(sw_ctx->aad_space));
>> - sg_unmark_end(&sw_ctx->sg_aead_in[1]);
>> - sg_chain(sw_ctx->sg_aead_in, 2, sw_ctx->sg_plaintext_data);
>> - sg_init_table(sw_ctx->sg_aead_out, 2);
>> - sg_set_buf(&sw_ctx->sg_aead_out[0], sw_ctx->aad_space,
>> - sizeof(sw_ctx->aad_space));
>> - sg_unmark_end(&sw_ctx->sg_aead_out[1]);
>> - sg_chain(sw_ctx->sg_aead_out, 2, sw_ctx->sg_encrypted_data);
>> + sg_init_table(sw_ctx_tx->sg_encrypted_data,
>> + ARRAY_SIZE(sw_ctx_tx->sg_encrypted_data));
>> + sg_init_table(sw_ctx_tx->sg_plaintext_data,
>> + ARRAY_SIZE(sw_ctx_tx->sg_plaintext_data));
>> +
>> + sg_init_table(sw_ctx_tx->sg_aead_in, 2);
>> + sg_set_buf(&sw_ctx_tx->sg_aead_in[0], sw_ctx_tx->aad_space,
>> + sizeof(sw_ctx_tx->aad_space));
>> + sg_unmark_end(&sw_ctx_tx->sg_aead_in[1]);
>> + sg_chain(sw_ctx_tx->sg_aead_in, 2, sw_ctx_tx->sg_plaintext_data);
>> + sg_init_table(sw_ctx_tx->sg_aead_out, 2);
>> + sg_set_buf(&sw_ctx_tx->sg_aead_out[0], sw_ctx_tx->aad_space,
>> + sizeof(sw_ctx_tx->aad_space));
>> + sg_unmark_end(&sw_ctx_tx->sg_aead_out[1]);
>> + sg_chain(sw_ctx_tx->sg_aead_out, 2,
>> + sw_ctx_tx->sg_encrypted_data);
>> }
>>
>> if (!*aead) {
>> @@ -1160,16 +1175,16 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
>> cb.rcv_msg = tls_queue;
>> cb.parse_msg = tls_read_size;
>>
>> - strp_init(&sw_ctx->strp, sk, &cb);
>> + strp_init(&sw_ctx_rx->strp, sk, &cb);
>>
>> write_lock_bh(&sk->sk_callback_lock);
>> - sw_ctx->saved_data_ready = sk->sk_data_ready;
>> + sw_ctx_rx->saved_data_ready = sk->sk_data_ready;
>> sk->sk_data_ready = tls_data_ready;
>> write_unlock_bh(&sk->sk_callback_lock);
>>
>> - sw_ctx->sk_poll = sk->sk_socket->ops->poll;
>> + sw_ctx_rx->sk_poll = sk->sk_socket->ops->poll;
>>
>> - strp_check_rcv(&sw_ctx->strp);
>> + strp_check_rcv(&sw_ctx_rx->strp);
>> }
>>
>> goto out;
>> @@ -1181,11 +1196,16 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
>> kfree(cctx->rec_seq);
>> cctx->rec_seq = NULL;
>> free_iv:
>> - kfree(ctx->tx.iv);
>> - ctx->tx.iv = NULL;
>> + kfree(cctx->iv);
>> + cctx->iv = NULL;
>> free_priv:
>> - kfree(ctx->priv_ctx);
>> - ctx->priv_ctx = NULL;
>> + if (tx) {
>> + kfree(ctx->priv_ctx_tx);
>> + ctx->priv_ctx_tx = NULL;
>> + } else {
>> + kfree(ctx->priv_ctx_rx);
>> + ctx->priv_ctx_rx = NULL;
>> + }
>> out:
>> return rc;
>> }
>>
>
> ./scripts/checkpatch.pl c.diff
> WARNING: prefer 'help' over '---help---' for new help texts
> #198: FILE: net/tls/Kconfig:18:
> +config TLS_DEVICE
>
> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
> #218:
> new file mode 100644
>
> WARNING: Missing or malformed SPDX-License-Identifier tag in line 1
> #223: FILE: net/tls/tls_device.c:1:
> +/* Copyright (c) 2018, Mellanox Technologies All rights reserved.
>
> CHECK: Alignment should match open parenthesis
> #576: FILE: net/tls/tls_device.c:354:
> + rc = tls_do_allocation(sk, ctx, pfrag,
> + tls_ctx->tx.prepend_size);
>
> CHECK: Alignment should match open parenthesis
> #793: FILE: net/tls/tls_device.c:571:
> + ctx->tx.iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
> + GFP_KERNEL);
>
> WARNING: 'preceed' may be misspelled - perhaps 'precede'?
> #841: FILE: net/tls/tls_device.c:619:
> + * This lock must preceed get_netdev_for_sock to prevent races between
>
> WARNING: Missing or malformed SPDX-License-Identifier tag in line 1
> #988: FILE: net/tls/tls_device_fallback.c:1:
> +/* Copyright (c) 2018, Mellanox Technologies All rights reserved.
>
> WARNING: braces {} are not necessary for single statement blocks
> #1240: FILE: net/tls/tls_device_fallback.c:253:
> + if (!is_start_marker) {
> + *sync_size = 0;
> + }
>
> CHECK: Blank lines aren't necessary after an open brace '{'
> #1277: FILE: net/tls/tls_device_fallback.c:290:
> +{
> +
>
> CHECK: Please don't use multiple blank lines
> #1278: FILE: net/tls/tls_device_fallback.c:291:
> +
> +
>
> CHECK: Alignment should match open parenthesis
> #1330: FILE: net/tls/tls_device_fallback.c:343:
> + if (tls_enc_records(aead_req, ctx->aead_send, sg_in, sg_out, aad, iv,
> + rcd_sn, sync_size + payload_len) < 0)
>
> CHECK: Please don't use multiple blank lines
> #1518: FILE: net/tls/tls_main.c:283:
> +
> +
>
> WARNING: line over 80 characters
> #1935: FILE: net/tls/tls_sw.c:1141:
> + sg_chain(sw_ctx_tx->sg_aead_in, 2, sw_ctx_tx->sg_plaintext_data);
>
> total: 0 errors, 7 warnings, 6 checks, 1912 lines checked
>
> NOTE: For some of the reported defects, checkpatch may be able to
> mechanically convert to the typical style using --fix or --fix-inplace.
>
> c.diff has style problems, please review.
>
^ permalink raw reply
* Re: [PATCH v3 2/2] net: usb: asix88179_178a: de-duplicate code
From: Marc Zyngier @ 2018-04-02 9:45 UTC (permalink / raw)
To: Alexander Kurz
Cc: David S . Miller, Andrew F . Davis, linux-usb, netdev, Freddy Xin
In-Reply-To: <20180402074349.12010-2-akurz@blala.de>
On Mon, 02 Apr 2018 08:43:49 +0100,
Alexander Kurz wrote:
Alexander,
>
> Remove the duplicated code for asix88179_178a bind and reset methods.
>
> Signed-off-by: Alexander Kurz <akurz@blala.de>
> ---
> drivers/net/usb/ax88179_178a.c | 137 ++++++++++-------------------------------
> 1 file changed, 31 insertions(+), 106 deletions(-)
What has changed between this patch and the previous one? Having a bit
of a change-log would certainly help. Also, I would have appreciated a
reply to the questions I had on v2 before you posted a third version.
>
> diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
> index a6ef75907ae9..fea4c7b877cc 100644
> --- a/drivers/net/usb/ax88179_178a.c
> +++ b/drivers/net/usb/ax88179_178a.c
> @@ -1223,7 +1223,7 @@ static int ax88179_led_setting(struct usbnet *dev)
> return 0;
> }
>
> -static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
> +static int ax88179_bind_or_reset(struct usbnet *dev, bool do_reset)
> {
> u8 buf[5];
> u16 *tmp16;
> @@ -1231,12 +1231,11 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
> struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
> struct ethtool_eee eee_data;
>
> - usbnet_get_endpoints(dev, intf);
> -
> tmp16 = (u16 *)buf;
> tmp = (u8 *)buf;
>
> - memset(ax179_data, 0, sizeof(*ax179_data));
> + if (!do_reset)
> + memset(ax179_data, 0, sizeof(*ax179_data));
>
> /* Power up ethernet PHY */
> *tmp16 = 0;
> @@ -1249,9 +1248,13 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
> ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
> msleep(100);
>
> + if (do_reset)
> + ax88179_auto_detach(dev, 0);
> +
> ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
> ETH_ALEN, dev->net->dev_addr);
> - memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
> + if (!do_reset)
> + memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
>
> /* RX bulk configuration */
> memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
> @@ -1266,19 +1269,21 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
> ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
> 1, 1, tmp);
>
> - dev->net->netdev_ops = &ax88179_netdev_ops;
> - dev->net->ethtool_ops = &ax88179_ethtool_ops;
> - dev->net->needed_headroom = 8;
> - dev->net->max_mtu = 4088;
> -
> - /* Initialize MII structure */
> - dev->mii.dev = dev->net;
> - dev->mii.mdio_read = ax88179_mdio_read;
> - dev->mii.mdio_write = ax88179_mdio_write;
> - dev->mii.phy_id_mask = 0xff;
> - dev->mii.reg_num_mask = 0xff;
> - dev->mii.phy_id = 0x03;
> - dev->mii.supports_gmii = 1;
> + if (!do_reset) {
> + dev->net->netdev_ops = &ax88179_netdev_ops;
> + dev->net->ethtool_ops = &ax88179_ethtool_ops;
> + dev->net->needed_headroom = 8;
> + dev->net->max_mtu = 4088;
> +
> + /* Initialize MII structure */
> + dev->mii.dev = dev->net;
> + dev->mii.mdio_read = ax88179_mdio_read;
> + dev->mii.mdio_write = ax88179_mdio_write;
> + dev->mii.phy_id_mask = 0xff;
> + dev->mii.reg_num_mask = 0xff;
> + dev->mii.phy_id = 0x03;
> + dev->mii.supports_gmii = 1;
> + }
>
> dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> NETIF_F_RXCSUM;
> @@ -1330,6 +1335,13 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
> return 0;
> }
>
> +static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
> +{
> + usbnet_get_endpoints(dev, intf);
> +
> + return ax88179_bind_or_reset(dev, false);
> +}
> +
> static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
> {
> u16 tmp16;
> @@ -1530,94 +1542,7 @@ static int ax88179_link_reset(struct usbnet *dev)
>
> static int ax88179_reset(struct usbnet *dev)
> {
> - u8 buf[5];
> - u16 *tmp16;
> - u8 *tmp;
> - struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
> - struct ethtool_eee eee_data;
> -
> - tmp16 = (u16 *)buf;
> - tmp = (u8 *)buf;
> -
> - /* Power up ethernet PHY */
> - *tmp16 = 0;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
> -
> - *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
> - msleep(200);
> -
> - *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
> - msleep(100);
> -
> - /* Ethernet PHY Auto Detach*/
> - ax88179_auto_detach(dev, 0);
> -
> - ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
> - dev->net->dev_addr);
> -
> - /* RX bulk configuration */
> - memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
> -
> - dev->rx_urb_size = 1024 * 20;
> -
> - *tmp = 0x34;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
> -
> - *tmp = 0x52;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
> - 1, 1, tmp);
> -
> - dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> - NETIF_F_RXCSUM;
> -
> - dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> - NETIF_F_RXCSUM;
> -
> - /* Enable checksum offload */
> - *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
> - AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
> -
> - *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
> - AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
> -
> - /* Configure RX control register => start operation */
> - *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
> - AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
> -
> - *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
> - AX_MONITOR_MODE_RWMP;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
> -
> - /* Configure default medium type => giga */
> - *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
> - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
> - AX_MEDIUM_GIGAMODE;
> - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
> - 2, 2, tmp16);
> -
> - ax88179_led_setting(dev);
> -
> - ax179_data->eee_enabled = 0;
> - ax179_data->eee_active = 0;
> -
> - ax88179_disable_eee(dev);
> -
> - ax88179_ethtool_get_eee(dev, &eee_data);
> - eee_data.advertised = 0;
> - ax88179_ethtool_set_eee(dev, &eee_data);
> -
> - /* Restart autoneg */
> - mii_nway_restart(&dev->mii);
> -
> - usbnet_link_change(dev, 0, 0);
> -
> - return 0;
> + return ax88179_bind_or_reset(dev, true);
> }
>
> static int ax88179_stop(struct usbnet *dev)
Overall, this patch makes much more sense than the previous one (I can
actually see duplicated code being removed). I'll give it a go later
today.
Thanks,
M.
--
Jazz is not dead, it just smell funny.
^ permalink raw reply
* KASAN: use-after-free Read in ccid2_hc_tx_packet_recv
From: syzbot @ 2018-04-02 9:20 UTC (permalink / raw)
To: alexey.kodanev, davem, dccp, edumazet, gerrit, keescook,
linux-kernel, netdev, soheil, syzkaller-bugs
Hello,
syzbot hit the following crash on upstream commit
0adb32858b0bddf4ada5f364a84ed60b196dbcda (Sun Apr 1 21:20:27 2018 +0000)
Linux 4.16
syzbot dashboard link:
https://syzkaller.appspot.com/bug?extid=554ccde221001ab5479a
Unfortunately, I don't have any reproducer for this crash yet.
Raw console output:
https://syzkaller.appspot.com/x/log.txt?id=5822430194958336
Kernel config:
https://syzkaller.appspot.com/x/.config?id=-2374466361298166459
compiler: gcc (GCC) 7.1.1 20170620
user-space arch: i386
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+554ccde221001ab5479a@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for
details.
If you forward the report, please keep this part and the footer.
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
dccp_parse_options: DCCP(000000007d56a000): Option 32 (len=7) error=9
==================================================================
dccp_check_seqno: Step 6 failed for RESET packet, (LSWL(279336972291068) <=
P.seqno(279336972291066) <= S.SWH(279336972291142)) and (P.ackno exists or
LAWL(234137106534459) <= P.ackno(234137106534459) <=
S.AWH(234137106534460), sending SYNC...
BUG: KASAN: use-after-free in ccid2_hc_tx_packet_recv+0x234a/0x2440
net/dccp/ccids/ccid2.c:598
Read of size 1 at addr ffff8801bb7a4a82 by task syz-executor1/1660
CPU: 1 PID: 1660 Comm: syz-executor1 Not tainted 4.16.0+ #285
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:17 [inline]
dump_stack+0x194/0x24d lib/dump_stack.c:53
print_address_description+0x73/0x250 mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report+0x23c/0x360 mm/kasan/report.c:412
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:430
ccid2_hc_tx_packet_recv+0x234a/0x2440 net/dccp/ccids/ccid2.c:598
ccid_hc_tx_packet_recv net/dccp/ccid.h:192 [inline]
dccp_deliver_input_to_ccids+0x1d0/0x250 net/dccp/input.c:186
dccp_rcv_established+0x88/0xb0 net/dccp/input.c:378
dccp_v4_do_rcv+0x135/0x160 net/dccp/ipv4.c:653
sk_backlog_rcv include/net/sock.h:908 [inline]
__release_sock+0x124/0x360 net/core/sock.c:2271
release_sock+0xa4/0x2a0 net/core/sock.c:2786
dccp_sendmsg+0x528/0xe60 net/dccp/proto.c:820
inet_sendmsg+0x11f/0x5e0 net/ipv4/af_inet.c:764
sock_sendmsg_nosec net/socket.c:630 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:640
___sys_sendmsg+0x320/0x8b0 net/socket.c:2046
__sys_sendmmsg+0x31b/0x620 net/socket.c:2129
C_SYSC_sendmmsg net/compat.c:745 [inline]
compat_SyS_sendmmsg+0x32/0x40 net/compat.c:742
do_syscall_32_irqs_on arch/x86/entry/common.c:330 [inline]
do_fast_syscall_32+0x3ec/0xf9f arch/x86/entry/common.c:392
entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
RIP: 0023:0xf7f6dc99
RSP: 002b:00000000f5f690ac EFLAGS: 00000282 ORIG_RAX: 0000000000000159
RAX: ffffffffffffffda RBX: 0000000000000013 RCX: 000000002000b880
RDX: 0000000000000122 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
Allocated by task 1660:
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:552
__do_kmalloc_node mm/slab.c:3670 [inline]
__kmalloc_node_track_caller+0x47/0x70 mm/slab.c:3684
__kmalloc_reserve.isra.39+0x41/0xd0 net/core/skbuff.c:137
__alloc_skb+0x13b/0x780 net/core/skbuff.c:205
alloc_skb include/linux/skbuff.h:983 [inline]
dccp_send_ack+0xb6/0x350 net/dccp/output.c:580
ccid2_hc_rx_packet_recv+0x10d/0x180 net/dccp/ccids/ccid2.c:766
ccid_hc_rx_packet_recv net/dccp/ccid.h:185 [inline]
dccp_deliver_input_to_ccids+0xd9/0x250 net/dccp/input.c:180
dccp_rcv_established+0x88/0xb0 net/dccp/input.c:378
dccp_v4_do_rcv+0x135/0x160 net/dccp/ipv4.c:653
sk_backlog_rcv include/net/sock.h:908 [inline]
__sk_receive_skb+0x33e/0xc10 net/core/sock.c:513
dccp_v4_rcv+0xf5f/0x1c80 net/dccp/ipv4.c:874
ip_local_deliver_finish+0x2f1/0xc50 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:288 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:449 [inline]
ip_rcv_finish+0xa36/0x2040 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:288 [inline]
ip_rcv+0xb76/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a41/0x3460 net/core/dev.c:4562
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4627
process_backlog+0x203/0x740 net/core/dev.c:5307
napi_poll net/core/dev.c:5705 [inline]
net_rx_action+0x792/0x1910 net/core/dev.c:5771
__do_softirq+0x2d7/0xb85 kernel/softirq.c:285
Freed by task 1660:
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
__kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:520
kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:527
__cache_free mm/slab.c:3486 [inline]
kfree+0xd9/0x260 mm/slab.c:3801
skb_free_head+0x74/0xb0 net/core/skbuff.c:550
skb_release_data+0x58c/0x790 net/core/skbuff.c:570
skb_release_all+0x4a/0x60 net/core/skbuff.c:627
__kfree_skb net/core/skbuff.c:641 [inline]
kfree_skb+0x15d/0x4c0 net/core/skbuff.c:659
dccp_v4_do_rcv+0x10d/0x160 net/dccp/ipv4.c:688
sk_backlog_rcv include/net/sock.h:908 [inline]
__release_sock+0x124/0x360 net/core/sock.c:2271
release_sock+0xa4/0x2a0 net/core/sock.c:2786
dccp_sendmsg+0x528/0xe60 net/dccp/proto.c:820
inet_sendmsg+0x11f/0x5e0 net/ipv4/af_inet.c:764
sock_sendmsg_nosec net/socket.c:630 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:640
___sys_sendmsg+0x320/0x8b0 net/socket.c:2046
__sys_sendmmsg+0x31b/0x620 net/socket.c:2129
C_SYSC_sendmmsg net/compat.c:745 [inline]
compat_SyS_sendmmsg+0x32/0x40 net/compat.c:742
do_syscall_32_irqs_on arch/x86/entry/common.c:330 [inline]
do_fast_syscall_32+0x3ec/0xf9f arch/x86/entry/common.c:392
entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
The buggy address belongs to the object at ffff8801bb7a4600
which belongs to the cache kmalloc-2048 of size 2048
The buggy address is located 1154 bytes inside of
2048-byte region [ffff8801bb7a4600, ffff8801bb7a4e00)
The buggy address belongs to the page:
page:ffffea0006ede900 count:1 mapcount:0 mapping:ffff8801bb7a4600 index:0x0
compound_mapcount: 0
flags: 0x2fffc0000008100(slab|head)
raw: 02fffc0000008100 ffff8801bb7a4600 0000000000000000 0000000100000003
raw: ffffea0006bcbd20 ffffea0006f5b1a0 ffff8801dac00c40 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801bb7a4980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801bb7a4a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff8801bb7a4a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8801bb7a4b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801bb7a4b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.
syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line in the email body.
^ permalink raw reply
* possible deadlock in skb_queue_tail
From: syzbot @ 2018-04-02 9:20 UTC (permalink / raw)
To: davem, dh.herrmann, dvlasenk, dwindsor, elena.reshetova,
ishkamiel, keescook, ktkhai, linux-kernel, matthew, mjurczyk,
netdev, syzkaller-bugs, viro
Hello,
syzbot hit the following crash on net-next commit
06b19fe9a6df7aaa423cd8404ebe5ac9ec4b2960 (Sun Apr 1 03:37:33 2018 +0000)
Merge branch 'chelsio-inline-tls'
syzbot dashboard link:
https://syzkaller.appspot.com/bug?extid=6b495100f17ca8554ab9
Unfortunately, I don't have any reproducer for this crash yet.
Raw console output:
https://syzkaller.appspot.com/x/log.txt?id=6218830443446272
Kernel config:
https://syzkaller.appspot.com/x/.config?id=3327544840960562528
compiler: gcc (GCC) 7.1.1 20170620
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+6b495100f17ca8554ab9@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for
details.
If you forward the report, please keep this part and the footer.
======================================================
WARNING: possible circular locking dependency detected
4.16.0-rc6+ #290 Not tainted
------------------------------------------------------
syz-executor7/20971 is trying to acquire lock:
(&af_unix_sk_receive_queue_lock_key){+.+.}, at: [<00000000271ef0d8>]
skb_queue_tail+0x26/0x150 net/core/skbuff.c:2899
but task is already holding lock:
(&(&u->lock)->rlock/1){+.+.}, at: [<000000004e725e14>]
unix_state_double_lock+0x7b/0xb0 net/unix/af_unix.c:1088
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&(&u->lock)->rlock/1){+.+.}:
_raw_spin_lock_nested+0x28/0x40 kernel/locking/spinlock.c:354
sk_diag_dump_icons net/unix/diag.c:82 [inline]
sk_diag_fill.isra.4+0xa52/0xfe0 net/unix/diag.c:144
sk_diag_dump net/unix/diag.c:178 [inline]
unix_diag_dump+0x400/0x4f0 net/unix/diag.c:206
netlink_dump+0x492/0xcf0 net/netlink/af_netlink.c:2221
__netlink_dump_start+0x4ec/0x710 net/netlink/af_netlink.c:2318
netlink_dump_start include/linux/netlink.h:214 [inline]
unix_diag_handler_dump+0x3e7/0x750 net/unix/diag.c:307
__sock_diag_cmd net/core/sock_diag.c:230 [inline]
sock_diag_rcv_msg+0x204/0x360 net/core/sock_diag.c:261
netlink_rcv_skb+0x14b/0x380 net/netlink/af_netlink.c:2443
sock_diag_rcv+0x2a/0x40 net/core/sock_diag.c:272
netlink_unicast_kernel net/netlink/af_netlink.c:1307 [inline]
netlink_unicast+0x4c4/0x6b0 net/netlink/af_netlink.c:1333
netlink_sendmsg+0xa4a/0xe80 net/netlink/af_netlink.c:1896
sock_sendmsg_nosec net/socket.c:629 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:639
sock_write_iter+0x31a/0x5d0 net/socket.c:908
call_write_iter include/linux/fs.h:1782 [inline]
new_sync_write fs/read_write.c:469 [inline]
__vfs_write+0x684/0x970 fs/read_write.c:482
vfs_write+0x189/0x510 fs/read_write.c:544
SYSC_write fs/read_write.c:589 [inline]
SyS_write+0xef/0x220 fs/read_write.c:581
do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x42/0xb7
-> #0 (&af_unix_sk_receive_queue_lock_key){+.+.}:
lock_acquire+0x1d5/0x580 kernel/locking/lockdep.c:3920
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0x96/0xc0 kernel/locking/spinlock.c:152
skb_queue_tail+0x26/0x150 net/core/skbuff.c:2899
unix_dgram_sendmsg+0xa30/0x1610 net/unix/af_unix.c:1807
sock_sendmsg_nosec net/socket.c:629 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:639
___sys_sendmsg+0x320/0x8b0 net/socket.c:2047
__sys_sendmmsg+0x1ee/0x620 net/socket.c:2137
SYSC_sendmmsg net/socket.c:2168 [inline]
SyS_sendmmsg+0x35/0x60 net/socket.c:2163
do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x42/0xb7
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(&u->lock)->rlock/1);
lock(&af_unix_sk_receive_queue_lock_key);
lock(&(&u->lock)->rlock/1);
lock(&af_unix_sk_receive_queue_lock_key);
*** DEADLOCK ***
1 lock held by syz-executor7/20971:
#0: (&(&u->lock)->rlock/1){+.+.}, at: [<000000004e725e14>]
unix_state_double_lock+0x7b/0xb0 net/unix/af_unix.c:1088
stack backtrace:
CPU: 0 PID: 20971 Comm: syz-executor7 Not tainted 4.16.0-rc6+ #290
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:17 [inline]
dump_stack+0x194/0x24d lib/dump_stack.c:53
print_circular_bug.isra.38+0x2cd/0x2dc kernel/locking/lockdep.c:1223
check_prev_add kernel/locking/lockdep.c:1863 [inline]
check_prevs_add kernel/locking/lockdep.c:1976 [inline]
validate_chain kernel/locking/lockdep.c:2417 [inline]
__lock_acquire+0x30a8/0x3e00 kernel/locking/lockdep.c:3431
lock_acquire+0x1d5/0x580 kernel/locking/lockdep.c:3920
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0x96/0xc0 kernel/locking/spinlock.c:152
skb_queue_tail+0x26/0x150 net/core/skbuff.c:2899
unix_dgram_sendmsg+0xa30/0x1610 net/unix/af_unix.c:1807
sock_sendmsg_nosec net/socket.c:629 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:639
___sys_sendmsg+0x320/0x8b0 net/socket.c:2047
__sys_sendmmsg+0x1ee/0x620 net/socket.c:2137
SYSC_sendmmsg net/socket.c:2168 [inline]
SyS_sendmmsg+0x35/0x60 net/socket.c:2163
do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x455269
RSP: 002b:00007f71ffad6c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000133
RAX: ffffffffffffffda RBX: 00007f71ffad76d4 RCX: 0000000000455269
RDX: 04924924924924f4 RSI: 0000000020000200 RDI: 0000000000000016
RBP: 000000000072bf58 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000200000d4 R11: 0000000000000246 R12: 00000000ffffffff
R13: 00000000000004ca R14: 00000000006f9390 R15: 0000000000000001
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: sync thread started: state = BACKUP, mcast_ifn = bcsh0, syncid = 0,
id = 0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
IPVS: Unknown mcast interface: bcsh0
---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.
syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line in the email body.
^ permalink raw reply
* Re: [patch iproute2-next] man: fix devlink object list
From: Jiri Pirko @ 2018-04-02 9:15 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, stephen, mlxsw, valex
In-Reply-To: <1ce8129e-444f-8424-5db2-e6761090bf60@gmail.com>
Fri, Mar 30, 2018 at 06:43:33PM CEST, dsahern@gmail.com wrote:
>On 3/29/18 8:26 AM, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
>> ---
>> man/man8/devlink.8 | 10 +++++++++-
>> 1 file changed, 9 insertions(+), 1 deletion(-)
>>
>
>resource and sb exist on master, so this patch seems more appropriate
>for it than -next.
It's a documentation fix, so I sent it to -next. I don't mind this to be
applied on master though. Stephen?
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] fs/crashdd: add API to collect hardware dump in second kernel
From: Jiri Pirko @ 2018-04-02 9:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: Rahul Lakkireddy, netdev, linux-fsdevel, kexec, linux-kernel,
davem, viro, ebiederm, stephen, akpm, torvalds, ganeshgr,
nirranjan, indranil, valex
In-Reply-To: <20180330151129.GG28244@lunn.ch>
Fri, Mar 30, 2018 at 05:11:29PM CEST, andrew@lunn.ch wrote:
>> Please see:
>> http://patchwork.ozlabs.org/project/netdev/list/?series=36524
>>
>> I bevieve that the solution in the patchset could be used for
>> your usecase too.
>
>Hi Jiri
>
>https://lkml.org/lkml/2018/3/20/436
>
>How well does this API work for a 2Gbyte snapshot?
Ccing Alex who did the tests.
>
> Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] fs/crashdd: add API to collect hardware dump in second kernel
From: Jiri Pirko @ 2018-04-02 9:11 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Rahul Lakkireddy, netdev@vger.kernel.org,
linux-fsdevel@vger.kernel.org, kexec@lists.infradead.org,
linux-kernel@vger.kernel.org, davem@davemloft.net,
viro@zeniv.linux.org.uk, stephen@networkplumber.org,
akpm@linux-foundation.org, torvalds@linux-foundation.org,
Ganesh GR, Nirranjan Kirubaharan, Indranil Choudhury
In-Reply-To: <87k1tt2yo7.fsf@xmission.com>
Fri, Mar 30, 2018 at 08:42:00PM CEST, ebiederm@xmission.com wrote:
>Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> writes:
>
>> On Friday, March 03/30/18, 2018 at 16:09:07 +0530, Jiri Pirko wrote:
>>> Sat, Mar 24, 2018 at 11:56:33AM CET, rahul.lakkireddy@chelsio.com wrote:
>>> >Add a new module crashdd that exports the /sys/kernel/crashdd/
>>> >directory in second kernel, containing collected hardware/firmware
>>> >dumps.
>>> >
>>> >The sequence of actions done by device drivers to append their device
>>> >specific hardware/firmware logs to /sys/kernel/crashdd/ directory are
>>> >as follows:
>>> >
>>> >1. During probe (before hardware is initialized), device drivers
>>> >register to the crashdd module (via crashdd_add_dump()), with
>>> >callback function, along with buffer size and log name needed for
>>> >firmware/hardware log collection.
>>> >
>>> >2. Crashdd creates a driver's directory under
>>> >/sys/kernel/crashdd/<driver>. Then, it allocates the buffer with
>>>
>>> This smells. I need to identify the exact ASIC instance that produced
>>> the dump. To identify by driver name does not help me if I have multiple
>>> instances of the same driver. This looks wrong to me. This looks like
>>> a job for devlink where you have 1 devlink instance per 1 ASIC instance.
>>>
>>> Please see:
>>> http://patchwork.ozlabs.org/project/netdev/list/?series=36524
>>>
>>> I bevieve that the solution in the patchset could be used for
>>> your usecase too.
>>>
>>>
>>
>> The sysfs approach proposed here had been dropped in favour exporting
>> the dumps as ELF notes in /proc/vmcore.
>>
>> Will be posting the new patches soon.
>
>The concern was actually how you identify which device that came from.
>Where you read the identifier changes but sysfs or /proc/vmcore the
>change remains valid.
Yeah. I still don't see how you link the dump and the device. Rahul, did
you look at the patchset I pointed out?
Thanks!
^ permalink raw reply
* Hello
From: Mrs. Pamela Atuegbe @ 2018-04-02 8:07 UTC (permalink / raw)
Am Mrs.Pamela Atuegbe, I work in one of the prime bank here in burkina
faso, i want the bank to transfer the money left by our late customer
is a foreigner from Korea. can you investment this money and also help
the poor' the amount value at $13,300,000.00 (Thirteen Million Three
Hundred Thousand United States American Dollars), left in his account
still unclaimed. more details will be giving to you if you are
interested, I wait your reply Thank's.
With Best Regard,
Name: Mrs. Pamela Atuegbe.
^ permalink raw reply
* Re: [PATCH] net: improve ipv4 performances
From: kbuild test robot @ 2018-04-02 7:57 UTC (permalink / raw)
To: Anton Gary Ceph; +Cc: kbuild-all, netdev, linux-kernel
In-Reply-To: <20180401183121.13022-1-agaceph@gmail.com>
Hi Anton,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net/master]
[also build test WARNING on v4.16 next-20180329]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Anton-Gary-Ceph/net-improve-ipv4-performances/20180402-103807
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> net/bridge/br_private.h:690:15: sparse: restricted __be16 degrades to integer
net/bridge/br_private.h:694:15: sparse: restricted __be16 degrades to integer
--
>> net/bridge/br_multicast.c:66:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:69:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:96:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:99:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:171:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:175:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:96:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:99:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:581:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:584:14: sparse: restricted __be16 degrades to integer
>> net/bridge/br_multicast.c:66:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:69:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:96:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:99:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:96:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:99:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:1325:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:1328:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:1765:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:1769:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:1913:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:1917:14: sparse: restricted __be16 degrades to integer
>> net/bridge/br_private.h:690:15: sparse: restricted __be16 degrades to integer
net/bridge/br_private.h:694:15: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:2497:14: sparse: restricted __be16 degrades to integer
net/bridge/br_multicast.c:2532:14: sparse: restricted __be16 degrades to integer
--
net/core/filter.c:318:33: sparse: subtraction of functions? Share your drugs
net/core/filter.c:321:33: sparse: subtraction of functions? Share your drugs
net/core/filter.c:324:33: sparse: subtraction of functions? Share your drugs
net/core/filter.c:327:33: sparse: subtraction of functions? Share your drugs
net/core/filter.c:330:33: sparse: subtraction of functions? Share your drugs
net/core/filter.c:1184:39: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sock_filter const *filter @@ got struct sockstruct sock_filter const *filter @@
net/core/filter.c:1184:39: expected struct sock_filter const *filter
net/core/filter.c:1184:39: got struct sock_filter [noderef] <asn:1>*filter
net/core/filter.c:1286:39: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sock_filter const *filter @@ got struct sockstruct sock_filter const *filter @@
net/core/filter.c:1286:39: expected struct sock_filter const *filter
net/core/filter.c:1286:39: got struct sock_filter [noderef] <asn:1>*filter
net/core/filter.c:1547:43: sparse: incorrect type in argument 2 (different base types) @@ expected restricted __wsum [usertype] diff @@ got unsigned lonrestricted __wsum [usertype] diff @@
net/core/filter.c:1547:43: expected restricted __wsum [usertype] diff
net/core/filter.c:1547:43: got unsigned long long [unsigned] [usertype] to
net/core/filter.c:1550:36: sparse: incorrect type in argument 2 (different base types) @@ expected restricted __be16 [usertype] old @@ got unsigned lonrestricted __be16 [usertype] old @@
net/core/filter.c:1550:36: expected restricted __be16 [usertype] old
net/core/filter.c:1550:36: got unsigned long long [unsigned] [usertype] from
net/core/filter.c:1550:42: sparse: incorrect type in argument 3 (different base types) @@ expected restricted __be16 [usertype] new @@ got unsigned lonrestricted __be16 [usertype] new @@
net/core/filter.c:1550:42: expected restricted __be16 [usertype] new
net/core/filter.c:1550:42: got unsigned long long [unsigned] [usertype] to
net/core/filter.c:1553:36: sparse: incorrect type in argument 2 (different base types) @@ expected restricted __be32 [usertype] from @@ got unsigned lonrestricted __be32 [usertype] from @@
net/core/filter.c:1553:36: expected restricted __be32 [usertype] from
net/core/filter.c:1553:36: got unsigned long long [unsigned] [usertype] from
net/core/filter.c:1553:42: sparse: incorrect type in argument 3 (different base types) @@ expected restricted __be32 [usertype] to @@ got unsigned lonrestricted __be32 [usertype] to @@
net/core/filter.c:1553:42: expected restricted __be32 [usertype] to
net/core/filter.c:1553:42: got unsigned long long [unsigned] [usertype] to
net/core/filter.c:1598:59: sparse: incorrect type in argument 3 (different base types) @@ expected restricted __wsum [usertype] diff @@ got unsigned lonrestricted __wsum [usertype] diff @@
net/core/filter.c:1598:59: expected restricted __wsum [usertype] diff
net/core/filter.c:1598:59: got unsigned long long [unsigned] [usertype] to
net/core/filter.c:1601:52: sparse: incorrect type in argument 3 (different base types) @@ expected restricted __be16 [usertype] from @@ got unsigned lonrestricted __be16 [usertype] from @@
net/core/filter.c:1601:52: expected restricted __be16 [usertype] from
net/core/filter.c:1601:52: got unsigned long long [unsigned] [usertype] from
net/core/filter.c:1601:58: sparse: incorrect type in argument 4 (different base types) @@ expected restricted __be16 [usertype] to @@ got unsigned lonrestricted __be16 [usertype] to @@
net/core/filter.c:1601:58: expected restricted __be16 [usertype] to
net/core/filter.c:1601:58: got unsigned long long [unsigned] [usertype] to
net/core/filter.c:1604:52: sparse: incorrect type in argument 3 (different base types) @@ expected restricted __be32 [usertype] from @@ got unsigned lonrestricted __be32 [usertype] from @@
net/core/filter.c:1604:52: expected restricted __be32 [usertype] from
net/core/filter.c:1604:52: got unsigned long long [unsigned] [usertype] from
net/core/filter.c:1604:58: sparse: incorrect type in argument 4 (different base types) @@ expected restricted __be32 [usertype] to @@ got unsigned lonrestricted __be32 [usertype] to @@
net/core/filter.c:1604:58: expected restricted __be32 [usertype] to
net/core/filter.c:1604:58: got unsigned long long [unsigned] [usertype] to
net/core/filter.c:1650:28: sparse: incorrect type in return expression (different base types) @@ expected unsigned long long @@ got nsigned long long @@
net/core/filter.c:1650:28: expected unsigned long long
net/core/filter.c:1650:28: got restricted __wsum
net/core/filter.c:1672:35: sparse: incorrect type in return expression (different base types) @@ expected unsigned long long @@ got restricted unsigned long long @@
net/core/filter.c:1672:35: expected unsigned long long
net/core/filter.c:1672:35: got restricted __wsum [usertype] csum
>> net/core/filter.c:2244:14: sparse: restricted __be16 degrades to integer
net/core/filter.c:2246:14: sparse: restricted __be16 degrades to integer
--
>> include/linux/netdevice.h:4035:14: sparse: restricted __be16 degrades to integer
include/linux/netdevice.h:4037:14: sparse: restricted __be16 degrades to integer
>> net/core/skbuff.c:4646:14: sparse: restricted __be16 degrades to integer
net/core/skbuff.c:4650:14: sparse: restricted __be16 degrades to integer
--
>> include/net/netfilter/nf_queue.h:83:14: sparse: restricted __be16 degrades to integer
include/net/netfilter/nf_queue.h:89:14: sparse: restricted __be16 degrades to integer
>> include/net/netfilter/nf_queue.h:83:14: sparse: restricted __be16 degrades to integer
include/net/netfilter/nf_queue.h:89:14: sparse: restricted __be16 degrades to integer
--
>> net/netfilter/nf_tables_netdev.c:27:14: sparse: restricted __be16 degrades to integer
net/netfilter/nf_tables_netdev.c:30:14: sparse: restricted __be16 degrades to integer
--
>> include/net/netfilter/nf_queue.h:83:14: sparse: restricted __be16 degrades to integer
include/net/netfilter/nf_queue.h:89:14: sparse: restricted __be16 degrades to integer
--
>> net/netfilter/nf_flow_table_inet.c:14:14: sparse: restricted __be16 degrades to integer
net/netfilter/nf_flow_table_inet.c:16:14: sparse: restricted __be16 degrades to integer
--
>> net/openvswitch/conntrack.c:1113:14: sparse: restricted __be16 degrades to integer
net/openvswitch/conntrack.c:1116:14: sparse: restricted __be16 degrades to integer
vim +690 net/bridge/br_private.h
cc0fdd80 Linus Lüssing 2013-08-30 685
cc0fdd80 Linus Lüssing 2013-08-30 686 static inline bool br_multicast_querier_exists(struct net_bridge *br,
cc0fdd80 Linus Lüssing 2013-08-30 687 struct ethhdr *eth)
b00589af Linus Lüssing 2013-08-01 688 {
f9ba1e10 Anton Gary Ceph 2018-04-01 689 switch (__builtin_expect(eth->h_proto, ETH_P_IP)) {
cc0fdd80 Linus Lüssing 2013-08-30 @690 case (htons(ETH_P_IP)):
0888d5f3 daniel 2016-06-24 691 return __br_multicast_querier_exists(br,
0888d5f3 daniel 2016-06-24 692 &br->ip4_other_query, false);
cc0fdd80 Linus Lüssing 2013-08-30 693 #if IS_ENABLED(CONFIG_IPV6)
cc0fdd80 Linus Lüssing 2013-08-30 694 case (htons(ETH_P_IPV6)):
0888d5f3 daniel 2016-06-24 695 return __br_multicast_querier_exists(br,
0888d5f3 daniel 2016-06-24 696 &br->ip6_other_query, true);
cc0fdd80 Linus Lüssing 2013-08-30 697 #endif
cc0fdd80 Linus Lüssing 2013-08-30 698 default:
cc0fdd80 Linus Lüssing 2013-08-30 699 return false;
cc0fdd80 Linus Lüssing 2013-08-30 700 }
b00589af Linus Lüssing 2013-08-01 701 }
1080ab95 Nikolay Aleksandrov 2016-06-28 702
:::::: The code at line 690 was first introduced by commit
:::::: cc0fdd802859eaeb00e1c87dbb655594bed2844c bridge: separate querier and query timer into IGMP/IPv4 and MLD/IPv6 ones
:::::: TO: Linus Lüssing <linus.luessing@web.de>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply
* [PATCH v3 2/2] net: usb: asix88179_178a: de-duplicate code
From: Alexander Kurz @ 2018-04-02 7:43 UTC (permalink / raw)
To: David S . Miller
Cc: Andrew F . Davis, Marc Zyngier, linux-usb, netdev, Freddy Xin,
Alexander Kurz
In-Reply-To: <20180402074349.12010-1-akurz@blala.de>
Remove the duplicated code for asix88179_178a bind and reset methods.
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
drivers/net/usb/ax88179_178a.c | 137 ++++++++++-------------------------------
1 file changed, 31 insertions(+), 106 deletions(-)
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index a6ef75907ae9..fea4c7b877cc 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1223,7 +1223,7 @@ static int ax88179_led_setting(struct usbnet *dev)
return 0;
}
-static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
+static int ax88179_bind_or_reset(struct usbnet *dev, bool do_reset)
{
u8 buf[5];
u16 *tmp16;
@@ -1231,12 +1231,11 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
struct ethtool_eee eee_data;
- usbnet_get_endpoints(dev, intf);
-
tmp16 = (u16 *)buf;
tmp = (u8 *)buf;
- memset(ax179_data, 0, sizeof(*ax179_data));
+ if (!do_reset)
+ memset(ax179_data, 0, sizeof(*ax179_data));
/* Power up ethernet PHY */
*tmp16 = 0;
@@ -1249,9 +1248,13 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
msleep(100);
+ if (do_reset)
+ ax88179_auto_detach(dev, 0);
+
ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
ETH_ALEN, dev->net->dev_addr);
- memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+ if (!do_reset)
+ memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
/* RX bulk configuration */
memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
@@ -1266,19 +1269,21 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
1, 1, tmp);
- dev->net->netdev_ops = &ax88179_netdev_ops;
- dev->net->ethtool_ops = &ax88179_ethtool_ops;
- dev->net->needed_headroom = 8;
- dev->net->max_mtu = 4088;
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = ax88179_mdio_read;
- dev->mii.mdio_write = ax88179_mdio_write;
- dev->mii.phy_id_mask = 0xff;
- dev->mii.reg_num_mask = 0xff;
- dev->mii.phy_id = 0x03;
- dev->mii.supports_gmii = 1;
+ if (!do_reset) {
+ dev->net->netdev_ops = &ax88179_netdev_ops;
+ dev->net->ethtool_ops = &ax88179_ethtool_ops;
+ dev->net->needed_headroom = 8;
+ dev->net->max_mtu = 4088;
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = ax88179_mdio_read;
+ dev->mii.mdio_write = ax88179_mdio_write;
+ dev->mii.phy_id_mask = 0xff;
+ dev->mii.reg_num_mask = 0xff;
+ dev->mii.phy_id = 0x03;
+ dev->mii.supports_gmii = 1;
+ }
dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
@@ -1330,6 +1335,13 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
return 0;
}
+static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ usbnet_get_endpoints(dev, intf);
+
+ return ax88179_bind_or_reset(dev, false);
+}
+
static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
{
u16 tmp16;
@@ -1530,94 +1542,7 @@ static int ax88179_link_reset(struct usbnet *dev)
static int ax88179_reset(struct usbnet *dev)
{
- u8 buf[5];
- u16 *tmp16;
- u8 *tmp;
- struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
- struct ethtool_eee eee_data;
-
- tmp16 = (u16 *)buf;
- tmp = (u8 *)buf;
-
- /* Power up ethernet PHY */
- *tmp16 = 0;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
-
- *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
- msleep(200);
-
- *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
- msleep(100);
-
- /* Ethernet PHY Auto Detach*/
- ax88179_auto_detach(dev, 0);
-
- ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
- dev->net->dev_addr);
-
- /* RX bulk configuration */
- memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
-
- dev->rx_urb_size = 1024 * 20;
-
- *tmp = 0x34;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
-
- *tmp = 0x52;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
- 1, 1, tmp);
-
- dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_RXCSUM;
-
- dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_RXCSUM;
-
- /* Enable checksum offload */
- *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
- AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
-
- *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
- AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
-
- /* Configure RX control register => start operation */
- *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
- AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
-
- *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
- AX_MONITOR_MODE_RWMP;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
-
- /* Configure default medium type => giga */
- *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
- AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
- AX_MEDIUM_GIGAMODE;
- ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
- 2, 2, tmp16);
-
- ax88179_led_setting(dev);
-
- ax179_data->eee_enabled = 0;
- ax179_data->eee_active = 0;
-
- ax88179_disable_eee(dev);
-
- ax88179_ethtool_get_eee(dev, &eee_data);
- eee_data.advertised = 0;
- ax88179_ethtool_set_eee(dev, &eee_data);
-
- /* Restart autoneg */
- mii_nway_restart(&dev->mii);
-
- usbnet_link_change(dev, 0, 0);
-
- return 0;
+ return ax88179_bind_or_reset(dev, true);
}
static int ax88179_stop(struct usbnet *dev)
--
2.11.0
^ permalink raw reply related
* [PATCH v3 1/2] net: usb: asix88179_178a: set permanent address once only
From: Alexander Kurz @ 2018-04-02 7:43 UTC (permalink / raw)
To: David S . Miller
Cc: Andrew F . Davis, Marc Zyngier, linux-usb, netdev, Freddy Xin,
Alexander Kurz
The permanent address of asix88179_178a devices is read at probe time
and should not be overwritten later. Otherwise it may be overwritten
unintentionally with a configured address.
Signed-off-by: Alexander Kurz <akurz@blala.de>
---
drivers/net/usb/ax88179_178a.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index f32261ecd215..a6ef75907ae9 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1556,7 +1556,6 @@ static int ax88179_reset(struct usbnet *dev)
ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
dev->net->dev_addr);
- memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
/* RX bulk configuration */
memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v5 03/14] PCI: Add pcie_bandwidth_capable() to compute max supported link bandwidth
From: Tal Gilboa @ 2018-04-02 7:34 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Tariq Toukan, Jacob Keller, Ariel Elior, Ganesh Goudar,
Jeff Kirsher, everest-linux-l2, intel-wired-lan, netdev,
linux-kernel, linux-pci
In-Reply-To: <20180402004049.GA131023@bhelgaas-glaptop.roam.corp.google.com>
On 4/2/2018 3:40 AM, Bjorn Helgaas wrote:
> On Sun, Apr 01, 2018 at 11:38:53PM +0300, Tal Gilboa wrote:
>> On 3/31/2018 12:05 AM, Bjorn Helgaas wrote:
>>> From: Tal Gilboa <talgi@mellanox.com>
>>>
>>> Add pcie_bandwidth_capable() to compute the max link bandwidth supported by
>>> a device, based on the max link speed and width, adjusted by the encoding
>>> overhead.
>>>
>>> The maximum bandwidth of the link is computed as:
>>>
>>> max_link_speed * max_link_width * (1 - encoding_overhead)
>>>
>>> The encoding overhead is about 20% for 2.5 and 5.0 GT/s links using 8b/10b
>>> encoding, and about 1.5% for 8 GT/s or higher speed links using 128b/130b
>>> encoding.
>>>
>>> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
>>> [bhelgaas: adjust for pcie_get_speed_cap() and pcie_get_width_cap()
>>> signatures, don't export outside drivers/pci]
>>> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>>> Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
>>> ---
>>> drivers/pci/pci.c | 21 +++++++++++++++++++++
>>> drivers/pci/pci.h | 9 +++++++++
>>> 2 files changed, 30 insertions(+)
>>>
>>> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
>>> index 43075be79388..9ce89e254197 100644
>>> --- a/drivers/pci/pci.c
>>> +++ b/drivers/pci/pci.c
>>> @@ -5208,6 +5208,27 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev)
>>> return PCIE_LNK_WIDTH_UNKNOWN;
>>> }
>>> +/**
>>> + * pcie_bandwidth_capable - calculates a PCI device's link bandwidth capability
>>> + * @dev: PCI device
>>> + * @speed: storage for link speed
>>> + * @width: storage for link width
>>> + *
>>> + * Calculate a PCI device's link bandwidth by querying for its link speed
>>> + * and width, multiplying them, and applying encoding overhead.
>>> + */
>>> +u32 pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed,
>>> + enum pcie_link_width *width)
>>> +{
>>> + *speed = pcie_get_speed_cap(dev);
>>> + *width = pcie_get_width_cap(dev);
>>> +
>>> + if (*speed == PCI_SPEED_UNKNOWN || *width == PCIE_LNK_WIDTH_UNKNOWN)
>>> + return 0;
>>> +
>>> + return *width * PCIE_SPEED2MBS_ENC(*speed);
>>> +}
>>> +
>>> /**
>>> * pci_select_bars - Make BAR mask from the type of resource
>>> * @dev: the PCI device for which BAR mask is made
>>> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
>>> index 66738f1050c0..2a50172b9803 100644
>>> --- a/drivers/pci/pci.h
>>> +++ b/drivers/pci/pci.h
>>> @@ -261,8 +261,17 @@ void pci_disable_bridge_window(struct pci_dev *dev);
>>> (speed) == PCIE_SPEED_2_5GT ? "2.5 GT/s" : \
>>> "Unknown speed")
>>> +/* PCIe speed to Mb/s with encoding overhead: 20% for gen2, ~1.5% for gen3 */
>>> +#define PCIE_SPEED2MBS_ENC(speed) \
>>
>> Missing gen4.
>
> I made it "gen3+". I think that's accurate, isn't it? The spec
> doesn't seem to actually use "gen3" as a specific term, but sec 4.2.2
> says rates of 8 GT/s or higher (which I think includes gen3 and gen4)
> use 128b/130b encoding.
>
I meant that PCIE_SPEED_16_0GT will return 0 from this macro since it
wasn't added. Need to return 15754.
^ permalink raw reply
* Re: linux-next: Signed-off-by missing for commits in the net-next tree
From: Stephen Rothwell @ 2018-04-02 6:50 UTC (permalink / raw)
To: Johan Hedberg
Cc: David Miller, Networking, Linux-Next Mailing List,
Linux Kernel Mailing List, Marcel Holtmann
In-Reply-To: <20180402053803.GA17750@x1c.home>
[-- Attachment #1: Type: text/plain, Size: 1059 bytes --]
Hi Johan,
On Mon, 2 Apr 2018 08:38:03 +0300 Johan Hedberg <johan.hedberg@intel.com> wrote:
>
> On Mon, Apr 02, 2018, Stephen Rothwell wrote:
> > 45a42bc9cc65 ("Bluetooth: hci_bcm: Remove DMI quirk for the MINIX Z83-4")
> > f9b95db0165a ("Bluetooth: btrsi: remove unused including <linux/version.h>")
> > 96e58d368fa6 ("Bluetooth: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for BTUSB_QCA_ROME")
> > 9ea471320e13 ("Bluetooth: Mark expected switch fall-throughs")
> >
> > are missing a Signed-off-by from their committer.
>
> I think this is because I fixed up a missing author name in "Bluetooth:
> hci_bcm: Remove DMI quirk for the MINIX Z83-4" and did a push --force,
> whereas these patches were originally committed by Marcel. Should I be
> adding my signed-off-by to all affected patches when doing such rebases?
Yep, Ideally we should have a Signed-off-by from everyone who involved
in getting the patches into the final tree. That definitely means that
the final committer needs to add one.
--
Cheers,
Stephen Rothwell
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* WARNING in add_uevent_var
From: syzbot @ 2018-04-02 6:01 UTC (permalink / raw)
To: davem, johannes, linux-kernel, linux-wireless, netdev,
syzkaller-bugs
Hello,
syzbot hit the following crash on upstream commit
10b84daddbec72c6b440216a69de9a9605127f7a (Sat Mar 31 17:59:00 2018 +0000)
Merge branch 'perf-urgent-for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
syzbot dashboard link:
https://syzkaller.appspot.com/bug?extid=230d9e642a85d3fec29c
So far this crash happened 5 times on net-next, upstream.
C reproducer: https://syzkaller.appspot.com/x/repro.c?id=6614377067184128
syzkaller reproducer:
https://syzkaller.appspot.com/x/repro.syz?id=6535492073947136
Raw console output:
https://syzkaller.appspot.com/x/log.txt?id=6339348970602496
Kernel config:
https://syzkaller.appspot.com/x/.config?id=-2760467897697295172
compiler: gcc (GCC) 7.1.1 20170620
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+230d9e642a85d3fec29c@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for
details.
If you forward the report, please keep this part and the footer.
------------[ cut here ]------------
add_uevent_var: buffer size too small
WARNING: CPU: 0 PID: 4431 at lib/kobject_uevent.c:594
add_uevent_var+0x2aa/0x2d0 lib/kobject_uevent.c:594
Kernel panic - not syncing: panic_on_warn set ...
CPU: 0 PID: 4431 Comm: syzkaller678536 Not tainted 4.16.0-rc7+ #374
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:17 [inline]
dump_stack+0x194/0x24d lib/dump_stack.c:53
panic+0x1e4/0x41c kernel/panic.c:183
__warn+0x1dc/0x200 kernel/panic.c:547
report_bug+0x1f4/0x2b0 lib/bug.c:186
fixup_bug.part.10+0x37/0x80 arch/x86/kernel/traps.c:178
fixup_bug arch/x86/kernel/traps.c:247 [inline]
do_error_trap+0x2d7/0x3e0 arch/x86/kernel/traps.c:296
do_invalid_op+0x1b/0x20 arch/x86/kernel/traps.c:315
invalid_op+0x1b/0x40 arch/x86/entry/entry_64.S:986
RIP: 0010:add_uevent_var+0x2aa/0x2d0 lib/kobject_uevent.c:594
RSP: 0018:ffff8801adba6810 EFLAGS: 00010286
RAX: dffffc0000000008 RBX: ffff8801ad7a6d40 RCX: ffffffff815b193e
RDX: 0000000000000000 RSI: 1ffff10035b74cb2 RDI: 1ffff10035b74c87
RBP: ffff8801adba68d8 R08: 1ffff10035b74c49 R09: 0000000000000000
R10: 0000000000000002 R11: 0000000000000000 R12: 1ffff10035b74d03
R13: ffff8801ad7a6e58 R14: 00000000000003e6 R15: 0000000000000438
rfkill_dev_uevent+0x31/0x170 net/rfkill/core.c:813
dev_uevent+0x2b6/0x7e0 drivers/base/core.c:913
kobject_uevent_env+0x3fe/0xd30 lib/kobject_uevent.c:476
kobject_uevent+0x1f/0x30 lib/kobject_uevent.c:565
device_add+0xd04/0x1650 drivers/base/core.c:1834
rfkill_register+0x254/0xd60 net/rfkill/core.c:1019
wiphy_register+0x19d1/0x2050 net/wireless/core.c:872
ieee80211_register_hw+0x1162/0x3100 net/mac80211/main.c:1041
mac80211_hwsim_new_radio+0x1d06/0x2fb0
drivers/net/wireless/mac80211_hwsim.c:2757
hwsim_new_radio_nl+0x67a/0x8c0 drivers/net/wireless/mac80211_hwsim.c:3214
genl_family_rcv_msg+0x7b7/0xfb0 net/netlink/genetlink.c:599
genl_rcv_msg+0xb2/0x140 net/netlink/genetlink.c:624
netlink_rcv_skb+0x14b/0x380 net/netlink/af_netlink.c:2447
genl_rcv+0x28/0x40 net/netlink/genetlink.c:635
netlink_unicast_kernel net/netlink/af_netlink.c:1311 [inline]
netlink_unicast+0x4c4/0x6b0 net/netlink/af_netlink.c:1337
netlink_sendmsg+0xa4a/0xe60 net/netlink/af_netlink.c:1900
sock_sendmsg_nosec net/socket.c:630 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:640
___sys_sendmsg+0x767/0x8b0 net/socket.c:2046
__sys_sendmsg+0xe5/0x210 net/socket.c:2080
SYSC_sendmsg net/socket.c:2091 [inline]
SyS_sendmsg+0x2d/0x50 net/socket.c:2087
do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x43fda9
RSP: 002b:00007ffde548edb8 EFLAGS: 00000213 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 000000000043fda9
RDX: 0000000000000000 RSI: 0000000020b3dfc8 RDI: 0000000000000003
RBP: 00000000006cb018 R08: 00000000004002c8 R09: 00000000004002c8
R10: 00000000004002c8 R11: 0000000000000213 R12: 00000000004016d0
R13: 0000000000401760 R14: 0000000000000000 R15: 0000000000000000
Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: disabled
Rebooting in 86400 seconds..
---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.
syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
If you want to test a patch for this bug, please reply with:
#syz test: git://repo/address.git branch
and provide the patch inline or as an attachment.
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line in the email body.
^ permalink raw reply
* general protection fault in tipc_nametbl_unsubscribe
From: syzbot @ 2018-04-02 6:01 UTC (permalink / raw)
To: davem, jon.maloy, linux-kernel, netdev, syzkaller-bugs,
tipc-discussion, ying.xue
Hello,
syzbot hit the following crash on upstream commit
10b84daddbec72c6b440216a69de9a9605127f7a (Sat Mar 31 17:59:00 2018 +0000)
Merge branch 'perf-urgent-for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
syzbot dashboard link:
https://syzkaller.appspot.com/bug?extid=4859fe19555ea87c42f3
So far this crash happened 3 times on upstream.
C reproducer: https://syzkaller.appspot.com/x/repro.c?id=4775372465897472
syzkaller reproducer:
https://syzkaller.appspot.com/x/repro.syz?id=4868734988582912
Raw console output:
https://syzkaller.appspot.com/x/log.txt?id=5073802094444544
Kernel config:
https://syzkaller.appspot.com/x/.config?id=-2760467897697295172
compiler: gcc (GCC) 7.1.1 20170620
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+4859fe19555ea87c42f3@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for
details.
If you forward the report, please keep this part and the footer.
R13: ffffffffffffffff R14: 0000000000000000 R15: 0000000000000000
Name sequence creation failed, no memory
Failed to create subscription for {24576,0,4294967295}
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
(ftrace buffer empty)
Modules linked in:
CPU: 1 PID: 4447 Comm: syzkaller851181 Not tainted 4.16.0-rc7+ #374
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:__list_del_entry_valid+0x7e/0x150 lib/list_debug.c:51
RSP: 0018:ffff8801ae1aef48 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff8801cf54c760 RDI: ffff8801cf54c768
RBP: ffff8801ae1aef60 R08: 1ffff10035c35cff R09: ffffffff89956150
R10: ffff8801ae1aee28 R11: 000000000000168a R12: ffffffff87745ea0
R13: ffff8801ae1af100 R14: ffff8801cf54c760 R15: ffff8801cf4c8cc0
FS: 0000000000000000(0000) GS:ffff8801db100000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055dce15c3090 CR3: 000000000846a002 CR4: 00000000001606e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
__list_del_entry include/linux/list.h:117 [inline]
list_del_init include/linux/list.h:159 [inline]
tipc_nametbl_unsubscribe+0x318/0x990 net/tipc/name_table.c:848
tipc_subscrb_subscrp_delete+0x1e9/0x460 net/tipc/subscr.c:212
tipc_subscrb_delete net/tipc/subscr.c:242 [inline]
tipc_subscrb_release_cb+0x17/0x30 net/tipc/subscr.c:321
tipc_topsrv_kern_unsubscr+0x2c3/0x430 net/tipc/server.c:535
tipc_group_delete+0x2c0/0x3d0 net/tipc/group.c:231
tipc_sk_leave+0x10b/0x200 net/tipc/socket.c:2795
tipc_release+0x154/0xff0 net/tipc/socket.c:577
sock_release+0x8d/0x1e0 net/socket.c:595
sock_close+0x16/0x20 net/socket.c:1149
__fput+0x327/0x7e0 fs/file_table.c:209
____fput+0x15/0x20 fs/file_table.c:243
task_work_run+0x199/0x270 kernel/task_work.c:113
exit_task_work include/linux/task_work.h:22 [inline]
do_exit+0x9bb/0x1ad0 kernel/exit.c:865
do_group_exit+0x149/0x400 kernel/exit.c:968
SYSC_exit_group kernel/exit.c:979 [inline]
SyS_exit_group+0x1d/0x20 kernel/exit.c:977
do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x43f228
RSP: 002b:00007ffde31217e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 000000000043f228
RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
RBP: 00000000004bf308 R08: 00000000000000e7 R09: ffffffffffffffd0
R10: 00000000204ee000 R11: 0000000000000246 R12: 0000000000000001
R13: 00000000006d1180 R14: 0000000000000000 R15: 0000000000000000
Code: 00 00 00 00 ad de 49 39 c4 74 66 48 b8 00 02 00 00 00 00 ad de 48 89
da 48 39 c3 74 65 48 c1 ea 03 48 b8 00 00 00 00 00 fc ff df <80> 3c 02 00
75 7b 48 8b 13 48 39 f2 75 57 49 8d 7c 24 08 48 b8
RIP: __list_del_entry_valid+0x7e/0x150 lib/list_debug.c:51 RSP:
ffff8801ae1aef48
---[ end trace ba18c1598e2d5535 ]---
---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.
syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
If you want to test a patch for this bug, please reply with:
#syz test: git://repo/address.git branch
and provide the patch inline or as an attachment.
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line in the email body.
^ permalink raw reply
* KASAN: stack-out-of-bounds Read in xfrm_state_find (5)
From: syzbot @ 2018-04-02 6:01 UTC (permalink / raw)
To: davem, herbert, linux-kernel, netdev, steffen.klassert,
syzkaller-bugs
Hello,
syzbot hit the following crash on upstream commit
10b84daddbec72c6b440216a69de9a9605127f7a (Sat Mar 31 17:59:00 2018 +0000)
Merge branch 'perf-urgent-for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
syzbot dashboard link:
https://syzkaller.appspot.com/bug?extid=d90468452f685a0b28eb
So far this crash happened 4 times on net-next, upstream.
C reproducer: https://syzkaller.appspot.com/x/repro.c?id=6686969799114752
syzkaller reproducer:
https://syzkaller.appspot.com/x/repro.syz?id=5121263362113536
Raw console output:
https://syzkaller.appspot.com/x/log.txt?id=5897355362566144
Kernel config:
https://syzkaller.appspot.com/x/.config?id=-2760467897697295172
compiler: gcc (GCC) 7.1.1 20170620
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+d90468452f685a0b28eb@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for
details.
If you forward the report, please keep this part and the footer.
==================================================================
BUG: KASAN: stack-out-of-bounds in xfrm_state_find+0x30de/0x3210
net/xfrm/xfrm_state.c:1051
Read of size 4 at addr ffff8801b25ef480 by task syzkaller538986/4480
CPU: 0 PID: 4480 Comm: syzkaller538986 Not tainted 4.16.0-rc7+ #9
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:17 [inline]
dump_stack+0x194/0x24d lib/dump_stack.c:53
print_address_description+0x73/0x250 mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report+0x23c/0x360 mm/kasan/report.c:412
__asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:432
xfrm_state_find+0x30de/0x3210 net/xfrm/xfrm_state.c:1051
xfrm_tmpl_resolve_one net/xfrm/xfrm_policy.c:1393 [inline]
xfrm_tmpl_resolve+0x2ee/0xc40 net/xfrm/xfrm_policy.c:1437
xfrm_resolve_and_create_bundle+0x184/0x28d0 net/xfrm/xfrm_policy.c:1833
xfrm_lookup+0xfcb/0x25c0 net/xfrm/xfrm_policy.c:2163
xfrm_lookup_route+0x39/0x1a0 net/xfrm/xfrm_policy.c:2283
ip_route_output_flow+0x7c/0xa0 net/ipv4/route.c:2583
udp_sendmsg+0x19bd/0x2f70 net/ipv4/udp.c:1012
udpv6_sendmsg+0x757/0x3400 net/ipv6/udp.c:1156
inet_sendmsg+0x11f/0x5e0 net/ipv4/af_inet.c:764
sock_sendmsg_nosec net/socket.c:630 [inline]
sock_sendmsg+0xca/0x110 net/socket.c:640
___sys_sendmsg+0x767/0x8b0 net/socket.c:2046
__sys_sendmsg+0xe5/0x210 net/socket.c:2080
SYSC_sendmsg net/socket.c:2091 [inline]
SyS_sendmsg+0x2d/0x50 net/socket.c:2087
do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x440139
RSP: 002b:00007fffa14c36e8 EFLAGS: 00000217 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440139
RDX: 0000000000000000 RSI: 0000000020000580 RDI: 0000000000000003
RBP: 00000000006ca018 R08: 00000000004002c8 R09: 00000000004002c8
R10: 00000000000000e8 R11: 0000000000000217 R12: 0000000000401a60
R13: 0000000000401af0 R14: 0000000000000000 R15: 0000000000000000
The buggy address belongs to the page:
page:ffffea0006c97bc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
flags: 0x2fffc0000000000()
raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff
raw: 0000000000000000 ffffea0006c90101 0000000000000000 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801b25ef380: f2 00 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2 f2
ffff8801b25ef400: f2 00 00 00 00 f2 f2 f2 f2 00 00 00 00 00 00 00
> ffff8801b25ef480: f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 f2 f2
^
ffff8801b25ef500: f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff8801b25ef580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
==================================================================
---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.
syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
If you want to test a patch for this bug, please reply with:
#syz test: git://repo/address.git branch
and provide the patch inline or as an attachment.
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line in the email body.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox