* Re: [PATCH trivial 1/2] net: Fix Kconfig indentation
From: David Miller @ 2019-09-26 6:56 UTC (permalink / raw)
To: krzk
Cc: m.grzeschik, wg, mkl, andrew, f.fainelli, hkallweit1, kuznet,
yoshfuji, pablo, kadlec, fw, trivial, netdev, linux-kernel,
linux-can, linux-rdma, linux-wireless, b.a.t.m.a.n,
netfilter-devel, coreteam, lvs-devel, rds-devel
In-Reply-To: <20190923155243.6997-1-krzk@kernel.org>
From: Krzysztof Kozlowski <krzk@kernel.org>
Date: Mon, 23 Sep 2019 17:52:42 +0200
> Adjust indentation from spaces to tab (+optional two spaces) as in
> coding style with command like:
> $ sed -e 's/^ /\t/' -i */Kconfig
>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Ok, I'll apply these to 'net'.
^ permalink raw reply
* Re: [PATCH 1/1] MAINTAINERS: add Yanjun to FORCEDETH maintainers list
From: David Miller @ 2019-09-26 6:51 UTC (permalink / raw)
To: rain.1986.08.12
Cc: yanjun.zhu, mchehab+samsung, gregkh, robh, linus.walleij,
nicolas.ferre, linux-kernel, netdev
In-Reply-To: <20190923143746.4310-1-rain.1986.08.12@gmail.com>
From: rain.1986.08.12@gmail.com
Date: Mon, 23 Sep 2019 22:37:46 +0800
> From: Rain River <rain.1986.08.12@gmail.com>
>
> Yanjun has been spending quite a lot of time fixing bugs
> in FORCEDETH source code. I'd like to add Yanjun to maintainers
> list.
>
> Signed-off-by: Rain River <rain.1986.08.12@gmail.com>
Applied, thank you.
^ permalink raw reply
* [PATCH net] net: socionext: ave: Avoid using netdev_err() before calling register_netdev()
From: Kunihiko Hayashi @ 2019-09-26 6:35 UTC (permalink / raw)
To: David S. Miller, netdev; +Cc: linux-kernel, Kunihiko Hayashi
Until calling register_netdev(), ndev->dev_name isn't specified, and
netdev_err() displays "(unnamed net_device)".
ave 65000000.ethernet (unnamed net_device) (uninitialized): invalid phy-mode setting
ave: probe of 65000000.ethernet failed with error -22
This replaces netdev_err() with dev_err() before calling register_netdev().
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
---
drivers/net/ethernet/socionext/sni_ave.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
index 10d0c3e..f20f6c4 100644
--- a/drivers/net/ethernet/socionext/sni_ave.c
+++ b/drivers/net/ethernet/socionext/sni_ave.c
@@ -1662,19 +1662,19 @@ static int ave_probe(struct platform_device *pdev)
"socionext,syscon-phy-mode",
1, 0, &args);
if (ret) {
- netdev_err(ndev, "can't get syscon-phy-mode property\n");
+ dev_err(dev, "can't get syscon-phy-mode property\n");
goto out_free_netdev;
}
priv->regmap = syscon_node_to_regmap(args.np);
of_node_put(args.np);
if (IS_ERR(priv->regmap)) {
- netdev_err(ndev, "can't map syscon-phy-mode\n");
+ dev_err(dev, "can't map syscon-phy-mode\n");
ret = PTR_ERR(priv->regmap);
goto out_free_netdev;
}
ret = priv->data->get_pinmode(priv, phy_mode, args.args[0]);
if (ret) {
- netdev_err(ndev, "invalid phy-mode setting\n");
+ dev_err(dev, "invalid phy-mode setting\n");
goto out_free_netdev;
}
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net] Bluetooth: SMP: remove set but not used variable 'smp'
From: Marcel Holtmann @ 2019-09-26 6:34 UTC (permalink / raw)
To: YueHaibing
Cc: Johan Hedberg, David S. Miller, Bluez mailing list,
kernel-janitors, netdev, linux-kernel
In-Reply-To: <20190923140516.166241-1-yuehaibing@huawei.com>
Hi Yue,
> On Sep 23, 2019, at 16:05, YueHaibing <yuehaibing@huawei.com> wrote:
>
> Fixes gcc '-Wunused-but-set-variable' warning:
>
> net/bluetooth/smp.c: In function 'smp_irk_matches':
> net/bluetooth/smp.c:505:18: warning:
> variable 'smp' set but not used [-Wunused-but-set-variable]
>
> net/bluetooth/smp.c: In function 'smp_generate_rpa':
> net/bluetooth/smp.c:526:18: warning:
> variable 'smp' set but not used [-Wunused-but-set-variable]
>
> It is not used since commit 28a220aac596 ("bluetooth: switch
> to AES library")
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> net/bluetooth/smp.c | 6 ------
> 1 file changed, 6 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH net] net: socionext: Fix a signedness bug in ave_probe()
From: Kunihiko Hayashi @ 2019-09-26 6:28 UTC (permalink / raw)
To: Dan Carpenter; +Cc: David S. Miller, netdev, kernel-janitors
In-Reply-To: <20190925105750.GG3264@mwanda>
Hi Dan,
Thank you for pointing out.
I've confirmed that this error handling works well with your patch.
Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Thank you,
On Wed, 25 Sep 2019 13:57:50 +0300 <dan.carpenter@oracle.com> wrote:
> The "phy_mode" variable is an enum and in this context GCC treats it as
> an unsigned int so the error handling is never triggered.
>
> Fixes: 4c270b55a5af ("net: ethernet: socionext: add AVE ethernet driver")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> drivers/net/ethernet/socionext/sni_ave.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
> index 10d0c3e478ab..d047a53f34f2 100644
> --- a/drivers/net/ethernet/socionext/sni_ave.c
> +++ b/drivers/net/ethernet/socionext/sni_ave.c
> @@ -1566,7 +1566,7 @@ static int ave_probe(struct platform_device *pdev)
>
> np = dev->of_node;
> phy_mode = of_get_phy_mode(np);
> - if (phy_mode < 0) {
> + if ((int)phy_mode < 0) {
> dev_err(dev, "phy-mode not found\n");
> return -EINVAL;
> }
> --
> 2.20.1
---
Best Regards,
Kunihiko Hayashi
^ permalink raw reply
* Re: [BUG] Unable to handle kernel NULL pointer dereference in phy_support_asym_pause
From: Heiner Kallweit @ 2019-09-26 6:12 UTC (permalink / raw)
To: Michal Vokáč, netdev@vger.kernel.org, Andrew Lunn,
Vivien Didelot, Florian Fainelli
Cc: David S. Miller
In-Reply-To: <573ffa6a-f29a-84d9-5895-b3d6cc389619@ysoft.com>
On 24.09.2019 13:27, Michal Vokáč wrote:
> Hi,
>
> just tried booting latest next-20190920 on our imx6dl-yapp4-hydra platform
> with QCA8334 switch and got this:
>
> [ 6.957822] 8<--- cut here ---
> [ 6.963550] Unable to handle kernel NULL pointer dereference at virtual address 00000264
> [ 6.974342] pgd = (ptrval)
> [ 6.979751] [00000264] *pgd=00000000
> [ 6.986005] Internal error: Oops: 5 [#1] SMP ARM
> [ 6.993318] CPU: 0 PID: 21 Comm: kworker/0:1 Not tainted 5.3.0-rc5-00985-g0394a63acfe2 #7
> [ 7.004196] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> [ 7.013467] Workqueue: events deferred_probe_work_func
> [ 7.021339] PC is at phy_support_asym_pause+0x14/0x44
> [ 7.029149] LR is at qca8k_port_enable+0x40/0x48
> [ 7.036485] pc : [<806840f4>] lr : [<80686724>] psr: 60000013
> [ 7.045489] sp : e821bca0 ip : e821bcb0 fp : e821bcac
> [ 7.053456] r10: 00000000 r9 : e8241f00 r8 : e812d040
> [ 7.061431] r7 : 00000000 r6 : 00000000 r5 : e8931640 r4 : 00000002
> [ 7.070702] r3 : 00000001 r2 : 00000000 r1 : 00000000 r0 : 00000000
> [ 7.079947] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
> [ 7.089825] Control: 10c5387d Table: 1000404a DAC: 00000051
> [ 7.098382] Process kworker/0:1 (pid: 21, stack limit = 0x(ptrval))
> [ 7.107431] Stack: (0xe821bca0 to 0xe821c000)
> [ 7.114607] bca0: e821bccc e821bcb0 80686724 806840ec e812d090 e812d090 e88a02cc 00000000
> [ 7.125637] bcc0: e821bce4 e821bcd0 80a74134 806866f0 e812d090 e812d0cc e821bd7c e821bce8
> [ 7.136666] bce0: 80a730bc 80a74104 00000000 e88a02cc 00000004 e821bd00 e88a02e0 80cc95f8
> [ 7.147725] bd00: e88a02e0 e88a02c0 e812d090 e812d090 81006548 e88a02e4 e812d040 e88a02c0
> [ 7.158791] bd20: 00000003 e812d040 e8830c00 00000000 e821bd5c e821bd40 806243b8 80623abc
> [ 7.169887] bd40: e8931640 00000000 00000000 5303fd08 e821bd7c e8931640 e8830c00 e8931680
> [ 7.181000] bd60: 00000000 81077adc 00000004 00000000 e821bd9c e821bd80 806864f8 80a72930
> [ 7.192107] bd80: 81077adc e8830c00 81123b24 00000000 e821bdb4 e821bda0 806856c8 80686354
> [ 7.203216] bda0: 81123a18 e8830c00 e821bde4 e821bdb8 8061f944 80685694 00000000 e8830c00
> [ 7.214318] bdc0: 81077adc e8830c00 81006548 00000001 810c07f0 00000000 e821be1c e821bde8
> [ 7.225434] bde0: 8061ff68 8061f850 e821be04 e821bdf8 81077adc e821be74 81077adc e821be74
> [ 7.236589] be00: e8830c00 81006548 00000001 810c07f0 e821be3c e821be20 80620178 8061ff04
> [ 7.247788] be20: 00000000 e821be74 806200dc 81006548 e821be6c e821be40 8061e160 806200e8
> [ 7.258982] be40: e821be6c e836d96c e86acdb8 5303fd08 e8830c00 81006548 e8830c44 81071194
> [ 7.270217] be60: e821bea4 e821be70 8061fd80 8061e104 8061b58c e8830c00 00000001 5303fd08
> [ 7.281470] be80: 00000000 e8830c00 81077998 e8830c00 81071194 00000000 e821beb4 e821bea8
> [ 7.292770] bea0: 80620220 8061fcac e821bed4 e821beb8 8061e360 80620210 e8830c00 81071180
> [ 7.304105] bec0: 81071180 81071194 e821bef4 e821bed8 8061f144 8061e2d8 810711b8 e81f5080
> [ 7.315494] bee0: eada5f40 eada7100 e821bf34 e821bef8 80142e2c 8061f0dc e8200d00 ffffe000
> [ 7.326890] bf00: e821bf1c e821bf10 8014234c e81f5080 eada5f40 e81f5094 eada5f58 ffffe000
> [ 7.338312] bf20: 00000008 81003d00 e821bf74 e821bf38 801433f4 80142c14 ffffe000 80e1264c
> [ 7.349778] bf40: 810c00c7 eada5f40 80148afc e81f76c0 e81f7680 00000000 e821a000 e81f5080
> [ 7.361246] bf60: 80143130 e8143e74 e821bfac e821bf78 80148e2c 8014313c e81f76dc e81f76dc
> [ 7.372758] bf80: e821bfac e81f7680 80148cc4 00000000 00000000 00000000 00000000 00000000
> [ 7.384313] bfa0: 00000000 e821bfb0 801010e8 80148cd0 00000000 00000000 00000000 00000000
> [ 7.395858] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 7.407363] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
> [ 7.418856] Backtrace:
> [ 7.424620] [<806840e0>] (phy_support_asym_pause) from [<80686724>] (qca8k_port_enable+0x40/0x48)
> [ 7.436911] [<806866e4>] (qca8k_port_enable) from [<80a74134>] (dsa_port_enable+0x3c/0x6c)
> [ 7.448629] r7:00000000 r6:e88a02cc r5:e812d090 r4:e812d090
> [ 7.457708] [<80a740f8>] (dsa_port_enable) from [<80a730bc>] (dsa_register_switch+0x798/0xacc)
> [ 7.469833] r5:e812d0cc r4:e812d090
> [ 7.476909] [<80a72924>] (dsa_register_switch) from [<806864f8>] (qca8k_sw_probe+0x1b0/0x1c4)
> [ 7.489008] r10:00000000 r9:00000004 r8:81077adc r7:00000000 r6:e8931680 r5:e8830c00
> [ 7.500419] r4:e8931640
> [ 7.506528] [<80686348>] (qca8k_sw_probe) from [<806856c8>] (mdio_probe+0x40/0x64)
> [ 7.517774] r7:00000000 r6:81123b24 r5:e8830c00 r4:81077adc
> [ 7.527048] [<80685688>] (mdio_probe) from [<8061f944>] (really_probe+0x100/0x2d8)
> [ 7.538284] r5:e8830c00 r4:81123a18
> [ 7.545528] [<8061f844>] (really_probe) from [<8061ff68>] (driver_probe_device+0x70/0x180)
> [ 7.557539] r10:00000000 r9:810c07f0 r8:00000001 r7:81006548 r6:e8830c00 r5:81077adc
> [ 7.569129] r4:e8830c00 r3:00000000
> [ 7.576439] [<8061fef8>] (driver_probe_device) from [<80620178>] (__device_attach_driver+0x9c/0xc8)
> [ 7.589338] r9:810c07f0 r8:00000001 r7:81006548 r6:e8830c00 r5:e821be74 r4:81077adc
> [ 7.600949] [<806200dc>] (__device_attach_driver) from [<8061e160>] (bus_for_each_drv+0x68/0xc8)
> [ 7.613617] r7:81006548 r6:806200dc r5:e821be74 r4:00000000
> [ 7.623099] [<8061e0f8>] (bus_for_each_drv) from [<8061fd80>] (__device_attach+0xe0/0x14c)
> [ 7.635235] r7:81071194 r6:e8830c44 r5:81006548 r4:e8830c00
> [ 7.644681] [<8061fca0>] (__device_attach) from [<80620220>] (device_initial_probe+0x1c/0x20)
> [ 7.657036] r8:00000000 r7:81071194 r6:e8830c00 r5:81077998 r4:e8830c00
> [ 7.667551] [<80620204>] (device_initial_probe) from [<8061e360>] (bus_probe_device+0x94/0x9c)
> [ 7.680054] [<8061e2cc>] (bus_probe_device) from [<8061f144>] (deferred_probe_work_func+0x74/0xa0)
> [ 7.692914] r7:81071194 r6:81071180 r5:81071180 r4:e8830c00
> [ 7.702440] [<8061f0d0>] (deferred_probe_work_func) from [<80142e2c>] (process_one_work+0x224/0x528)
> [ 7.715483] r7:eada7100 r6:eada5f40 r5:e81f5080 r4:810711b8
> [ 7.725046] [<80142c08>] (process_one_work) from [<801433f4>] (worker_thread+0x2c4/0x5e4)
> [ 7.737175] r10:81003d00 r9:00000008 r8:ffffe000 r7:eada5f58 r6:e81f5094 r5:eada5f40
> [ 7.748949] r4:e81f5080
> [ 7.755402] [<80143130>] (worker_thread) from [<80148e2c>] (kthread+0x168/0x170)
> [ 7.766823] r10:e8143e74 r9:80143130 r8:e81f5080 r7:e821a000 r6:00000000 r5:e81f7680
> [ 7.778636] r4:e81f76c0
> [ 7.785159] [<80148cc4>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c)
> [ 7.796457] Exception stack(0xe821bfb0 to 0xe821bff8)
> [ 7.805543] bfa0: 00000000 00000000 00000000 00000000
> [ 7.817805] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 7.830047] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [ 7.840688] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:80148cc4
> [ 7.852535] r4:e81f7680
> [ 7.859061] Code: e92dd800 e24cb004 e52de004 e8bd4000 (e5902264)
> [ 7.869239] ---[ end trace 1b5559d3dc3f80a4 ]---
>
> Bisecting the dsa code changes since v5.3 brought me to this commit:
>
> 0394a63acfe2a6e1c08af0eb1a9133ee8650d7bd is the first bad commit
> commit 0394a63acfe2a6e1c08af0eb1a9133ee8650d7bd
> Author: Vivien Didelot <vivien.didelot@gmail.com>
> Date: Mon Aug 19 16:00:50 2019 -0400
>
> net: dsa: enable and disable all ports
> Call the .port_enable and .port_disable functions for all ports,
> not only the user ports, so that drivers may optimize the power
> consumption of all ports after a successful setup.
> Unused ports are now disabled on setup. CPU and DSA ports are now
> enabled on setup and disabled on teardown. User ports were already
> enabled at slave creation and disabled at slave destruction.
> Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> :040000 040000 0462b53f03ece23b4af955c3b8a48dce05d90970 34e5df083585e6cce35600698a757508b539e508 M net
>
> Any ideas what might be wrong?
> Thank you!
>
This commit added a call to dsa_port_enable() with the phy_device parameter
being NULL what causes the NPE. Other port_enable callback implementations
may also not check this parameter and face a similar issue.
What I can't answer at a first glance is whether passing NULL is the bug,
or whether port_enable implementations not checking the parameter is the
bug.
> Michal
>
>
Heiner
^ permalink raw reply
* [PATCH] vhost: introduce mdev based hardware backend
From: Tiwei Bie @ 2019-09-26 4:54 UTC (permalink / raw)
To: mst, jasowang, alex.williamson, maxime.coquelin
Cc: linux-kernel, kvm, virtualization, netdev, dan.daly,
cunming.liang, zhihong.wang, lingshan.zhu, tiwei.bie
This patch introduces a mdev based hardware vhost backend.
This backend is built on top of the same abstraction used
in virtio-mdev and provides a generic vhost interface for
userspace to accelerate the virtio devices in guest.
This backend is implemented as a mdev device driver on top
of the same mdev device ops used in virtio-mdev but using
a different mdev class id, and it will register the device
as a VFIO device for userspace to use. Userspace can setup
the IOMMU with the existing VFIO container/group APIs and
then get the device fd with the device name. After getting
the device fd of this device, userspace can use vhost ioctls
to setup the backend.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
This patch depends on below series:
https://lkml.org/lkml/2019/9/24/357
RFC v4 -> v1:
- Implement vhost-mdev as a mdev device driver directly and
connect it to VFIO container/group. (Jason);
- Pass ring addresses as GPAs/IOVAs in vhost-mdev to avoid
meaningless HVA->GPA translations (Jason);
RFC v3 -> RFC v4:
- Build vhost-mdev on top of the same abstraction used by
virtio-mdev (Jason);
- Introduce vhost fd and pass VFIO fd via SET_BACKEND ioctl (MST);
RFC v2 -> RFC v3:
- Reuse vhost's ioctls instead of inventing a VFIO regions/irqs
based vhost protocol on top of vfio-mdev (Jason);
RFC v1 -> RFC v2:
- Introduce a new VFIO device type to build a vhost protocol
on top of vfio-mdev;
drivers/vhost/Kconfig | 9 +
drivers/vhost/Makefile | 3 +
drivers/vhost/mdev.c | 381 +++++++++++++++++++++++++++++++++++++
include/uapi/linux/vhost.h | 8 +
4 files changed, 401 insertions(+)
create mode 100644 drivers/vhost/mdev.c
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 3d03ccbd1adc..decf0be8efe9 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -34,6 +34,15 @@ config VHOST_VSOCK
To compile this driver as a module, choose M here: the module will be called
vhost_vsock.
+config VHOST_MDEV
+ tristate "Vhost driver for Mediated devices"
+ depends on EVENTFD && VFIO && VFIO_MDEV
+ select VHOST
+ default n
+ ---help---
+ Say M here to enable the vhost_mdev module for use with
+ the mediated device based hardware vhost accelerators
+
config VHOST
tristate
---help---
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile
index 6c6df24f770c..ad9c0f8c6d8c 100644
--- a/drivers/vhost/Makefile
+++ b/drivers/vhost/Makefile
@@ -10,4 +10,7 @@ vhost_vsock-y := vsock.o
obj-$(CONFIG_VHOST_RING) += vringh.o
+obj-$(CONFIG_VHOST_MDEV) += vhost_mdev.o
+vhost_mdev-y := mdev.o
+
obj-$(CONFIG_VHOST) += vhost.o
diff --git a/drivers/vhost/mdev.c b/drivers/vhost/mdev.c
new file mode 100644
index 000000000000..1c12a25b86a2
--- /dev/null
+++ b/drivers/vhost/mdev.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018-2019 Intel Corporation.
+ */
+
+#include <linux/compat.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/mdev.h>
+#include <linux/module.h>
+#include <linux/vfio.h>
+#include <linux/vhost.h>
+#include <linux/virtio_mdev.h>
+
+#include "vhost.h"
+
+struct vhost_mdev {
+ /* The lock is to protect this structure. */
+ struct mutex mutex;
+ struct vhost_dev dev;
+ struct vhost_virtqueue *vqs;
+ int nvqs;
+ u64 state;
+ u64 features;
+ u64 acked_features;
+ bool opened;
+ struct mdev_device *mdev;
+};
+
+static u8 mdev_get_status(struct mdev_device *mdev)
+{
+ const struct virtio_mdev_device_ops *ops = mdev_get_dev_ops(mdev);
+
+ return ops->get_status(mdev);
+}
+
+static void mdev_set_status(struct mdev_device *mdev, u8 status)
+{
+ const struct virtio_mdev_device_ops *ops = mdev_get_dev_ops(mdev);
+
+ return ops->set_status(mdev, status);
+}
+
+static void mdev_add_status(struct mdev_device *mdev, u8 status)
+{
+ status |= mdev_get_status(mdev);
+ mdev_set_status(mdev, status);
+}
+
+static void mdev_reset(struct mdev_device *mdev)
+{
+ mdev_set_status(mdev, 0);
+}
+
+static void handle_vq_kick(struct vhost_work *work)
+{
+ struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
+ poll.work);
+ struct vhost_mdev *m = container_of(vq->dev, struct vhost_mdev, dev);
+ const struct virtio_mdev_device_ops *ops = mdev_get_dev_ops(m->mdev);
+
+ ops->kick_vq(m->mdev, vq - m->vqs);
+}
+
+static irqreturn_t vhost_mdev_virtqueue_cb(void *private)
+{
+ struct vhost_virtqueue *vq = private;
+ struct eventfd_ctx *call_ctx = vq->call_ctx;
+
+ if (call_ctx)
+ eventfd_signal(call_ctx, 1);
+ return IRQ_HANDLED;
+}
+
+static long vhost_mdev_reset(struct vhost_mdev *m)
+{
+ struct mdev_device *mdev = m->mdev;
+
+ mdev_reset(mdev);
+ mdev_add_status(mdev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+ mdev_add_status(mdev, VIRTIO_CONFIG_S_DRIVER);
+ return 0;
+}
+
+static long vhost_mdev_start(struct vhost_mdev *m)
+{
+ struct mdev_device *mdev = m->mdev;
+ const struct virtio_mdev_device_ops *ops = mdev_get_dev_ops(mdev);
+ struct virtio_mdev_callback cb;
+ struct vhost_virtqueue *vq;
+ int idx;
+
+ ops->set_features(mdev, m->acked_features);
+
+ mdev_add_status(mdev, VIRTIO_CONFIG_S_FEATURES_OK);
+ if (!(mdev_get_status(mdev) & VIRTIO_CONFIG_S_FEATURES_OK))
+ goto reset;
+
+ for (idx = 0; idx < m->nvqs; idx++) {
+ vq = &m->vqs[idx];
+
+ if (!vq->desc || !vq->avail || !vq->used)
+ break;
+
+ if (ops->set_vq_state(mdev, idx, vq->last_avail_idx))
+ goto reset;
+
+ /*
+ * In vhost-mdev, userspace should pass ring addresses
+ * in guest physical addresses when IOMMU is disabled or
+ * IOVAs when IOMMU is enabled.
+ */
+ if (ops->set_vq_address(mdev, idx, (u64)vq->desc,
+ (u64)vq->avail, (u64)vq->used))
+ goto reset;
+
+ ops->set_vq_num(mdev, idx, vq->num);
+
+ cb.callback = vhost_mdev_virtqueue_cb;
+ cb.private = vq;
+ ops->set_vq_cb(mdev, idx, &cb);
+
+ ops->set_vq_ready(mdev, idx, 1);
+ }
+
+ mdev_add_status(mdev, VIRTIO_CONFIG_S_DRIVER_OK);
+ if (mdev_get_status(mdev) & VIRTIO_CONFIG_S_NEEDS_RESET)
+ goto reset;
+ return 0;
+
+reset:
+ vhost_mdev_reset(m);
+ return -ENODEV;
+}
+
+static long vhost_set_state(struct vhost_mdev *m, u64 __user *statep)
+{
+ u64 state;
+ long r;
+
+ if (copy_from_user(&state, statep, sizeof(state)))
+ return -EFAULT;
+
+ if (state >= VHOST_MDEV_S_MAX)
+ return -EINVAL;
+
+ if (m->state == state)
+ return 0;
+
+ m->state = state;
+
+ switch (m->state) {
+ case VHOST_MDEV_S_RUNNING:
+ r = vhost_mdev_start(m);
+ break;
+ case VHOST_MDEV_S_STOPPED:
+ r = vhost_mdev_reset(m);
+ break;
+ default:
+ r = -EINVAL;
+ break;
+ }
+
+ return r;
+}
+
+static long vhost_get_features(struct vhost_mdev *m, u64 __user *featurep)
+{
+ if (copy_to_user(featurep, &m->features, sizeof(m->features)))
+ return -EFAULT;
+ return 0;
+}
+
+static long vhost_set_features(struct vhost_mdev *m, u64 __user *featurep)
+{
+ u64 features;
+
+ if (copy_from_user(&features, featurep, sizeof(features)))
+ return -EFAULT;
+
+ if (features & ~m->features)
+ return -EINVAL;
+
+ m->acked_features = features;
+
+ return 0;
+}
+
+static long vhost_get_vring_base(struct vhost_mdev *m, void __user *argp)
+{
+ const struct virtio_mdev_device_ops *ops = mdev_get_dev_ops(m->mdev);
+ struct vhost_virtqueue *vq;
+ u32 idx;
+ long r;
+
+ r = get_user(idx, (u32 __user *)argp);
+ if (r < 0)
+ return r;
+ if (idx >= m->nvqs)
+ return -ENOBUFS;
+
+ vq = &m->vqs[idx];
+ vq->last_avail_idx = ops->get_vq_state(m->mdev, idx);
+
+ return vhost_vring_ioctl(&m->dev, VHOST_GET_VRING_BASE, argp);
+}
+
+static int vhost_mdev_open(void *device_data)
+{
+ struct vhost_mdev *m = device_data;
+ struct vhost_dev *dev;
+ struct vhost_virtqueue **vqs;
+ int nvqs, i, r;
+
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
+ mutex_lock(&m->mutex);
+
+ if (m->opened) {
+ r = -EBUSY;
+ goto err;
+ }
+
+ nvqs = m->nvqs;
+ vhost_mdev_reset(m);
+
+ memset(&m->dev, 0, sizeof(m->dev));
+ memset(m->vqs, 0, nvqs * sizeof(struct vhost_virtqueue));
+
+ vqs = kmalloc_array(nvqs, sizeof(*vqs), GFP_KERNEL);
+ if (!vqs) {
+ r = -ENOMEM;
+ goto err;
+ }
+
+ dev = &m->dev;
+ for (i = 0; i < nvqs; i++) {
+ vqs[i] = &m->vqs[i];
+ vqs[i]->handle_kick = handle_vq_kick;
+ }
+ vhost_dev_init(dev, vqs, nvqs, 0, 0, 0);
+ m->opened = true;
+ mutex_unlock(&m->mutex);
+
+ return 0;
+
+err:
+ mutex_unlock(&m->mutex);
+ module_put(THIS_MODULE);
+ return r;
+}
+
+static void vhost_mdev_release(void *device_data)
+{
+ struct vhost_mdev *m = device_data;
+
+ mutex_lock(&m->mutex);
+ vhost_mdev_reset(m);
+ vhost_dev_stop(&m->dev);
+ vhost_dev_cleanup(&m->dev);
+
+ kfree(m->dev.vqs);
+ m->opened = false;
+ mutex_unlock(&m->mutex);
+ module_put(THIS_MODULE);
+}
+
+static long vhost_mdev_unlocked_ioctl(void *device_data,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vhost_mdev *m = device_data;
+ void __user *argp = (void __user *)arg;
+ long r;
+
+ mutex_lock(&m->mutex);
+
+ switch (cmd) {
+ case VHOST_MDEV_SET_STATE:
+ r = vhost_set_state(m, argp);
+ break;
+ case VHOST_GET_FEATURES:
+ r = vhost_get_features(m, argp);
+ break;
+ case VHOST_SET_FEATURES:
+ r = vhost_set_features(m, argp);
+ break;
+ case VHOST_GET_VRING_BASE:
+ r = vhost_get_vring_base(m, argp);
+ break;
+ default:
+ r = vhost_dev_ioctl(&m->dev, cmd, argp);
+ if (r == -ENOIOCTLCMD)
+ r = vhost_vring_ioctl(&m->dev, cmd, argp);
+ }
+
+ mutex_unlock(&m->mutex);
+ return r;
+}
+
+static const struct vfio_device_ops vfio_vhost_mdev_dev_ops = {
+ .name = "vfio-vhost-mdev",
+ .open = vhost_mdev_open,
+ .release = vhost_mdev_release,
+ .ioctl = vhost_mdev_unlocked_ioctl,
+};
+
+static int vhost_mdev_probe(struct device *dev)
+{
+ struct mdev_device *mdev = mdev_from_dev(dev);
+ const struct virtio_mdev_device_ops *ops = mdev_get_dev_ops(mdev);
+ struct vhost_mdev *m;
+ int nvqs, r;
+
+ m = kzalloc(sizeof(*m), GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+ if (!m)
+ return -ENOMEM;
+
+ mutex_init(&m->mutex);
+
+ nvqs = ops->get_queue_max(mdev);
+ m->nvqs = nvqs;
+
+ m->vqs = kmalloc_array(nvqs, sizeof(struct vhost_virtqueue),
+ GFP_KERNEL);
+ if (!m->vqs) {
+ r = -ENOMEM;
+ goto err;
+ }
+
+ r = vfio_add_group_dev(dev, &vfio_vhost_mdev_dev_ops, m);
+ if (r)
+ goto err;
+
+ m->features = ops->get_features(mdev);
+ m->mdev = mdev;
+ return 0;
+
+err:
+ kfree(m->vqs);
+ kfree(m);
+ return r;
+}
+
+static void vhost_mdev_remove(struct device *dev)
+{
+ struct vhost_mdev *m;
+
+ m = vfio_del_group_dev(dev);
+ mutex_destroy(&m->mutex);
+ kfree(m->vqs);
+ kfree(m);
+}
+
+static struct mdev_class_id id_table[] = {
+ { MDEV_ID_VHOST },
+ { 0 },
+};
+
+static struct mdev_driver vhost_mdev_driver = {
+ .name = "vhost_mdev",
+ .probe = vhost_mdev_probe,
+ .remove = vhost_mdev_remove,
+ .id_table = id_table,
+};
+
+static int __init vhost_mdev_init(void)
+{
+ return mdev_register_driver(&vhost_mdev_driver, THIS_MODULE);
+}
+module_init(vhost_mdev_init);
+
+static void __exit vhost_mdev_exit(void)
+{
+ mdev_unregister_driver(&vhost_mdev_driver);
+}
+module_exit(vhost_mdev_exit);
+
+MODULE_VERSION("0.0.1");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediated device based accelerator for virtio");
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index 40d028eed645..5afbc2f08fa3 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -116,4 +116,12 @@
#define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64)
#define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int)
+/* VHOST_MDEV specific defines */
+
+#define VHOST_MDEV_SET_STATE _IOW(VHOST_VIRTIO, 0x70, __u64)
+
+#define VHOST_MDEV_S_STOPPED 0
+#define VHOST_MDEV_S_RUNNING 1
+#define VHOST_MDEV_S_MAX 2
+
#endif
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2] net: flow_offload: fix memory leak in nfp_abm_u32_knode_replace
From: Jakub Kicinski @ 2019-09-26 4:53 UTC (permalink / raw)
To: Navid Emamdoost
Cc: emamd001, smccaman, kjlu, David S. Miller, Pablo Neira Ayuso,
John Hurley, Colin Ian King, oss-drivers, netdev, linux-kernel
In-Reply-To: <20190926022240.3789-1-navid.emamdoost@gmail.com>
On Wed, 25 Sep 2019 21:22:35 -0500, Navid Emamdoost wrote:
> In nfp_abm_u32_knode_replace if the allocation for match fails it should
> go to the error handling instead of returning.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> ---
> Changes in v2:
> - Reused err variable for erorr value returning.
Thanks, there's another goto up top. And I think subject prefix could
be "nfp: abm:", perhaps?
> drivers/net/ethernet/netronome/nfp/abm/cls.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/netronome/nfp/abm/cls.c b/drivers/net/ethernet/netronome/nfp/abm/cls.c
> index 23ebddfb9532..b0cb9d201f7d 100644
> --- a/drivers/net/ethernet/netronome/nfp/abm/cls.c
> +++ b/drivers/net/ethernet/netronome/nfp/abm/cls.c
> @@ -198,14 +198,18 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
> if ((iter->val & cmask) == (val & cmask) &&
> iter->band != knode->res->classid) {
> NL_SET_ERR_MSG_MOD(extack, "conflict with already offloaded filter");
> + err = -EOPNOTSUPP;
> goto err_delete;
> }
> }
>
> if (!match) {
> match = kzalloc(sizeof(*match), GFP_KERNEL);
> - if (!match)
> - return -ENOMEM;
> + if (!match) {
> + err = -ENOMEM;
> + goto err_delete;
> + }
> +
> list_add(&match->list, &alink->dscp_map);
> }
> match->handle = knode->handle;
> @@ -221,7 +225,7 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
>
> err_delete:
> nfp_abm_u32_knode_delete(alink, knode);
> - return -EOPNOTSUPP;
> + return err;
> }
>
> static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type,
^ permalink raw reply
* Re: Fwd: [PATCH] bonding/802.3ad: fix slave initialization states race
From: Jay Vosburgh @ 2019-09-26 4:38 UTC (permalink / raw)
To: Aleksei Zakharov; +Cc: netdev, zhangsha (A)
In-Reply-To: <CAJYOGF9TY8WtUscsfJ=qduAw7_1BwU+4iE+eL6cidM=LBL9w+A@mail.gmail.com>
Aleksei Zakharov <zaharov@selectel.ru> wrote:
>ср, 25 сент. 2019 г. в 03:31, Jay Vosburgh <jay.vosburgh@canonical.com>:
>>
>> Алексей Захаров wrote:
>> [...]
>> >Right after reboot one of the slaves hangs with actor port state 71
>> >and partner port state 1.
>> >It doesn't send lacpdu and seems to be broken.
>> >Setting link down and up again fixes slave state.
>> [...]
>>
>> I think I see what failed in the first patch, could you test the
>> following patch? This one is for net-next, so you'd need to again swap
>> slave_err / netdev_err for the Ubuntu 4.15 kernel.
>>
>I've tested new patch. It seems to work. I can't reproduce the bug
>with this patch.
>There are two types of messages when link becomes up:
>First:
>bond-san: EVENT 1 llu 4294895911 slave eth2
>8021q: adding VLAN 0 to HW filter on device eth2
>bond-san: link status definitely down for interface eth2, disabling it
>mlx4_en: eth2: Link Up
>bond-san: EVENT 4 llu 4294895911 slave eth2
>bond-san: link status up for interface eth2, enabling it in 500 ms
>bond-san: invalid new link 3 on slave eth2
>bond-san: link status definitely up for interface eth2, 10000 Mbps full duplex
>Second:
>bond-san: EVENT 1 llu 4295147594 slave eth2
>8021q: adding VLAN 0 to HW filter on device eth2
>mlx4_en: eth2: Link Up
>bond-san: EVENT 4 llu 4295147594 slave eth2
>bond-san: link status up again after 0 ms for interface eth2
>bond-san: link status definitely up for interface eth2, 10000 Mbps full duplex
>
>These messages (especially "invalid new link") look a bit unclear from
>sysadmin point of view.
The "invalid new link" is appearing because bond_miimon_commit
is being asked to commit a new state that isn't UP or DOWN (3 is
BOND_LINK_BACK). I looked through the patched code today, and I don't
see a way to get to that message with the new link set to 3, so I'll add
some instrumentation and send out another patch to figure out what's
going on, as that shouldn't happen.
I don't see the "invalid" message testing locally, I think
because my network device doesn't transition to carrier up as quickly as
yours. I thought you were getting BOND_LINK_BACK passed through from
bond_enslave (which calls bond_set_slave_link_state, which will set
link_new_link to BOND_LINK_BACK and leave it there), but the
link_new_link is reset first thing in bond_miimon_inspect, so I'm not
sure how it gets into bond_miimon_commit (I'm thinking perhaps a
concurrent commit triggered by another slave, which then picks up this
proposed link state change by happenstance).
-J
---
-Jay Vosburgh, jay.vosburgh@canonical.com
^ permalink raw reply
* Re: [net-next v2 2/2] net: reject ptp requests with unsupported flags
From: Richard Cochran @ 2019-09-26 4:02 UTC (permalink / raw)
To: Jacob Keller
Cc: netdev, Intel Wired LAN, Jeffrey Kirsher, Felipe Balbi,
David S . Miller, Christopher Hall
In-Reply-To: <20190926022820.7900-3-jacob.e.keller@intel.com>
On Wed, Sep 25, 2019 at 07:28:20PM -0700, Jacob Keller wrote:
> This patch may not be correct for individual drivers, especially
> regarding the rising vs falling edge flags. I interpreted the default
> behavior to be to timestamp the rising edge of a pin transition.
So I think this patch goes too far. It breaks the implied ABI.
> diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
> index fd3071f55bd3..2867a2581a36 100644
> --- a/drivers/net/ethernet/intel/igb/igb_ptp.c
> +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
> @@ -521,6 +521,10 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
>
> switch (rq->type) {
> case PTP_CLK_REQ_EXTTS:
> + /* Reject requests with unsupported flags */
> + if (rq->extts.flags & ~(PTP_ENABLE_FEATURE | PTP_RISING_EDGE))
> + return -EOPNOTSUPP;
This HW always time stamps both edges, and that is not configurable.
Here you reject PTP_FALLING_EDGE, and that is clearly wrong. If the
driver had been really picky (my fault I guess), it should have always
insisted on (PTP_RISING_EDGE | PTP_FALLING_EDGE) being set together.
But it is too late to enforce that now, because it could break user
space programs.
I do agree with the sentiment of checking the flags at the driver
level, but this needs to be done case by case, with the drivers'
author's input.
(The req.perout.flags can be done unconditionally in all drivers,
since there were never any valid flags, but req.extts.flags needs
careful attention.)
Thanks,
Richard
^ permalink raw reply
* Re: [net-next v2 1/2] ptp: correctly disable flags on old ioctls
From: Richard Cochran @ 2019-09-26 3:43 UTC (permalink / raw)
To: Jacob Keller
Cc: netdev, Intel Wired LAN, Jeffrey Kirsher, Felipe Balbi,
David S . Miller, Christopher Hall
In-Reply-To: <20190926022820.7900-2-jacob.e.keller@intel.com>
On Wed, Sep 25, 2019 at 07:28:19PM -0700, Jacob Keller wrote:
> diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
> index 9c18476d8d10..67d0199840fd 100644
> --- a/drivers/ptp/ptp_chardev.c
> +++ b/drivers/ptp/ptp_chardev.c
> @@ -155,7 +155,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
> err = -EINVAL;
> break;
> } else if (cmd == PTP_EXTTS_REQUEST) {
> - req.extts.flags &= ~PTP_EXTTS_VALID_FLAGS;
> + req.extts.flags &= PTP_EXTTS_V1_VALID_FLAGS;
Duh, the bit wise negation was not the intention. Thanks for catching
this, and introducing the "V1" set of flags makes sense.
@davem Please merge this patch as a bug fix.
Acked-by: Richard Cochran <richardcochran@gmail.com>
^ permalink raw reply
* Re: [PATCH net] net: broadcom/bcmsysport: Fix signedness in bcm_sysport_probe()
From: Florian Fainelli @ 2019-09-26 3:18 UTC (permalink / raw)
To: Dan Carpenter, Florian Fainelli
Cc: David S. Miller, bcm-kernel-feedback-list, netdev,
kernel-janitors
In-Reply-To: <20190925105604.GD3264@mwanda>
On 9/25/2019 3:56 AM, Dan Carpenter wrote:
> The "priv->phy_interface" variable is an enum and in this context GCC
> will treat it as unsigned so the error handling will never be
> triggered.
>
> Fixes: 80105befdb4b ("net: systemport: add Broadcom SYSTEMPORT Ethernet MAC driver")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATCH V11 0/4] BPF: New helper to obtain namespace data from current task
From: Eric W. Biederman @ 2019-09-26 0:59 UTC (permalink / raw)
To: Carlos Neira; +Cc: netdev, yhs, brouer, bpf
In-Reply-To: <20190924152005.4659-1-cneirabustos@gmail.com>
Carlos Neira <cneirabustos@gmail.com> writes:
> Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
> scripts but this helper returns the pid as seen by the root namespace which is
> fine when a bcc script is not executed inside a container.
> When the process of interest is inside a container, pid filtering will not work
> if bpf_get_current_pid_tgid() is used.
> This helper addresses this limitation returning the pid as it's seen by the current
> namespace where the script is executing.
>
> In the future different pid_ns files may belong to different devices, according to the
> discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
> To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
> This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
> used to do pid filtering even inside a container.
I think I may have asked this before. If I am repeating old gound
please excuse me.
Am I correct in understanding these new helpers are designed to be used
when programs running in ``conainers'' call it inside pid namespaces
register bpf programs for tracing?
If so would it be possible to change how the existing bpf opcodes
operate when they are used in the context of a pid namespace?
That later would seem to allow just moving an existing application into
a pid namespace with no modifications. If we can do this with trivial
cost at bpf compile time and with no userspace changes that would seem
a better approach.
If not can someone point me to why we can't do that? What am I missing?
Eric
> Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
>
> Carlos Neira (4):
> fs/nsfs.c: added ns_match
> bpf: added new helper bpf_get_ns_current_pid_tgid
> tools: Added bpf_get_ns_current_pid_tgid helper
> tools/testing/selftests/bpf: Add self-tests for new helper. self tests
> added for new helper
>
> fs/nsfs.c | 8 +
> include/linux/bpf.h | 1 +
> include/linux/proc_ns.h | 2 +
> include/uapi/linux/bpf.h | 18 ++-
> kernel/bpf/core.c | 1 +
> kernel/bpf/helpers.c | 32 ++++
> kernel/trace/bpf_trace.c | 2 +
> tools/include/uapi/linux/bpf.h | 18 ++-
> tools/testing/selftests/bpf/Makefile | 2 +-
> tools/testing/selftests/bpf/bpf_helpers.h | 3 +
> .../selftests/bpf/progs/test_pidns_kern.c | 71 ++++++++
> tools/testing/selftests/bpf/test_pidns.c | 152 ++++++++++++++++++
> 12 files changed, 307 insertions(+), 3 deletions(-)
> create mode 100644 tools/testing/selftests/bpf/progs/test_pidns_kern.c
> create mode 100644 tools/testing/selftests/bpf/test_pidns.c
^ permalink raw reply
* [net-next v2 0/2] new PTP ioctl fixes
From: Jacob Keller @ 2019-09-26 2:28 UTC (permalink / raw)
To: netdev
Cc: Intel Wired LAN, Jeffrey Kirsher, Jacob Keller, Richard Cochran,
Felipe Balbi, David S . Miller, Christopher Hall
I noticed recently that Filip added new versions of the PTP ioctls which
correctly honor the reserved fields (making it so that we can safely extend
them in the future).
Unfortunately, this breaks the old ioctls for a couple of reasons. First,
the flags for the old ioctls get cleared. This means that the external
timestamp request can never be enabled. Further, it means future new flags
will *not* be cleared, and thus old ioctl will potentially send non-zero
data and be mis-interpreted.
Additionally, new flags are not protected against in-driver, because no
current driver verifies that the flags are only one of the supported ones.
This means new flags will be mis-interpreted by the drivers.
This series provides patches to fix drivers to verify and reject unsupported
flags, as well as to fix the ioctls to clear flags on the old version of the
ioctl properly.
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Christopher Hall <christopher.s.hall@intel.com>
Range-diff from v1:
1: c317dc1cc7eb = 1: c317dc1cc7eb ptp: correctly disable flags on old ioctls
2: 08ce725c7f2a ! 2: 5537762fb9cc net: reject ptp requests with unsupported flags
@@ drivers/net/phy/dp83640.c: static int ptp_dp83640_enable(struct ptp_clock_info *
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
+ /* Reject requests with unsupported flags */
-+ if (rq->extts.flags & ~(PTP_FEATURE_ENABLE |
++ if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
+ PTP_RISING_EDGE |
+ PTP_FALLING_EDGE))
+ return -EOPNOTSUPP;
Jacob Keller (2):
ptp: correctly disable flags on old ioctls
net: reject ptp requests with unsupported flags
drivers/net/dsa/mv88e6xxx/ptp.c | 5 +++++
drivers/net/ethernet/broadcom/tg3.c | 4 ++++
drivers/net/ethernet/intel/igb/igb_ptp.c | 8 +++++++
.../ethernet/mellanox/mlx5/core/lib/clock.c | 10 +++++++++
drivers/net/ethernet/microchip/lan743x_ptp.c | 4 ++++
drivers/net/ethernet/renesas/ravb_ptp.c | 9 ++++++++
.../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 4 ++++
drivers/net/phy/dp83640.c | 8 +++++++
drivers/ptp/ptp_chardev.c | 4 ++--
include/uapi/linux/ptp_clock.h | 22 +++++++++++++++++++
10 files changed, 76 insertions(+), 2 deletions(-)
--
2.23.0.245.gf157bbb9169d
^ permalink raw reply
* [net-next v2 2/2] net: reject ptp requests with unsupported flags
From: Jacob Keller @ 2019-09-26 2:28 UTC (permalink / raw)
To: netdev
Cc: Intel Wired LAN, Jeffrey Kirsher, Jacob Keller, Richard Cochran,
Felipe Balbi, David S . Miller, Christopher Hall
In-Reply-To: <20190926022820.7900-1-jacob.e.keller@intel.com>
Fix all of the drivers which implement support for the periodic output
or external timestamp requests to reject unsupported flags.
This is important for forward compatibility: if a new flag is
introduced, the driver should reject requests to enable the flag until
it has been modified to actually support the flag in question.
This patch may not be correct for individual drivers, especially
regarding the rising vs falling edge flags. I interpreted the default
behavior to be to timestamp the rising edge of a pin transition.
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Christopher Hall <christopher.s.hall@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/dsa/mv88e6xxx/ptp.c | 5 +++++
drivers/net/ethernet/broadcom/tg3.c | 4 ++++
drivers/net/ethernet/intel/igb/igb_ptp.c | 8 ++++++++
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 10 ++++++++++
drivers/net/ethernet/microchip/lan743x_ptp.c | 4 ++++
drivers/net/ethernet/renesas/ravb_ptp.c | 9 +++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 4 ++++
drivers/net/phy/dp83640.c | 8 ++++++++
8 files changed, 52 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
index 073cbd0bb91b..2364b6b67a7b 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.c
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -273,6 +273,11 @@ static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip *chip,
int pin;
int err;
+ /* Reject requests with unsupported flags */
+ if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
+ PTP_RISING_EDGE))
+ return -EOPNOTSUPP;
+
pin = ptp_find_pin(chip->ptp_clock, PTP_PF_EXTTS, rq->extts.index);
if (pin < 0)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 77f3511b97de..ca3aa1250dd1 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6280,6 +6280,10 @@ static int tg3_ptp_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
+ /* Reject requests with unsupported flags */
+ if (rq->perout.flags)
+ return -EOPNOTSUPP;
+
if (rq->perout.index != 0)
return -EINVAL;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index fd3071f55bd3..2867a2581a36 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -521,6 +521,10 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
+ /* Reject requests with unsupported flags */
+ if (rq->extts.flags & ~(PTP_ENABLE_FEATURE | PTP_RISING_EDGE))
+ return -EOPNOTSUPP;
+
if (on) {
pin = ptp_find_pin(igb->ptp_clock, PTP_PF_EXTTS,
rq->extts.index);
@@ -551,6 +555,10 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
return 0;
case PTP_CLK_REQ_PEROUT:
+ /* Reject requests with unsupported flags */
+ if (rq->perout.flags)
+ return -EOPNOTSUPP;
+
if (on) {
pin = ptp_find_pin(igb->ptp_clock, PTP_PF_PEROUT,
rq->perout.index);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 0059b290e095..9a40f24e3193 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -236,6 +236,12 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp,
if (!MLX5_PPS_CAP(mdev))
return -EOPNOTSUPP;
+ /* Reject requests with unsupported flags */
+ if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
+ PTP_RISING_EDGE |
+ PTP_FALLING_EDGE))
+ return -EOPNOTSUPP;
+
if (rq->extts.index >= clock->ptp_info.n_pins)
return -EINVAL;
@@ -290,6 +296,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
if (!MLX5_PPS_CAP(mdev))
return -EOPNOTSUPP;
+ /* Reject requests with unsupported flags */
+ if (rq->perout.flags)
+ return -EOPNOTSUPP;
+
if (rq->perout.index >= clock->ptp_info.n_pins)
return -EINVAL;
diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c
index 57b26c2acf87..e8fe9a90fe4f 100644
--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
+++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
@@ -429,6 +429,10 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on,
int pulse_width = 0;
int perout_bit = 0;
+ /* Reject requests with unsupported flags */
+ if (perout->flags)
+ return -EOPNOTSUPP;
+
if (!on) {
lan743x_ptp_perout_off(adapter);
return 0;
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
index 9a42580693cb..fe66697aafec 100644
--- a/drivers/net/ethernet/renesas/ravb_ptp.c
+++ b/drivers/net/ethernet/renesas/ravb_ptp.c
@@ -182,6 +182,11 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
struct net_device *ndev = priv->ndev;
unsigned long flags;
+ /* Reject requests with unsupported flags */
+ if (req->flags & ~(PTP_ENABLE_FEATURE |
+ PTP_RISING_EDGE))
+ return -EOPNOTSUPP;
+
if (req->index)
return -EINVAL;
@@ -211,6 +216,10 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
unsigned long flags;
int error = 0;
+ /* Reject requests with unsupported flags */
+ if (req->flags)
+ return -EOPNOTSUPP;
+
if (req->index)
return -EINVAL;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 173493db038c..352dc4c68625 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -140,6 +140,10 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
+ /* Reject requests with unsupported flags */
+ if (rq->perout.flags)
+ return -EOPNOTSUPP;
+
cfg = &priv->pps[rq->perout.index];
cfg->start.tv_sec = rq->perout.start.sec;
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 6580094161a9..2781b0e2d947 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -469,6 +469,11 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
+ /* Reject requests with unsupported flags */
+ if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
+ PTP_RISING_EDGE |
+ PTP_FALLING_EDGE))
+ return -EOPNOTSUPP;
index = rq->extts.index;
if (index >= N_EXT_TS)
return -EINVAL;
@@ -491,6 +496,9 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
return 0;
case PTP_CLK_REQ_PEROUT:
+ /* Reject requests with unsupported flags */
+ if (rq->perout.flags)
+ return -EOPNOTSUPP;
if (rq->perout.index >= N_PER_OUT)
return -EINVAL;
return periodic_output(clock, rq, on, rq->perout.index);
--
2.23.0.245.gf157bbb9169d
^ permalink raw reply related
* [net-next v2 1/2] ptp: correctly disable flags on old ioctls
From: Jacob Keller @ 2019-09-26 2:28 UTC (permalink / raw)
To: netdev
Cc: Intel Wired LAN, Jeffrey Kirsher, Jacob Keller, Richard Cochran,
Felipe Balbi, David S . Miller, Christopher Hall
In-Reply-To: <20190926022820.7900-1-jacob.e.keller@intel.com>
Commit 415606588c61 ("PTP: introduce new versions of IOCTLs",
2019-09-13) introduced new versions of the PTP ioctls which actually
validate that the flags are acceptable values.
As part of this, it cleared the flags value using a bitwise
and+negation, in an attempt to prevent the old ioctl from accidentally
enabling new features.
This is incorrect for a couple of reasons. First, it results in
accidentally preventing previously working flags on the request ioctl.
By clearing the "valid" flags, we now no longer allow setting the
enable, rising edge, or falling edge flags.
Second, if we add new additional flags in the future, they must not be
set by the old ioctl. (Since the flag wasn't checked before, we could
potentially break userspace programs which sent garbage flag data.
The correct way to resolve this is to check for and clear all but the
originally valid flags.
Create defines indicating which flags are correctly checked and
interpreted by the original ioctls. Use these to clear any bits which
will not be correctly interpreted by the original ioctls.
In the future, new flags must be added to the VALID_FLAGS macros, but
*not* to the V1_VALID_FLAGS macros. In this way, new features may be
exposed over the v2 ioctls, but without breaking previous userspace
which happened to not clear the flags value properly. The old ioctl will
continue to behave the same way, while the new ioctl gains the benefit
of using the flags fields.
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Christopher Hall <christopher.s.hall@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/ptp/ptp_chardev.c | 4 ++--
include/uapi/linux/ptp_clock.h | 22 ++++++++++++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 9c18476d8d10..67d0199840fd 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -155,7 +155,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EINVAL;
break;
} else if (cmd == PTP_EXTTS_REQUEST) {
- req.extts.flags &= ~PTP_EXTTS_VALID_FLAGS;
+ req.extts.flags &= PTP_EXTTS_V1_VALID_FLAGS;
req.extts.rsv[0] = 0;
req.extts.rsv[1] = 0;
}
@@ -184,7 +184,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EINVAL;
break;
} else if (cmd == PTP_PEROUT_REQUEST) {
- req.perout.flags &= ~PTP_PEROUT_VALID_FLAGS;
+ req.perout.flags &= PTP_PEROUT_V1_VALID_FLAGS;
req.perout.rsv[0] = 0;
req.perout.rsv[1] = 0;
req.perout.rsv[2] = 0;
diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
index f16301015949..59e89a1bc3bb 100644
--- a/include/uapi/linux/ptp_clock.h
+++ b/include/uapi/linux/ptp_clock.h
@@ -31,15 +31,37 @@
#define PTP_ENABLE_FEATURE (1<<0)
#define PTP_RISING_EDGE (1<<1)
#define PTP_FALLING_EDGE (1<<2)
+
+/*
+ * flag fields valid for the new PTP_EXTTS_REQUEST2 ioctl.
+ */
#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \
PTP_RISING_EDGE | \
PTP_FALLING_EDGE)
+/*
+ * flag fields valid for the original PTP_EXTTS_REQUEST ioctl.
+ * DO NOT ADD NEW FLAGS HERE.
+ */
+#define PTP_EXTTS_V1_VALID_FLAGS (PTP_ENABLE_FEATURE | \
+ PTP_RISING_EDGE | \
+ PTP_FALLING_EDGE)
+
/*
* Bits of the ptp_perout_request.flags field:
*/
#define PTP_PEROUT_ONE_SHOT (1<<0)
+
+/*
+ * flag fields valid for the new PTP_PEROUT_REQUEST2 ioctl.
+ */
#define PTP_PEROUT_VALID_FLAGS (PTP_PEROUT_ONE_SHOT)
+
+/*
+ * No flags are valid for the original PTP_PEROUT_REQUEST ioctl
+ */
+#define PTP_PEROUT_V1_VALID_FLAGS (0)
+
/*
* struct ptp_clock_time - represents a time value
*
--
2.23.0.245.gf157bbb9169d
^ permalink raw reply related
* [PATCH v2] net: flow_offload: fix memory leak in nfp_abm_u32_knode_replace
From: Navid Emamdoost @ 2019-09-26 2:22 UTC (permalink / raw)
To: jakub.kicinski
Cc: emamd001, smccaman, kjlu, Navid Emamdoost, David S. Miller,
Pablo Neira Ayuso, John Hurley, Colin Ian King, oss-drivers,
netdev, linux-kernel
In-Reply-To: <20190925182846.69a261e8@cakuba.netronome.com>
In nfp_abm_u32_knode_replace if the allocation for match fails it should
go to the error handling instead of returning.
Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
---
Changes in v2:
- Reused err variable for erorr value returning.
---
drivers/net/ethernet/netronome/nfp/abm/cls.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/abm/cls.c b/drivers/net/ethernet/netronome/nfp/abm/cls.c
index 23ebddfb9532..b0cb9d201f7d 100644
--- a/drivers/net/ethernet/netronome/nfp/abm/cls.c
+++ b/drivers/net/ethernet/netronome/nfp/abm/cls.c
@@ -198,14 +198,18 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
if ((iter->val & cmask) == (val & cmask) &&
iter->band != knode->res->classid) {
NL_SET_ERR_MSG_MOD(extack, "conflict with already offloaded filter");
+ err = -EOPNOTSUPP;
goto err_delete;
}
}
if (!match) {
match = kzalloc(sizeof(*match), GFP_KERNEL);
- if (!match)
- return -ENOMEM;
+ if (!match) {
+ err = -ENOMEM;
+ goto err_delete;
+ }
+
list_add(&match->list, &alink->dscp_map);
}
match->handle = knode->handle;
@@ -221,7 +225,7 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
err_delete:
nfp_abm_u32_knode_delete(alink, knode);
- return -EOPNOTSUPP;
+ return err;
}
static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type,
--
2.17.1
^ permalink raw reply related
* Re: [Intel-wired-lan] [net-next 2/2] net: reject ptp requests with unsupported flags
From: kbuild test robot @ 2019-09-26 2:09 UTC (permalink / raw)
To: Jacob Keller
Cc: kbuild-all, netdev, Christopher Hall, Felipe Balbi,
Richard Cochran, Intel Wired LAN, David S . Miller
In-Reply-To: <20190925233312.13977-3-jacob.e.keller@intel.com>
[-- Attachment #1: Type: text/plain, Size: 3245 bytes --]
Hi Jacob,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net/master]
[cannot apply to v5.3 next-20190924]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Jacob-Keller/ptp-correctly-disable-flags-on-old-ioctls/20190926-073546
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-13) 7.4.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/net/phy/dp83640.c: In function 'ptp_dp83640_enable':
>> drivers/net/phy/dp83640.c:473:27: error: 'PTP_FEATURE_ENABLE' undeclared (first use in this function); did you mean 'DCB_FEATCFG_ENABLE'?
if (rq->extts.flags & ~(PTP_FEATURE_ENABLE |
^~~~~~~~~~~~~~~~~~
DCB_FEATCFG_ENABLE
drivers/net/phy/dp83640.c:473:27: note: each undeclared identifier is reported only once for each function it appears in
vim +473 drivers/net/phy/dp83640.c
460
461 static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
462 struct ptp_clock_request *rq, int on)
463 {
464 struct dp83640_clock *clock =
465 container_of(ptp, struct dp83640_clock, caps);
466 struct phy_device *phydev = clock->chosen->phydev;
467 unsigned int index;
468 u16 evnt, event_num, gpio_num;
469
470 switch (rq->type) {
471 case PTP_CLK_REQ_EXTTS:
472 /* Reject requests with unsupported flags */
> 473 if (rq->extts.flags & ~(PTP_FEATURE_ENABLE |
474 PTP_RISING_EDGE |
475 PTP_FALLING_EDGE))
476 return -EOPNOTSUPP;
477 index = rq->extts.index;
478 if (index >= N_EXT_TS)
479 return -EINVAL;
480 event_num = EXT_EVENT + index;
481 evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
482 if (on) {
483 gpio_num = 1 + ptp_find_pin(clock->ptp_clock,
484 PTP_PF_EXTTS, index);
485 if (gpio_num < 1)
486 return -EINVAL;
487 evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
488 if (rq->extts.flags & PTP_FALLING_EDGE)
489 evnt |= EVNT_FALL;
490 else
491 evnt |= EVNT_RISE;
492 }
493 mutex_lock(&clock->extreg_lock);
494 ext_write(0, phydev, PAGE5, PTP_EVNT, evnt);
495 mutex_unlock(&clock->extreg_lock);
496 return 0;
497
498 case PTP_CLK_REQ_PEROUT:
499 /* Reject requests with unsupported flags */
500 if (rq->perout.flags)
501 return -EOPNOTSUPP;
502 if (rq->perout.index >= N_PER_OUT)
503 return -EINVAL;
504 return periodic_output(clock, rq, on, rq->perout.index);
505
506 default:
507 break;
508 }
509
510 return -EOPNOTSUPP;
511 }
512
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 69878 bytes --]
^ permalink raw reply
* Re: [PATCH] net: flow_offload: fix memory leak in nfp_abm_u32_knode_replace
From: Jakub Kicinski @ 2019-09-26 1:28 UTC (permalink / raw)
To: Navid Emamdoost
Cc: emamd001, smccaman, kjlu, David S. Miller, Pablo Neira Ayuso,
Colin Ian King, oss-drivers, netdev, linux-kernel
In-Reply-To: <20190925183457.32695-1-navid.emamdoost@gmail.com>
On Wed, 25 Sep 2019 13:34:46 -0500, Navid Emamdoost wrote:
> In nfp_abm_u32_knode_replace if the allocation for match fails it should
> go to the error handling instead of returning.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
> ---
> drivers/net/ethernet/netronome/nfp/abm/cls.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/netronome/nfp/abm/cls.c b/drivers/net/ethernet/netronome/nfp/abm/cls.c
> index 23ebddfb9532..32eaab99d96c 100644
> --- a/drivers/net/ethernet/netronome/nfp/abm/cls.c
> +++ b/drivers/net/ethernet/netronome/nfp/abm/cls.c
> @@ -174,7 +174,7 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
> struct nfp_abm_u32_match *match = NULL, *iter;
> unsigned int tos_off;
> u8 mask, val;
> - int err;
> + int err, ret = -EOPNOTSUPP;
You can use the err variable for the return. Please don't break the
reverse christmas tree ordering. Please initialize the err variable
in the branch where failure occurred, not at the start of the function.
> if (!nfp_abm_u32_check_knode(alink->abm, knode, proto, extack))
> goto err_delete;
> @@ -204,8 +204,11 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
>
> if (!match) {
> match = kzalloc(sizeof(*match), GFP_KERNEL);
> - if (!match)
> - return -ENOMEM;
> + if (!match) {
> + ret = -ENOMEM;
> + goto err_delete;
> + }
> +
> list_add(&match->list, &alink->dscp_map);
> }
> match->handle = knode->handle;
> @@ -221,7 +224,7 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink,
>
> err_delete:
> nfp_abm_u32_knode_delete(alink, knode);
> - return -EOPNOTSUPP;
> + return ret;
> }
>
> static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type,
^ permalink raw reply
* Re: [PATCH] nfp: flower: prevent memory leak in nfp_flower_spawn_phy_reprs
From: Jakub Kicinski @ 2019-09-26 1:23 UTC (permalink / raw)
To: Navid Emamdoost
Cc: emamd001, kjlu, smccaman, David S. Miller, John Hurley,
Simon Horman, Pieter Jansen van Vuuren, Fred Lotter, oss-drivers,
netdev, linux-kernel
In-Reply-To: <20190925182405.31287-1-navid.emamdoost@gmail.com>
On Wed, 25 Sep 2019 13:24:02 -0500, Navid Emamdoost wrote:
> In nfp_flower_spawn_phy_reprs, in the for loop over eth_tbl if any of
> intermediate allocations or initializations fail memory is leaked.
> requiered releases are added.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
Fixes: b94524529741 ("nfp: flower: add per repr private data for LAG offload")
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
^ permalink raw reply
* Re: [PATCH] nfp: flower: fix memory leak in nfp_flower_spawn_vnic_reprs
From: Jakub Kicinski @ 2019-09-26 1:22 UTC (permalink / raw)
To: Navid Emamdoost
Cc: emamd001, kjlu, smccaman, David S. Miller, John Hurley,
Simon Horman, Pieter Jansen van Vuuren, Fred Lotter, oss-drivers,
netdev, linux-kernel
In-Reply-To: <20190925190512.3404-1-navid.emamdoost@gmail.com>
On Wed, 25 Sep 2019 14:05:09 -0500, Navid Emamdoost wrote:
> In nfp_flower_spawn_vnic_reprs in the loop if initialization or the
> allocations fail memory is leaked. Appropriate releases are added.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
Fixes: b94524529741 ("nfp: flower: add per repr private data for LAG offload")
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
^ permalink raw reply
* 答复: [PATCH] openvswitch: change type of UPCALL_PID attribute to NLA_UNSPEC
From: Li,Rongqing @ 2019-09-26 1:15 UTC (permalink / raw)
To: Pravin Shelar; +Cc: Linux Kernel Network Developers
In-Reply-To: <CAOrHB_Drgcyxa_2yR4QyyUTkADxT=mdRwPSKOgTrefpnQq5-=g@mail.gmail.com>
> -----邮件原件-----
> 发件人: Pravin Shelar [mailto:pshelar@ovn.org]
> 发送时间: 2019年9月26日 5:03
> 收件人: Li,Rongqing <lirongqing@baidu.com>
> 抄送: Linux Kernel Network Developers <netdev@vger.kernel.org>
> 主题: Re: [PATCH] openvswitch: change type of UPCALL_PID attribute to
> NLA_UNSPEC
>
> On Tue, Sep 24, 2019 at 4:11 AM Li RongQing <lirongqing@baidu.com> wrote:
> >
> > userspace openvswitch patch "(dpif-linux: Implement the API functions
> > to allow multiple handler threads read upcall)"
> > changes its type from U32 to UNSPEC, but leave the kernel unchanged
> >
> > and after kernel 6e237d099fac "(netlink: Relax attr validation for
> > fixed length types)", this bug is exposed by the below warning
> >
> > [ 57.215841] netlink: 'ovs-vswitchd': attribute type 5 has an
> invalid length.
> >
> > Signed-off-by: Li RongQing <lirongqing@baidu.com>
>
> Acked-by: Pravin B Shelar <pshelar@ovn.org>
>
Add a fixes:
Fixes: 5cd667b0a456 ("openvswitch: Allow each vport to have an array of 'port_id's")
-LI
> Thanks,
> Pravin.
^ permalink raw reply
* [PATCH net v2] vsock: Fix a lockdep warning in __vsock_release()
From: Dexuan Cui @ 2019-09-26 1:11 UTC (permalink / raw)
To: davem@davemloft.net, KY Srinivasan, Haiyang Zhang,
Stephen Hemminger, sashal@kernel.org, stefanha@redhat.com,
gregkh@linuxfoundation.org, arnd@arndb.de, deepa.kernel@gmail.com,
Dexuan Cui, ytht.net@gmail.com, tglx@linutronix.de,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hyperv@vger.kernel.org, kvm@vger.kernel.org,
virtualization@lists.linux-foundation.org, Michael Kelley,
sgarzare@redhat.com, jhansen@vmware.com
Lockdep is unhappy if two locks from the same class are held.
Fix the below warning for hyperv and virtio sockets (vmci socket code
doesn't have the issue) by using lock_sock_nested() when __vsock_release()
is called recursively:
============================================
WARNING: possible recursive locking detected
5.3.0+ #1 Not tainted
--------------------------------------------
server/1795 is trying to acquire lock:
ffff8880c5158990 (sk_lock-AF_VSOCK){+.+.}, at: hvs_release+0x10/0x120 [hv_sock]
but task is already holding lock:
ffff8880c5158150 (sk_lock-AF_VSOCK){+.+.}, at: __vsock_release+0x2e/0xf0 [vsock]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(sk_lock-AF_VSOCK);
lock(sk_lock-AF_VSOCK);
*** DEADLOCK ***
May be due to missing lock nesting notation
2 locks held by server/1795:
#0: ffff8880c5d05ff8 (&sb->s_type->i_mutex_key#10){+.+.}, at: __sock_release+0x2d/0xa0
#1: ffff8880c5158150 (sk_lock-AF_VSOCK){+.+.}, at: __vsock_release+0x2e/0xf0 [vsock]
stack backtrace:
CPU: 5 PID: 1795 Comm: server Not tainted 5.3.0+ #1
Call Trace:
dump_stack+0x67/0x90
__lock_acquire.cold.67+0xd2/0x20b
lock_acquire+0xb5/0x1c0
lock_sock_nested+0x6d/0x90
hvs_release+0x10/0x120 [hv_sock]
__vsock_release+0x24/0xf0 [vsock]
__vsock_release+0xa0/0xf0 [vsock]
vsock_release+0x12/0x30 [vsock]
__sock_release+0x37/0xa0
sock_close+0x14/0x20
__fput+0xc1/0x250
task_work_run+0x98/0xc0
do_exit+0x344/0xc60
do_group_exit+0x47/0xb0
get_signal+0x15c/0xc50
do_signal+0x30/0x720
exit_to_usermode_loop+0x50/0xa0
do_syscall_64+0x24e/0x270
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x7f4184e85f31
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---
NOTE: I only tested the code on Hyper-V. I can not test the code for
virtio socket, as I don't have a KVM host. :-( Sorry.
@Stefan, @Stefano: please review & test the patch for virtio socket,
and let me know if the patch breaks anything. Thanks!
Changes in v2:
Avoid the duplication of code in v1: https://lkml.org/lkml/2019/8/19/1361
Also fix virtio socket code.
net/vmw_vsock/af_vsock.c | 19 +++++++++++++++----
net/vmw_vsock/hyperv_transport.c | 2 +-
net/vmw_vsock/virtio_transport_common.c | 2 +-
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index ab47bf3ab66e..dbae4373cbab 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -638,8 +638,10 @@ struct sock *__vsock_create(struct net *net,
}
EXPORT_SYMBOL_GPL(__vsock_create);
-static void __vsock_release(struct sock *sk)
+static void __vsock_release(struct sock *sk, int level)
{
+ WARN_ON(level != 1 && level != 2);
+
if (sk) {
struct sk_buff *skb;
struct sock *pending;
@@ -648,9 +650,18 @@ static void __vsock_release(struct sock *sk)
vsk = vsock_sk(sk);
pending = NULL; /* Compiler warning. */
+ /* The release call is supposed to use lock_sock_nested()
+ * rather than lock_sock(), if a sock lock should be acquired.
+ */
transport->release(vsk);
- lock_sock(sk);
+ /* When "level" is 2, use the nested version to avoid the
+ * warning "possible recursive locking detected".
+ */
+ if (level == 1)
+ lock_sock(sk);
+ else
+ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
sock_orphan(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
@@ -659,7 +670,7 @@ static void __vsock_release(struct sock *sk)
/* Clean up any sockets that never were accepted. */
while ((pending = vsock_dequeue_accept(sk)) != NULL) {
- __vsock_release(pending);
+ __vsock_release(pending, 2);
sock_put(pending);
}
@@ -708,7 +719,7 @@ EXPORT_SYMBOL_GPL(vsock_stream_has_space);
static int vsock_release(struct socket *sock)
{
- __vsock_release(sock->sk);
+ __vsock_release(sock->sk, 1);
sock->sk = NULL;
sock->state = SS_FREE;
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index 261521d286d6..c443db7af8d4 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -559,7 +559,7 @@ static void hvs_release(struct vsock_sock *vsk)
struct sock *sk = sk_vsock(vsk);
bool remove_sock;
- lock_sock(sk);
+ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
remove_sock = hvs_close_lock_held(vsk);
release_sock(sk);
if (remove_sock)
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 5bb70c692b1e..a666ef8fc54e 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -820,7 +820,7 @@ void virtio_transport_release(struct vsock_sock *vsk)
struct sock *sk = &vsk->sk;
bool remove_sock = true;
- lock_sock(sk);
+ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
if (sk->sk_type == SOCK_STREAM)
remove_sock = virtio_transport_close(vsk);
--
2.19.1
^ permalink raw reply related
* RE: [PATCH] vsock: Fix a lockdep warning in __vsock_release()
From: Dexuan Cui @ 2019-09-26 1:10 UTC (permalink / raw)
To: Stefano Garzarella
Cc: jhansen@vmware.com, davem@davemloft.net, stefanha@redhat.com,
netdev@vger.kernel.org, Stephen Hemminger, Sasha Levin,
sashal@kernel.org, Haiyang Zhang, KY Srinivasan, Michael Kelley,
linux-hyperv@vger.kernel.org, gregkh@linuxfoundation.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20190822102529.q5ozdvh6kbymi6ni@steredhat>
> From: Stefano Garzarella <sgarzare@redhat.com>
> Sent: Thursday, August 22, 2019 3:25 AM
> > [...snipped...]
> > --- a/net/vmw_vsock/hyperv_transport.c
> > +++ b/net/vmw_vsock/hyperv_transport.c
> > @@ -559,7 +559,7 @@ static void hvs_release(struct vsock_sock *vsk)
> > struct sock *sk = sk_vsock(vsk);
> > bool remove_sock;
> >
> > - lock_sock(sk);
> > + lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
>
> Should we update also other transports?
>
> Stefano
Hi Stefano,
Sorry for the late reply! I'll post a v2 shortly.
As I checked, hyperv socket and virtio socket need to be fixed.
The vmci socket code doesn't acquire the sock lock in the release
callback, so it doesn't need any fix.
Thanks,
-- Dexuan
^ permalink raw reply
* RE: [PATCH V2 6/8] mdev: introduce virtio device and its device ops
From: Tian, Kevin @ 2019-09-26 0:48 UTC (permalink / raw)
To: Jason Wang, kvm@vger.kernel.org, linux-s390@vger.kernel.org,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
intel-gfx@lists.freedesktop.org,
intel-gvt-dev@lists.freedesktop.org, kwankhede@nvidia.com,
alex.williamson@redhat.com, mst@redhat.com, Bie, Tiwei
Cc: christophe.de.dinechin@gmail.com, sebott@linux.ibm.com,
airlied@linux.ie, joonas.lahtinen@linux.intel.com,
heiko.carstens@de.ibm.com,
virtualization@lists.linux-foundation.org,
rob.miller@broadcom.com, lulu@redhat.com, eperezma@redhat.com,
pasic@linux.ibm.com, borntraeger@de.ibm.com,
haotian.wang@sifive.com, Wang, Zhi A, farman@linux.ibm.com,
idos@mellanox.com, gor@linux.ibm.com, Liang, Cunming,
zhenyuw@linux.intel.com, Vivi, Rodrigo, Wang, Xiao W,
freude@linux.ibm.com, jani.nikula@linux.intel.com,
parav@mellanox.com, Wang, Zhihong, akrowiak@linux.ibm.com,
netdev@vger.kernel.org, cohuck@redhat.com, oberpar@linux.ibm.com,
maxime.coquelin@redhat.com, daniel@ffwll.ch, Zhu, Lingshan
In-Reply-To: <2210d23d-38e4-e654-e53d-7867348de86a@redhat.com>
> From: Jason Wang
> Sent: Wednesday, September 25, 2019 8:45 PM
>
>
> On 2019/9/25 下午5:09, Tian, Kevin wrote:
> >> From: Jason Wang [mailto:jasowang@redhat.com]
> >> Sent: Tuesday, September 24, 2019 9:54 PM
> >>
> >> This patch implements basic support for mdev driver that supports
> >> virtio transport for kernel virtio driver.
> >>
> >> Signed-off-by: Jason Wang <jasowang@redhat.com>
> >> ---
> >> include/linux/mdev.h | 2 +
> >> include/linux/virtio_mdev.h | 145
> >> ++++++++++++++++++++++++++++++++++++
> >> 2 files changed, 147 insertions(+)
> >> create mode 100644 include/linux/virtio_mdev.h
> >>
> >> diff --git a/include/linux/mdev.h b/include/linux/mdev.h
> >> index 3414307311f1..73ac27b3b868 100644
> >> --- a/include/linux/mdev.h
> >> +++ b/include/linux/mdev.h
> >> @@ -126,6 +126,8 @@ struct mdev_device *mdev_from_dev(struct
> device
> >> *dev);
> >>
> >> enum {
> >> MDEV_ID_VFIO = 1,
> >> + MDEV_ID_VIRTIO = 2,
> >> + MDEV_ID_VHOST = 3,
> >> /* New entries must be added here */
> >> };
> >>
> >> diff --git a/include/linux/virtio_mdev.h b/include/linux/virtio_mdev.h
> >> new file mode 100644
> >> index 000000000000..d1a40a739266
> >> --- /dev/null
> >> +++ b/include/linux/virtio_mdev.h
> >> @@ -0,0 +1,145 @@
> >> +/* SPDX-License-Identifier: GPL-2.0-only */
> >> +/*
> >> + * Virtio mediated device driver
> >> + *
> >> + * Copyright 2019, Red Hat Corp.
> >> + * Author: Jason Wang <jasowang@redhat.com>
> >> + */
> >> +#ifndef _LINUX_VIRTIO_MDEV_H
> >> +#define _LINUX_VIRTIO_MDEV_H
> >> +
> >> +#include <linux/interrupt.h>
> >> +#include <linux/mdev.h>
> >> +#include <uapi/linux/vhost.h>
> >> +
> >> +#define VIRTIO_MDEV_DEVICE_API_STRING "virtio-
> mdev"
> >> +#define VIRTIO_MDEV_VERSION 0x1
> > Just be curious. is this version identical to virtio spec version that below
> > callbacks are created for, or just irrelevant?
>
>
> It could be a hint but basically it's a way for userspace driver
> compatibility. For kernel we don't need this.
>
>
> >
> >> +
> >> +struct virtio_mdev_callback {
> >> + irqreturn_t (*callback)(void *data);
> >> + void *private;
> >> +};
> >> +
> >> +/**
> >> + * struct vfio_mdev_device_ops - Structure to be registered for each
> >> + * mdev device to register the device to virtio-mdev module.
> >> + *
> >> + * @set_vq_address: Set the address of virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * @desc_area: address of desc area
> >> + * @driver_area: address of driver area
> >> + * @device_area: address of device area
> >> + * Returns integer: success (0) or error (< 0)
> >> + * @set_vq_num: Set the size of virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * @num: the size of virtqueue
> >> + * @kick_vq: Kick the virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * @set_vq_cb: Set the interrut calback function for
> >> + * a virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * @cb: virtio-mdev interrupt callback
> >> structure
> >> + * @set_vq_ready: Set ready status for a virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * @ready: ready (true) not ready(false)
> >> + * @get_vq_ready: Get ready status for a virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * Returns boolean: ready (true) or not (false)
> >> + * @set_vq_state: Set the state for a virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * @state: virtqueue state (last_avail_idx)
> >> + * Returns integer: success (0) or error (< 0)
> >> + * @get_vq_state: Get the state for a virtqueue
> >> + * @mdev: mediated device
> >> + * @idx: virtqueue index
> >> + * Returns virtqueue state (last_avail_idx)
> >> + * @get_vq_align: Get the virtqueue align requirement
> >> + * for the device
> >> + * @mdev: mediated device
> >> + * Returns virtqueue algin requirement
> >> + * @get_features: Get virtio features supported by the device
> >> + * @mdev: mediated device
> >> + * Returns the features support by the
> >> + * device
> >> + * @get_features: Set virtio features supported by the driver
> >> + * @mdev: mediated device
> >> + * @features: feature support by the driver
> >> + * Returns integer: success (0) or error (< 0)
> >> + * @set_config_cb: Set the config interrupt callback
> >> + * @mdev: mediated device
> >> + * @cb: virtio-mdev interrupt callback
> >> structure
> >> + * @get_device_id: Get virtio device id
> >> + * @mdev: mediated device
> >> + * Returns u32: virtio device id
> >> + * @get_vendor_id: Get virtio vendor id
> >> + * @mdev: mediated device
> >> + * Returns u32: virtio vendor id
> >> + * @get_status: Get the device status
> >> + * @mdev: mediated device
> >> + * Returns u8: virtio device status
> >> + * @set_status: Set the device status
> >> + * @mdev: mediated device
> >> + * @status: virtio device status
> >> + * @get_config: Read from device specific confiugration
> >> space
> > configuration (and similar typos downward)
>
>
> Let me fix.
>
>
> >
> >> + * @mdev: mediated device
> >> + * @offset: offset from the beginning of
> >> + * configuration space
> >> + * @buf: buffer used to read to
> >> + * @len: the length to read from
> >> + * configration space
> >> + * @set_config: Write to device specific confiugration space
> >> + * @mdev: mediated device
> >> + * @offset: offset from the beginning of
> >> + * configuration space
> >> + * @buf: buffer used to write from
> >> + * @len: the length to write to
> >> + * configration space
> >> + * @get_version: Get the version of virtio mdev device
> >> + * @mdev: mediated device
> >> + * Returns integer: version of the device
> >> + * @get_generation: Get device generaton
> >> + * @mdev: mediated device
> >> + * Returns u32: device generation
> >> + */
> >> +struct virtio_mdev_device_ops {
> >> + /* Virtqueue ops */
> >> + int (*set_vq_address)(struct mdev_device *mdev,
> >> + u16 idx, u64 desc_area, u64 driver_area,
> >> + u64 device_area);
> >> + void (*set_vq_num)(struct mdev_device *mdev, u16 idx, u32 num);
> >> + void (*kick_vq)(struct mdev_device *mdev, u16 idx);
> >> + void (*set_vq_cb)(struct mdev_device *mdev, u16 idx,
> >> + struct virtio_mdev_callback *cb);
> >> + void (*set_vq_ready)(struct mdev_device *mdev, u16 idx, bool
> >> ready);
> >> + bool (*get_vq_ready)(struct mdev_device *mdev, u16 idx);
> >> + int (*set_vq_state)(struct mdev_device *mdev, u16 idx, u64 state);
> >> + u64 (*get_vq_state)(struct mdev_device *mdev, u16 idx);
> >> +
> >> + /* Device ops */
> >> + u16 (*get_vq_align)(struct mdev_device *mdev);
> >> + u64 (*get_features)(struct mdev_device *mdev);
> >> + int (*set_features)(struct mdev_device *mdev, u64 features);
> >> + void (*set_config_cb)(struct mdev_device *mdev,
> >> + struct virtio_mdev_callback *cb);
> >> + u16 (*get_queue_max)(struct mdev_device *mdev);
> >> + u32 (*get_device_id)(struct mdev_device *mdev);
> >> + u32 (*get_vendor_id)(struct mdev_device *mdev);
> >> + u8 (*get_status)(struct mdev_device *mdev);
> >> + void (*set_status)(struct mdev_device *mdev, u8 status);
> >> + void (*get_config)(struct mdev_device *mdev, unsigned int offset,
> >> + void *buf, unsigned int len);
> >> + void (*set_config)(struct mdev_device *mdev, unsigned int offset,
> >> + const void *buf, unsigned int len);
> >> + int (*get_version)(struct mdev_device *mdev);
> >> + u32 (*get_generation)(struct mdev_device *mdev);
> >> +};
> > I'm not sure how stable above ops are.
>
>
> It's the kernel internal API, so there's no strict requirement for this.
> We will export a version value for userspace for compatibility.
>
>
> > Does it make sense if defining
> > just two callbacks here, e.g. vq_ctrl and device_ctrl, and then let the
> > vendor driver to handle specific ops in each category (similar to how
> > ioctl works)?
>
>
> My understanding is that it introduce another indirection, you still
> need to differ from different command, and it's less flexible than
> direct callback.
>
> What's the value of doing this?
>
I just thought doing so may provide better compatibility to the
parent driver. Even when new op is introduced, a parent driver
that was developed against the old set can still be loaded in the
new kernel. It just returns error when unrecognized ops are
routed through vq_ctrl and device_ctrl, if the userspace doesn't
favor the exposed version value. But if above ops set is pretty
stable, then this comment can be ignored.
Thanks
Kevin
^ 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