* [PATCH net] net: ena: Add dependency for ENA_ETHERNET
From: Mao Wenan @ 2019-09-20 8:44 UTC (permalink / raw)
To: netanel, saeedb, zorik, davem
Cc: netdev, linux-kernel, kernel-janitors, Mao Wenan
If CONFIG_ENA_ETHERNET=y and CONFIG_DIMLIB=n,
below erros can be found:
drivers/net/ethernet/amazon/ena/ena_netdev.o: In function `ena_dim_work':
ena_netdev.c:(.text+0x21cc): undefined reference to `net_dim_get_rx_moderation'
ena_netdev.c:(.text+0x21cc): relocation truncated to
fit: R_AARCH64_CALL26 against undefined symbol `net_dim_get_rx_moderation'
drivers/net/ethernet/amazon/ena/ena_netdev.o: In function `ena_io_poll':
ena_netdev.c:(.text+0x7bd4): undefined reference to `net_dim'
ena_netdev.c:(.text+0x7bd4): relocation truncated to fit:
R_AARCH64_CALL26 against undefined symbol `net_dim'
After commit 282faf61a053 ("net: ena: switch to dim algorithm for rx adaptive
interrupt moderation"), it introduces dim algorithm, which configured by CONFIG_DIMLIB.
Fixes: 282faf61a053 ("net: ena: switch to dim algorithm for rx adaptive interrupt moderation")
Signed-off-by: Mao Wenan <maowenan@huawei.com>
---
drivers/net/ethernet/amazon/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amazon/Kconfig b/drivers/net/ethernet/amazon/Kconfig
index 69ca99d..fe46df4 100644
--- a/drivers/net/ethernet/amazon/Kconfig
+++ b/drivers/net/ethernet/amazon/Kconfig
@@ -18,7 +18,7 @@ if NET_VENDOR_AMAZON
config ENA_ETHERNET
tristate "Elastic Network Adapter (ENA) support"
- depends on PCI_MSI && !CPU_BIG_ENDIAN
+ depends on PCI_MSI && !CPU_BIG_ENDIAN && DIMLIB
---help---
This driver supports Elastic Network Adapter (ENA)"
--
2.7.4
^ permalink raw reply related
* [RFC PATCH V2 5/6] vringh: fix copy direction of vringh_iov_push_kern()
From: Jason Wang @ 2019-09-20 8:20 UTC (permalink / raw)
To: kvm, linux-s390, linux-kernel, dri-devel, intel-gfx,
intel-gvt-dev, kwankhede, alex.williamson, mst, tiwei.bie
Cc: virtualization, netdev, cohuck, maxime.coquelin, cunming.liang,
zhihong.wang, rob.miller, xiao.w.wang, haotian.wang, zhenyuw,
zhi.a.wang, jani.nikula, joonas.lahtinen, rodrigo.vivi, airlied,
daniel, farman, pasic, sebott, oberpar, heiko.carstens, gor,
borntraeger, akrowiak, pmorel, freude, lingshan.zhu, idos,
eperezma, lulu, Jason Wang
In-Reply-To: <20190920082050.19352-1-jasowang@redhat.com>
We want to copy from iov to buf, so the direction was wrong.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/vringh.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index 08ad0d1f0476..a0a2d74967ef 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -852,6 +852,12 @@ static inline int xfer_kern(void *src, void *dst, size_t len)
return 0;
}
+static inline int kern_xfer(void *dst, void *src, size_t len)
+{
+ memcpy(dst, src, len);
+ return 0;
+}
+
/**
* vringh_init_kern - initialize a vringh for a kernelspace vring.
* @vrh: the vringh to initialize.
@@ -958,7 +964,7 @@ EXPORT_SYMBOL(vringh_iov_pull_kern);
ssize_t vringh_iov_push_kern(struct vringh_kiov *wiov,
const void *src, size_t len)
{
- return vringh_iov_xfer(wiov, (void *)src, len, xfer_kern);
+ return vringh_iov_xfer(wiov, (void *)src, len, kern_xfer);
}
EXPORT_SYMBOL(vringh_iov_push_kern);
--
2.19.1
^ permalink raw reply related
* [RFC PATCH V2 6/6] docs: Sample driver to demonstrate how to implement virtio-mdev framework
From: Jason Wang @ 2019-09-20 8:20 UTC (permalink / raw)
To: kvm, linux-s390, linux-kernel, dri-devel, intel-gfx,
intel-gvt-dev, kwankhede, alex.williamson, mst, tiwei.bie
Cc: virtualization, netdev, cohuck, maxime.coquelin, cunming.liang,
zhihong.wang, rob.miller, xiao.w.wang, haotian.wang, zhenyuw,
zhi.a.wang, jani.nikula, joonas.lahtinen, rodrigo.vivi, airlied,
daniel, farman, pasic, sebott, oberpar, heiko.carstens, gor,
borntraeger, akrowiak, pmorel, freude, lingshan.zhu, idos,
eperezma, lulu, Jason Wang
In-Reply-To: <20190920082050.19352-1-jasowang@redhat.com>
This sample driver creates mdev device that simulate virtio net device
over virtio mdev transport. The device is implemented through vringh
and workqueue. A device specific dma ops is to make sure HVA is used
directly as the IOVA. This should be sufficient for kernel virtio
driver to work.
No more work for userspace VFIO based vhost-mdev driver to work. E.g
through notifier, it will be addressed in the future.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
samples/Kconfig | 7 +
samples/vfio-mdev/Makefile | 1 +
samples/vfio-mdev/mvnet.c | 688 +++++++++++++++++++++++++++++++++++++
3 files changed, 696 insertions(+)
create mode 100644 samples/vfio-mdev/mvnet.c
diff --git a/samples/Kconfig b/samples/Kconfig
index c8dacb4dda80..a1a1ca2c00b7 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -131,6 +131,13 @@ config SAMPLE_VFIO_MDEV_MDPY
mediated device. It is a simple framebuffer and supports
the region display interface (VFIO_GFX_PLANE_TYPE_REGION).
+config SAMPLE_VIRTIO_MDEV_NET
+ tristate "Build virtio mdev net example mediated device sample code -- loadable modules only"
+ depends on VIRTIO_MDEV_DEVICE && VHOST_RING && m
+ help
+ Build a networking sample device for use as a virtio
+ mediated device.
+
config SAMPLE_VFIO_MDEV_MDPY_FB
tristate "Build VFIO mdpy example guest fbdev driver -- loadable module only"
depends on FB && m
diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile
index 10d179c4fdeb..f34af90ed0a0 100644
--- a/samples/vfio-mdev/Makefile
+++ b/samples/vfio-mdev/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o
obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY) += mdpy.o
obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB) += mdpy-fb.o
obj-$(CONFIG_SAMPLE_VFIO_MDEV_MBOCHS) += mbochs.o
+obj-$(CONFIG_SAMPLE_VIRTIO_MDEV_NET) += mvnet.o
diff --git a/samples/vfio-mdev/mvnet.c b/samples/vfio-mdev/mvnet.c
new file mode 100644
index 000000000000..e1036e753c76
--- /dev/null
+++ b/samples/vfio-mdev/mvnet.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Mediated virtual virtio-net device driver.
+ *
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
+ * Author: Jason Wang <jasowang@redhat.com>
+ *
+ * Sample driver that creates mdev device that simulates ethernet loopback
+ * device.
+ *
+ * Usage:
+ *
+ * # modprobe virtio_mdev
+ * # modprobe mvnet
+ * # cd /sys/devices/virtual/mvnet/mvnet/mdev_supported_types/mvnet-
+ * # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" > ./create
+ * # cd devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001
+ * # ls -d virtio0
+ * virtio0
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/uuid.h>
+#include <linux/iommu.h>
+#include <linux/sysfs.h>
+#include <linux/file.h>
+#include <linux/etherdevice.h>
+#include <linux/mdev.h>
+#include <linux/vringh.h>
+#include <linux/virtio_mdev.h>
+#include <uapi/linux/virtio_config.h>
+#include <uapi/linux/virtio_net.h>
+
+#define VERSION_STRING "0.1"
+#define DRIVER_AUTHOR "Red Hat Corporation"
+
+#define MVNET_CLASS_NAME "mvnet"
+#define MVNET_NAME "mvnet"
+
+/*
+ * Global Structures
+ */
+
+static struct mvnet_dev {
+ struct class *vd_class;
+ struct idr vd_idr;
+ struct device dev;
+} mvnet_dev;
+
+struct mvnet_virtqueue {
+ struct vringh vring;
+ struct vringh_kiov iov;
+ unsigned short head;
+ bool ready;
+ u64 desc_addr;
+ u64 device_addr;
+ u64 driver_addr;
+ u32 num;
+ void *private;
+ irqreturn_t (*cb)(void *);
+};
+
+#define MVNET_QUEUE_ALIGN PAGE_SIZE
+#define MVNET_QUEUE_MAX 256
+#define MVNET_DEVICE_ID 0x1
+#define MVNET_VENDOR_ID 0
+
+u64 mvnet_features = (1ULL << VIRTIO_F_ANY_LAYOUT) |
+ (1ULL << VIRTIO_F_VERSION_1) |
+ (1ULL << VIRTIO_F_IOMMU_PLATFORM) ;
+
+/* State of each mdev device */
+struct mvnet_state {
+ struct mvnet_virtqueue vqs[2];
+ struct work_struct work;
+ spinlock_t lock;
+ struct mdev_device *mdev;
+ struct virtio_net_config config;
+ void *buffer;
+ u32 status;
+ u32 generation;
+ u64 features;
+ struct list_head next;
+};
+
+static struct mutex mdev_list_lock;
+static struct list_head mdev_devices_list;
+
+static void mvnet_queue_ready(struct mvnet_state *mvnet, unsigned idx)
+{
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+ int ret;
+
+ ret = vringh_init_kern(&vq->vring, mvnet_features, MVNET_QUEUE_MAX,
+ false, (struct vring_desc *)vq->desc_addr,
+ (struct vring_avail *)vq->driver_addr,
+ (struct vring_used *)vq->device_addr);
+}
+
+static void mvnet_vq_reset(struct mvnet_virtqueue *vq)
+{
+ vq->ready = 0;
+ vq->desc_addr = 0;
+ vq->driver_addr = 0;
+ vq->device_addr = 0;
+ vq->cb = NULL;
+ vq->private = NULL;
+ vringh_init_kern(&vq->vring, mvnet_features, MVNET_QUEUE_MAX,
+ false, 0, 0, 0);
+}
+
+static void mvnet_reset(struct mvnet_state *mvnet)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ mvnet_vq_reset(&mvnet->vqs[i]);
+
+ mvnet->features = 0;
+ mvnet->status = 0;
+ ++mvnet->generation;
+}
+
+static void mvnet_work(struct work_struct *work)
+{
+ struct mvnet_state *mvnet = container_of(work, struct
+ mvnet_state, work);
+ struct mvnet_virtqueue *txq = &mvnet->vqs[1];
+ struct mvnet_virtqueue *rxq = &mvnet->vqs[0];
+ size_t read, write, total_write;
+ int err;
+ int pkts = 0;
+
+ spin_lock(&mvnet->lock);
+
+ if (!txq->ready || !rxq->ready)
+ goto out;
+
+ while (true) {
+ total_write = 0;
+ err = vringh_getdesc_kern(&txq->vring, &txq->iov, NULL,
+ &txq->head, GFP_ATOMIC);
+ if (err <= 0)
+ break;
+
+ err = vringh_getdesc_kern(&rxq->vring, NULL, &rxq->iov,
+ &rxq->head, GFP_ATOMIC);
+ if (err <= 0) {
+ vringh_complete_kern(&txq->vring, txq->head, 0);
+ break;
+ }
+
+ while (true) {
+ read = vringh_iov_pull_kern(&txq->iov, mvnet->buffer,
+ PAGE_SIZE);
+ if (read <= 0)
+ break;
+
+ write = vringh_iov_push_kern(&rxq->iov, mvnet->buffer,
+ read);
+ if (write <= 0)
+ break;
+
+ total_write += write;
+ }
+
+ /* Make sure data is wrote before advancing index */
+ smp_wmb();
+
+ vringh_complete_kern(&txq->vring, txq->head, 0);
+ vringh_complete_kern(&rxq->vring, rxq->head, total_write);
+
+ /* Make sure used is visible before rasing the
+ interrupt */
+ smp_wmb();
+
+ local_bh_disable();
+ if (txq->cb)
+ txq->cb(txq->private);
+ if (rxq->cb)
+ rxq->cb(rxq->private);
+ local_bh_enable();
+
+ if (++pkts > 4) {
+ schedule_work(&mvnet->work);
+ goto out;
+ }
+ }
+
+out:
+ spin_unlock(&mvnet->lock);
+}
+
+static dma_addr_t mvnet_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ /* Vringh can only use HVA */
+ return (dma_addr_t)(page_address(page) + offset);
+}
+
+static void mvnet_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ return ;
+}
+
+static void *mvnet_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_addr, gfp_t flag,
+ unsigned long attrs)
+{
+ void *addr = kmalloc(size, flag);
+
+ if (addr == NULL)
+ *dma_addr = DMA_MAPPING_ERROR;
+ else
+ *dma_addr = (dma_addr_t) addr;
+
+ return addr;
+}
+
+static void mvnet_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_addr,
+ unsigned long attrs)
+{
+ kfree((void *)dma_addr);
+}
+
+static const struct dma_map_ops mvnet_dma_ops = {
+ .map_page = mvnet_map_page,
+ .unmap_page = mvnet_unmap_page,
+ .alloc = mvnet_alloc_coherent,
+ .free = mvnet_free_coherent,
+};
+
+static int mvnet_create(struct kobject *kobj, struct mdev_device *mdev)
+{
+ struct mvnet_state *mvnet;
+ struct virtio_net_config *config;
+ struct device *dev = mdev_dev(mdev);
+
+ if (!mdev)
+ return -EINVAL;
+
+ mvnet = kzalloc(sizeof(struct mvnet_state), GFP_KERNEL);
+ if (mvnet == NULL)
+ return -ENOMEM;
+
+ mvnet->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!mvnet->buffer) {
+ kfree(mvnet);
+ return -ENOMEM;
+ }
+
+ config = &mvnet->config;
+ config->mtu = 1500;
+ config->status = VIRTIO_NET_S_LINK_UP;
+ eth_random_addr(config->mac);
+
+ INIT_WORK(&mvnet->work, mvnet_work);
+
+ spin_lock_init(&mvnet->lock);
+ mvnet->mdev = mdev;
+ mdev_set_drvdata(mdev, mvnet);
+
+ mutex_lock(&mdev_list_lock);
+ list_add(&mvnet->next, &mdev_devices_list);
+ mutex_unlock(&mdev_list_lock);
+
+ dev->coherent_dma_mask = DMA_BIT_MASK(64);
+ set_dma_ops(dev, &mvnet_dma_ops);
+
+ return 0;
+}
+
+static int mvnet_remove(struct mdev_device *mdev)
+{
+ struct mvnet_state *mds, *tmp_mds;
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ int ret = -EINVAL;
+
+ mutex_lock(&mdev_list_lock);
+ list_for_each_entry_safe(mds, tmp_mds, &mdev_devices_list, next) {
+ if (mvnet == mds) {
+ list_del(&mvnet->next);
+ mdev_set_drvdata(mdev, NULL);
+ kfree(mvnet->buffer);
+ kfree(mvnet);
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&mdev_list_lock);
+
+ return ret;
+}
+
+static ssize_t
+sample_mvnet_dev_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ if (mdev_from_dev(dev))
+ return sprintf(buf, "This is MDEV %s\n", dev_name(dev));
+
+ return sprintf(buf, "\n");
+}
+
+static DEVICE_ATTR_RO(sample_mvnet_dev);
+
+static struct attribute *mvnet_dev_attrs[] = {
+ &dev_attr_sample_mvnet_dev.attr,
+ NULL,
+};
+
+static const struct attribute_group mvnet_dev_group = {
+ .name = "mvnet_dev",
+ .attrs = mvnet_dev_attrs,
+};
+
+static const struct attribute_group *mvnet_dev_groups[] = {
+ &mvnet_dev_group,
+ NULL,
+};
+
+static ssize_t
+sample_mdev_dev_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ if (mdev_from_dev(dev))
+ return sprintf(buf, "This is MDEV %s\n", dev_name(dev));
+
+ return sprintf(buf, "\n");
+}
+
+static DEVICE_ATTR_RO(sample_mdev_dev);
+
+static struct attribute *mdev_dev_attrs[] = {
+ &dev_attr_sample_mdev_dev.attr,
+ NULL,
+};
+
+static const struct attribute_group mdev_dev_group = {
+ .name = "vendor",
+ .attrs = mdev_dev_attrs,
+};
+
+static const struct attribute_group *mdev_dev_groups[] = {
+ &mdev_dev_group,
+ NULL,
+};
+
+#define MVNET_STRING_LEN 16
+
+static ssize_t
+name_show(struct kobject *kobj, struct device *dev, char *buf)
+{
+ char name[MVNET_STRING_LEN];
+ const char *name_str = "virtio-net";
+
+ snprintf(name, MVNET_STRING_LEN, "%s", dev_driver_string(dev));
+ if (!strcmp(kobj->name, name))
+ return sprintf(buf, "%s\n", name_str);
+
+ return -EINVAL;
+}
+
+static MDEV_TYPE_ATTR_RO(name);
+
+static ssize_t
+available_instances_show(struct kobject *kobj, struct device *dev, char *buf)
+{
+ return sprintf(buf, "%d\n", INT_MAX);
+}
+
+static MDEV_TYPE_ATTR_RO(available_instances);
+
+static ssize_t device_api_show(struct kobject *kobj, struct device *dev,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", VIRTIO_MDEV_DEVICE_API_STRING);
+}
+
+static MDEV_TYPE_ATTR_RO(device_api);
+
+static struct attribute *mdev_types_attrs[] = {
+ &mdev_type_attr_name.attr,
+ &mdev_type_attr_device_api.attr,
+ &mdev_type_attr_available_instances.attr,
+ NULL,
+};
+
+static struct attribute_group mdev_type_group = {
+ .name = "",
+ .attrs = mdev_types_attrs,
+};
+
+static struct attribute_group *mdev_type_groups[] = {
+ &mdev_type_group,
+ NULL,
+};
+
+static int mvnet_set_vq_address(struct mdev_device *mdev, u16 idx,
+ u64 desc_area, u64 driver_area, u64 device_area)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+
+ vq->desc_addr = desc_area;
+ vq->driver_addr = driver_area;
+ vq->device_addr = device_area;
+
+ return 0;
+}
+
+static void mvnet_set_vq_num(struct mdev_device *mdev, u16 idx, u32 num)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+
+ vq->num = num;
+}
+
+static void mvnet_kick_vq(struct mdev_device *mdev, u16 idx)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+
+ if (vq->ready)
+ schedule_work(&mvnet->work);
+}
+
+static void mvnet_set_vq_cb(struct mdev_device *mdev, u16 idx,
+ struct virtio_mdev_callback *cb)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+
+ vq->cb = cb->callback;
+ vq->private = cb->private;
+}
+
+static void mvnet_set_vq_ready(struct mdev_device *mdev, u16 idx, bool ready)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+
+ spin_lock(&mvnet->lock);
+ vq->ready = ready;
+ if (vq->ready)
+ mvnet_queue_ready(mvnet, idx);
+ spin_unlock(&mvnet->lock);
+}
+
+static bool mvnet_get_vq_ready(struct mdev_device *mdev, u16 idx)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+
+ return vq->ready;
+}
+
+static int mvnet_set_vq_state(struct mdev_device *mdev, u16 idx, u64 state)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+ struct vringh *vrh = &vq->vring;
+
+ spin_lock(&mvnet->lock);
+ vrh->last_avail_idx = state;
+ spin_unlock(&mvnet->lock);
+
+ return 0;
+}
+
+static u64 mvnet_get_vq_state(struct mdev_device *mdev, u16 idx)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+ struct mvnet_virtqueue *vq = &mvnet->vqs[idx];
+ struct vringh *vrh = &vq->vring;
+
+ return vrh->last_avail_idx;
+}
+
+static u16 mvnet_get_vq_align(struct mdev_device *mdev)
+{
+ return MVNET_QUEUE_ALIGN;
+}
+
+static u64 mvnet_get_features(struct mdev_device *mdev)
+{
+ return mvnet_features;
+}
+
+static int mvnet_set_features(struct mdev_device *mdev, u64 features)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+
+ /* DMA mapping must be done by driver */
+ if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
+ return -EINVAL;
+
+ mvnet->features = features & mvnet_features;
+
+ return 0;
+}
+
+static void mvnet_set_config_cb(struct mdev_device *mdev,
+ struct virtio_mdev_callback *cb)
+{
+ /* We don't support config interrupt */
+}
+
+static u16 mvnet_get_queue_max(struct mdev_device *mdev)
+{
+ return MVNET_QUEUE_MAX;
+}
+
+static u32 mvnet_get_device_id(struct mdev_device *mdev)
+{
+ return MVNET_DEVICE_ID;
+}
+
+static u32 mvnet_get_vendor_id(struct mdev_device *mdev)
+{
+ return MVNET_VENDOR_ID;
+}
+
+static u8 mvnet_get_status(struct mdev_device *mdev)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+
+ return mvnet->status;
+}
+
+static void mvnet_set_status(struct mdev_device *mdev, u8 status)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+
+ mvnet->status = status;
+
+ if (status == 0) {
+ spin_lock(&mvnet->lock);
+ mvnet_reset(mvnet);
+ spin_unlock(&mvnet->lock);
+ }
+}
+
+static void mvnet_get_config(struct mdev_device *mdev, unsigned offset,
+ void *buf, unsigned len)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+
+ if (offset + len < sizeof(struct virtio_net_config))
+ memcpy(buf, &mvnet->config + offset, len);
+}
+
+static void mvnet_set_config(struct mdev_device *mdev, unsigned offset,
+ const void *buf, unsigned len)
+{
+ /* No writable config supportted by mvnet */
+}
+
+static int mvnet_get_version(struct mdev_device *mdev)
+{
+ return 0x1;
+}
+
+static u32 mvnet_get_generation(struct mdev_device *mdev)
+{
+ struct mvnet_state *mvnet = mdev_get_drvdata(mdev);
+
+ return mvnet->generation;
+}
+
+static const struct virtio_mdev_parent_ops virtio_mdev_ops = {
+ .set_vq_address = mvnet_set_vq_address,
+ .set_vq_num = mvnet_set_vq_num,
+ .kick_vq = mvnet_kick_vq,
+ .set_vq_cb = mvnet_set_vq_cb,
+ .set_vq_ready = mvnet_set_vq_ready,
+ .get_vq_ready = mvnet_get_vq_ready,
+ .set_vq_state = mvnet_set_vq_state,
+ .get_vq_state = mvnet_get_vq_state,
+ .get_vq_align = mvnet_get_vq_align,
+ .get_features = mvnet_get_features,
+ .set_features = mvnet_set_features,
+ .set_config_cb = mvnet_set_config_cb,
+ .get_queue_max = mvnet_get_queue_max,
+ .get_device_id = mvnet_get_device_id,
+ .get_vendor_id = mvnet_get_vendor_id,
+ .get_status = mvnet_get_status,
+ .set_status = mvnet_set_status,
+ .get_config = mvnet_get_config,
+ .set_config = mvnet_set_config,
+ .get_version = mvnet_get_version,
+ .get_generation = mvnet_get_generation,
+};
+
+static const struct mdev_parent_ops mdev_fops = {
+ .owner = THIS_MODULE,
+ .dev_attr_groups = mvnet_dev_groups,
+ .mdev_attr_groups = mdev_dev_groups,
+ .supported_type_groups = mdev_type_groups,
+ .create = mvnet_create,
+ .remove = mvnet_remove,
+ .device_ops = &virtio_mdev_ops,
+};
+
+static void mvnet_device_release(struct device *dev)
+{
+ dev_dbg(dev, "mvnet: released\n");
+}
+
+static int __init mvnet_dev_init(void)
+{
+ int ret = 0;
+
+ pr_info("mvnet_dev: %s\n", __func__);
+
+ memset(&mvnet_dev, 0, sizeof(mvnet_dev));
+
+ idr_init(&mvnet_dev.vd_idr);
+
+ mvnet_dev.vd_class = class_create(THIS_MODULE, MVNET_CLASS_NAME);
+
+ if (IS_ERR(mvnet_dev.vd_class)) {
+ pr_err("Error: failed to register mvnet_dev class\n");
+ ret = PTR_ERR(mvnet_dev.vd_class);
+ goto failed1;
+ }
+
+ mvnet_dev.dev.class = mvnet_dev.vd_class;
+ mvnet_dev.dev.release = mvnet_device_release;
+ dev_set_name(&mvnet_dev.dev, "%s", MVNET_NAME);
+
+ ret = device_register(&mvnet_dev.dev);
+ if (ret)
+ goto failed2;
+
+ ret = mdev_register_virtio_device(&mvnet_dev.dev, &mdev_fops);
+ if (ret)
+ goto failed3;
+
+ mutex_init(&mdev_list_lock);
+ INIT_LIST_HEAD(&mdev_devices_list);
+
+ goto all_done;
+
+failed3:
+
+ device_unregister(&mvnet_dev.dev);
+failed2:
+ class_destroy(mvnet_dev.vd_class);
+
+failed1:
+all_done:
+ return ret;
+}
+
+static void __exit mvnet_dev_exit(void)
+{
+ mvnet_dev.dev.bus = NULL;
+ mdev_unregister_device(&mvnet_dev.dev);
+
+ device_unregister(&mvnet_dev.dev);
+ idr_destroy(&mvnet_dev.vd_idr);
+ class_destroy(mvnet_dev.vd_class);
+ mvnet_dev.vd_class = NULL;
+ pr_info("mvnet_dev: Unloaded!\n");
+}
+
+module_init(mvnet_dev_init)
+module_exit(mvnet_dev_exit)
+
+MODULE_LICENSE("GPL v2");
+MODULE_INFO(supported, "Test driver that simulate serial port over PCI");
+MODULE_VERSION(VERSION_STRING);
+MODULE_AUTHOR(DRIVER_AUTHOR);
--
2.19.1
^ permalink raw reply related
* [PATCH v2 3/3] seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE
From: Christian Brauner @ 2019-09-20 8:30 UTC (permalink / raw)
To: keescook, luto
Cc: jannh, wad, shuah, ast, daniel, kafai, songliubraving, yhs,
linux-kernel, linux-kselftest, netdev, bpf, Christian Brauner,
Tycho Andersen, Tyler Hicks, stable
In-Reply-To: <20190920083007.11475-1-christian.brauner@ubuntu.com>
Test whether a syscall can be performed after having been intercepted by
the seccomp notifier. The test uses dup() and kcmp() since it allows us to
nicely test whether the dup() syscall actually succeeded by comparing whether
the fds refer to the same underlying struct file.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Song Liu <songliubraving@fb.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: Tycho Andersen <tycho@tycho.ws>
CC: Tyler Hicks <tyhicks@canonical.com>
Cc: stable@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: bpf@vger.kernel.org
---
/* v2 */
- Shuah Khan <shuah@kernel.org>:
- skip test on missing precondition
/* v1 */
Link: https://lore.kernel.org/r/20190919095903.19370-4-christian.brauner@ubuntu.com
- Christian Brauner <christian.brauner@ubuntu.com>:
- adapt to new flag name SECCOMP_USER_NOTIF_FLAG_CONTINUE
/* v0 */
Link: https://lore.kernel.org/r/20190918084833.9369-5-christian.brauner@ubuntu.com
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 107 ++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index e996d7b7fd6e..2519377ebda3 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -44,6 +44,7 @@
#include <sys/times.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <linux/kcmp.h>
#include <unistd.h>
#include <sys/syscall.h>
@@ -167,6 +168,10 @@ struct seccomp_metadata {
#define SECCOMP_RET_USER_NOTIF 0x7fc00000U
+#ifndef SECCOMP_USER_NOTIF_FLAG_CONTINUE
+#define SECCOMP_USER_NOTIF_FLAG_CONTINUE 0x00000001
+#endif
+
#define SECCOMP_IOC_MAGIC '!'
#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr)
#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type)
@@ -3481,6 +3486,108 @@ TEST(seccomp_get_notif_sizes)
EXPECT_EQ(sizes.seccomp_notif_resp, sizeof(struct seccomp_notif_resp));
}
+static int filecmp(pid_t pid1, pid_t pid2, int fd1, int fd2)
+{
+#ifdef __NR_kcmp
+ return syscall(__NR_kcmp, pid1, pid2, KCMP_FILE, fd1, fd2);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+TEST(user_notification_continue)
+{
+ pid_t pid;
+ long ret;
+ int status, listener;
+ struct seccomp_notif req = {};
+ struct seccomp_notif_resp resp = {};
+ struct pollfd pollfd;
+
+ ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ ASSERT_EQ(0, ret) {
+ TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+ }
+
+ listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER);
+ ASSERT_GE(listener, 0);
+
+ pid = fork();
+ ASSERT_GE(pid, 0);
+
+ if (pid == 0) {
+ int dup_fd, pipe_fds[2];
+ pid_t self;
+
+ ret = pipe(pipe_fds);
+ if (ret < 0)
+ exit(1);
+
+ dup_fd = dup(pipe_fds[0]);
+ if (dup_fd < 0)
+ exit(1);
+
+ self = getpid();
+
+ ret = filecmp(self, self, pipe_fds[0], dup_fd);
+ if (ret)
+ exit(2);
+
+ exit(0);
+ }
+
+ pollfd.fd = listener;
+ pollfd.events = POLLIN | POLLOUT;
+
+ EXPECT_GT(poll(&pollfd, 1, -1), 0);
+ EXPECT_EQ(pollfd.revents, POLLIN);
+
+ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0);
+
+ pollfd.fd = listener;
+ pollfd.events = POLLIN | POLLOUT;
+
+ EXPECT_GT(poll(&pollfd, 1, -1), 0);
+ EXPECT_EQ(pollfd.revents, POLLOUT);
+
+ EXPECT_EQ(req.data.nr, __NR_dup);
+
+ resp.id = req.id;
+ resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;
+
+ /*
+ * Verify that setting SECCOMP_USER_NOTIF_FLAG_CONTINUE enforces other
+ * args be set to 0.
+ */
+ resp.error = 0;
+ resp.val = USER_NOTIF_MAGIC;
+ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1);
+ EXPECT_EQ(errno, EINVAL);
+
+ resp.error = USER_NOTIF_MAGIC;
+ resp.val = 0;
+ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), -1);
+ EXPECT_EQ(errno, EINVAL);
+
+ resp.error = 0;
+ resp.val = 0;
+ EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp), 0) {
+ if (errno == EINVAL)
+ XFAIL(goto skip, "Kernel does not support SECCOMP_USER_NOTIF_FLAG_CONTINUE");
+ }
+
+skip:
+ EXPECT_EQ(waitpid(pid, &status, 0), pid);
+ EXPECT_EQ(true, WIFEXITED(status));
+ EXPECT_EQ(0, WEXITSTATUS(status)) {
+ if (WEXITSTATUS(status) == 2) {
+ XFAIL(return, "Kernel does not support kcmp() syscall");
+ return;
+ }
+ }
+}
+
/*
* TODO:
* - add microbenchmarks
--
2.23.0
^ permalink raw reply related
* [PATCH v2 2/3] seccomp: avoid overflow in implicit constant conversion
From: Christian Brauner @ 2019-09-20 8:30 UTC (permalink / raw)
To: keescook, luto
Cc: jannh, wad, shuah, ast, daniel, kafai, songliubraving, yhs,
linux-kernel, linux-kselftest, netdev, bpf, Christian Brauner,
Tyler Hicks, Tycho Andersen, stable
In-Reply-To: <20190920083007.11475-1-christian.brauner@ubuntu.com>
USER_NOTIF_MAGIC is assigned to int variables in this test so set it to INT_MAX
to avoid warnings:
seccomp_bpf.c: In function ‘user_notification_continue’:
seccomp_bpf.c:3088:26: warning: overflow in implicit constant conversion [-Woverflow]
#define USER_NOTIF_MAGIC 116983961184613L
^
seccomp_bpf.c:3572:15: note: in expansion of macro ‘USER_NOTIF_MAGIC’
resp.error = USER_NOTIF_MAGIC;
^~~~~~~~~~~~~~~~
Fixes: 6a21cc50f0c7 ("seccomp: add a return code to trap to userspace")
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Song Liu <songliubraving@fb.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: Tycho Andersen <tycho@tycho.ws>
Cc: stable@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: bpf@vger.kernel.org
---
/* v2 */
unchanged
/* v1 */
Link: https://lore.kernel.org/r/20190919095903.19370-3-christian.brauner@ubuntu.com
unchanged
/* v0 */
Link: https://lore.kernel.org/r/20190918084833.9369-4-christian.brauner@ubuntu.com
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 6ef7f16c4cf5..e996d7b7fd6e 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -35,6 +35,7 @@
#include <stdbool.h>
#include <string.h>
#include <time.h>
+#include <limits.h>
#include <linux/elf.h>
#include <sys/uio.h>
#include <sys/utsname.h>
@@ -3072,7 +3073,7 @@ static int user_trap_syscall(int nr, unsigned int flags)
return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog);
}
-#define USER_NOTIF_MAGIC 116983961184613L
+#define USER_NOTIF_MAGIC INT_MAX
TEST(user_notification_basic)
{
pid_t pid;
--
2.23.0
^ permalink raw reply related
* [PATCH v2 1/3] seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE
From: Christian Brauner @ 2019-09-20 8:30 UTC (permalink / raw)
To: keescook, luto
Cc: jannh, wad, shuah, ast, daniel, kafai, songliubraving, yhs,
linux-kernel, linux-kselftest, netdev, bpf, Christian Brauner,
Tycho Andersen, Tyler Hicks
In-Reply-To: <20190920083007.11475-1-christian.brauner@ubuntu.com>
This allows the seccomp notifier to continue a syscall. A positive
discussion about this feature was triggered by a post to the
ksummit-discuss mailing list (cf. [3]) and took place during KSummit
(cf. [1]) and again at the containers/checkpoint-restore
micro-conference at Linux Plumbers.
Recently we landed seccomp support for SECCOMP_RET_USER_NOTIF (cf. [4])
which enables a process (watchee) to retrieve an fd for its seccomp
filter. This fd can then be handed to another (usually more privileged)
process (watcher). The watcher will then be able to receive seccomp
messages about the syscalls having been performed by the watchee.
This feature is heavily used in some userspace workloads. For example,
it is currently used to intercept mknod() syscalls in user namespaces
aka in containers.
The mknod() syscall can be easily filtered based on dev_t. This allows
us to only intercept a very specific subset of mknod() syscalls.
Furthermore, mknod() is not possible in user namespaces toto coelo and
so intercepting and denying syscalls that are not in the whitelist on
accident is not a big deal. The watchee won't notice a difference.
In contrast to mknod(), a lot of other syscall we intercept (e.g.
setxattr()) cannot be easily filtered like mknod() because they have
pointer arguments. Additionally, some of them might actually succeed in
user namespaces (e.g. setxattr() for all "user.*" xattrs). Since we
currently cannot tell seccomp to continue from a user notifier we are
stuck with performing all of the syscalls in lieu of the container. This
is a huge security liability since it is extremely difficult to
correctly assume all of the necessary privileges of the calling task
such that the syscall can be successfully emulated without escaping
other additional security restrictions (think missing CAP_MKNOD for
mknod(), or MS_NODEV on a filesystem etc.). This can be solved by
telling seccomp to resume the syscall.
One thing that came up in the discussion was the problem that another
thread could change the memory after userspace has decided to let the
syscall continue which is a well known TOCTOU with seccomp which is
present in other ways already.
The discussion showed that this feature is already very useful for any
syscall without pointer arguments. For any accidentally intercepted
non-pointer syscall it is safe to continue.
For syscalls with pointer arguments there is a race but for any cautious
userspace and the main usec cases the race doesn't matter. The notifier
is intended to be used in a scenario where a more privileged watcher
supervises the syscalls of lesser privileged watchee to allow it to get
around kernel-enforced limitations by performing the syscall for it
whenever deemed save by the watcher. Hence, if a user tricks the watcher
into allowing a syscall they will either get a deny based on
kernel-enforced restrictions later or they will have changed the
arguments in such a way that they manage to perform a syscall with
arguments that they would've been allowed to do anyway.
In general, it is good to point out again, that the notifier fd was not
intended to allow userspace to implement a security policy but rather to
work around kernel security mechanisms in cases where the watcher knows
that a given action is safe to perform.
/* References */
[1]: https://linuxplumbersconf.org/event/4/contributions/560
[2]: https://linuxplumbersconf.org/event/4/contributions/477
[3]: https://lore.kernel.org/r/20190719093538.dhyopljyr5ns33qx@brauner.io
[4]: commit 6a21cc50f0c7 ("seccomp: add a return code to trap to userspace")
Co-developed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Reviewed-by: Tycho Andersen <tycho@tycho.ws>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
CC: Tyler Hicks <tyhicks@canonical.com>
---
/* v2 */
- Jann Horn <jannh@google.com>:
- mention that SECCOMP_USER_NOTIF_FLAG_CONTINUE can be used to override lower
SECCOMP_RET_USER_NOTIF and SECCOMP_RET_TRACE filters
/* v1 */
Link: https://lore.kernel.org/r/20190919095903.19370-2-christian.brauner@ubuntu.com
- Kees Cook <keescook@chromium.org>, Tycho Andersen <tycho@tycho.ws>:
- s/SECCOMP_RET_USER_NOTIF_ALLOW/SECCOMP_USER_NOTIF_FLAG_CONTINUE/g
- Kees Cook <keescook@chromium.org>:
- put giant warning about the dangers, and correct usage of the
SECCOMP_USER_NOTIF_FLAG_CONTINUE flag
- Kees Cook <keescook@chromium.org>:
- change return type for seccomp_do_user_notification() to int to align with
similar functions
/* v0 */
Link: https://lore.kernel.org/r/20190918084833.9369-2-christian.brauner@ubuntu.com
---
include/uapi/linux/seccomp.h | 28 ++++++++++++++++++++++++++++
kernel/seccomp.c | 28 ++++++++++++++++++++++------
2 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
index 90734aa5aa36..61fbbb7c1ee9 100644
--- a/include/uapi/linux/seccomp.h
+++ b/include/uapi/linux/seccomp.h
@@ -76,6 +76,34 @@ struct seccomp_notif {
struct seccomp_data data;
};
+/*
+ * Valid flags for struct seccomp_notif_resp
+ *
+ * Note, the SECCOMP_USER_NOTIF_FLAG_CONTINUE flag must be used with caution!
+ * If set by the process supervising the syscalls of another process the
+ * syscall will continue. This is problematic because of an inherent TOCTOU.
+ * An attacker can exploit the time while the supervised process is waiting on
+ * a response from the supervising process to rewrite syscall arguments which
+ * are passed as pointers of the intercepted syscall.
+ * It should be absolutely clear that this means that the seccomp notifier
+ * _cannot_ be used to implement a security policy! It should only ever be used
+ * in scenarios where a more privileged process supervises the syscalls of a
+ * lesser privileged process to get around kernel-enforced security
+ * restrictions when the privileged process deems this safe. In other words,
+ * in order to continue a syscall the supervising process should be sure that
+ * another security mechanism or the kernel itself will sufficiently block
+ * syscalls if arguments are rewritten to something unsafe.
+ *
+ * Similar precautions should be applied when stacking SECCOMP_RET_USER_NOTIF.
+ * For SECCOMP_RET_USER_NOTIF filters acting on the same syscall the uppermost
+ * filter takes precedence. This means that the uppermost
+ * SECCOMP_RET_USER_NOTIF filter can override any SECCOMP_IOCTL_NOTIF_SEND from
+ * lower filters essentially allowing all syscalls to pass by using
+ * SECCOMP_USER_NOTIF_FLAG_CONTINUE. Note that SECCOMP_RET_USER_NOTIF can
+ * equally be overriden by SECCOMP_USER_NOTIF_FLAG_CONTINUE.
+ */
+#define SECCOMP_USER_NOTIF_FLAG_CONTINUE BIT(0)
+
struct seccomp_notif_resp {
__u64 id;
__s64 val;
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index dba52a7db5e8..12d2227e5786 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -75,6 +75,7 @@ struct seccomp_knotif {
/* The return values, only valid when in SECCOMP_NOTIFY_REPLIED */
int error;
long val;
+ u32 flags;
/* Signals when this has entered SECCOMP_NOTIFY_REPLIED */
struct completion ready;
@@ -732,11 +733,12 @@ static u64 seccomp_next_notify_id(struct seccomp_filter *filter)
return filter->notif->next_id++;
}
-static void seccomp_do_user_notification(int this_syscall,
- struct seccomp_filter *match,
- const struct seccomp_data *sd)
+static int seccomp_do_user_notification(int this_syscall,
+ struct seccomp_filter *match,
+ const struct seccomp_data *sd)
{
int err;
+ u32 flags = 0;
long ret = 0;
struct seccomp_knotif n = {};
@@ -764,6 +766,7 @@ static void seccomp_do_user_notification(int this_syscall,
if (err == 0) {
ret = n.val;
err = n.error;
+ flags = n.flags;
}
/*
@@ -780,8 +783,14 @@ static void seccomp_do_user_notification(int this_syscall,
list_del(&n.list);
out:
mutex_unlock(&match->notify_lock);
+
+ /* Userspace requests to continue the syscall. */
+ if (flags & SECCOMP_USER_NOTIF_FLAG_CONTINUE)
+ return 0;
+
syscall_set_return_value(current, task_pt_regs(current),
err, ret);
+ return -1;
}
static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
@@ -867,8 +876,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
return 0;
case SECCOMP_RET_USER_NOTIF:
- seccomp_do_user_notification(this_syscall, match, sd);
- goto skip;
+ if (seccomp_do_user_notification(this_syscall, match, sd))
+ goto skip;
+
+ return 0;
case SECCOMP_RET_LOG:
seccomp_log(this_syscall, 0, action, true);
@@ -1087,7 +1098,11 @@ static long seccomp_notify_send(struct seccomp_filter *filter,
if (copy_from_user(&resp, buf, sizeof(resp)))
return -EFAULT;
- if (resp.flags)
+ if (resp.flags & ~SECCOMP_USER_NOTIF_FLAG_CONTINUE)
+ return -EINVAL;
+
+ if ((resp.flags & SECCOMP_USER_NOTIF_FLAG_CONTINUE) &&
+ (resp.error || resp.val))
return -EINVAL;
ret = mutex_lock_interruptible(&filter->notify_lock);
@@ -1116,6 +1131,7 @@ static long seccomp_notify_send(struct seccomp_filter *filter,
knotif->state = SECCOMP_NOTIFY_REPLIED;
knotif->error = resp.error;
knotif->val = resp.val;
+ knotif->flags = resp.flags;
complete(&knotif->ready);
out:
mutex_unlock(&filter->notify_lock);
--
2.23.0
^ permalink raw reply related
* [PATCH v2 0/3] seccomp: continue syscall from notifier
From: Christian Brauner @ 2019-09-20 8:30 UTC (permalink / raw)
To: keescook, luto
Cc: jannh, wad, shuah, ast, daniel, kafai, songliubraving, yhs,
linux-kernel, linux-kselftest, netdev, bpf, Christian Brauner
Hey everyone,
/* v2 */
This is the patchset coming out of the KSummit session Kees and I gave
in Lisbon last week (cf. [3] which also contains slides with more
details on related things such as deep argument inspection).
The simple idea is to extend the seccomp notifier to allow for the
continuation of a syscall. The rationale for this can be found in the
commit message to [1]. For the curious there is more detail in [2].
This patchset would unblock supervising an extended set of syscalls such
as mount() where a privileged process is supervising the syscalls of a
lesser privileged process and emulates the syscall for the latter in
userspace.
For more comments on security see [1] and the comments in
include/uapi/linux/seccomp.h added by this patchset.
Kees, if you prefer a pr the series can be pulled from:
git@gitolite.kernel.org:pub/scm/linux/kernel/git/brauner/linux tags/seccomp-notify-syscall-continue-v5.5
For anyone who wants to play with this it's sitting in:
https://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git/log/?h=seccomp_syscall_continue
/* v1 */
Link: https://lore.kernel.org/r/20190919095903.19370-1-christian.brauner@ubuntu.com
- Kees Cook <keescook@chromium.org>:
- dropped patch because it is already present in linux-next
[PATCH 2/4] seccomp: add two missing ptrace ifdefines
Link: https://lore.kernel.org/r/20190918084833.9369-3-christian.brauner@ubuntu.com
/* v0 */
Link: https://lore.kernel.org/r/20190918084833.9369-1-christian.brauner@ubuntu.com
Thanks!
Christian
*** BLURB HERE ***
Christian Brauner (3):
seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE
seccomp: avoid overflow in implicit constant conversion
seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE
include/uapi/linux/seccomp.h | 28 +++++
kernel/seccomp.c | 28 ++++-
tools/testing/selftests/seccomp/seccomp_bpf.c | 110 +++++++++++++++++-
3 files changed, 159 insertions(+), 7 deletions(-)
--
2.23.0
^ permalink raw reply
* Re: [PATCH v2 2/3] seccomp: avoid overflow in implicit constant conversion
From: Tycho Andersen @ 2019-09-20 8:47 UTC (permalink / raw)
To: Christian Brauner
Cc: keescook, luto, jannh, wad, shuah, ast, daniel, kafai,
songliubraving, yhs, linux-kernel, linux-kselftest, netdev, bpf,
Tyler Hicks, stable
In-Reply-To: <20190920083007.11475-3-christian.brauner@ubuntu.com>
On Fri, Sep 20, 2019 at 10:30:06AM +0200, Christian Brauner wrote:
> USER_NOTIF_MAGIC is assigned to int variables in this test so set it to INT_MAX
> to avoid warnings:
>
> seccomp_bpf.c: In function ‘user_notification_continue’:
> seccomp_bpf.c:3088:26: warning: overflow in implicit constant conversion [-Woverflow]
> #define USER_NOTIF_MAGIC 116983961184613L
> ^
> seccomp_bpf.c:3572:15: note: in expansion of macro ‘USER_NOTIF_MAGIC’
> resp.error = USER_NOTIF_MAGIC;
> ^~~~~~~~~~~~~~~~
>
> Fixes: 6a21cc50f0c7 ("seccomp: add a return code to trap to userspace")
> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
> Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Andy Lutomirski <luto@amacapital.net>
> Cc: Will Drewry <wad@chromium.org>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Martin KaFai Lau <kafai@fb.com>
> Cc: Song Liu <songliubraving@fb.com>
> Cc: Yonghong Song <yhs@fb.com>
> Cc: Tycho Andersen <tycho@tycho.ws>
You can also add,
Reviewed-by: Tycho Andersen <tycho@tycho.ws>
for this one.
Tycho
^ permalink raw reply
* [PATCH v2] ethernet: gemini: Use devm_platform_ioremap_resource() in gemini_ethernet_probe()
From: Markus Elfring @ 2019-09-20 9:23 UTC (permalink / raw)
To: netdev, linux-arm-kernel, David S. Miller, Hans Ulli Kroll,
Linus Walleij, Radhey Shyam Pandey
Cc: LKML, kernel-janitors
In-Reply-To: <CH2PR02MB700047AFFFE08FE5FD563541C78E0@CH2PR02MB7000.namprd02.prod.outlook.com>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Fri, 20 Sep 2019 10:52:56 +0200
Simplify this function implementation by using the wrapper function
“devm_platform_ioremap_resource” instead of calling the functions
“platform_get_resource” and “devm_ioremap_resource” directly.
* Thus reduce also a bit of exception handling code here.
* Delete the local variable “res”.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
v2:
Further changes were requested by Radhey Shyam Pandey.
https://lore.kernel.org/r/CH2PR02MB700047AFFFE08FE5FD563541C78E0@CH2PR02MB7000.namprd02.prod.outlook.com/
* Updates for three modules were split into
a separate patch for each driver.
* The commit description was adjusted.
drivers/net/ethernet/cortina/gemini.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index e736ce2c58ca..f009415ee4d8 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -2549,17 +2549,13 @@ static int gemini_ethernet_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct gemini_ethernet *geth;
unsigned int retry = 5;
- struct resource *res;
u32 val;
/* Global registers */
geth = devm_kzalloc(dev, sizeof(*geth), GFP_KERNEL);
if (!geth)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
- geth->base = devm_ioremap_resource(dev, res);
+ geth->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(geth->base))
return PTR_ERR(geth->base);
geth->dev = dev;
--
2.23.0
^ permalink raw reply related
* Re: [PATCH -next] treewide: remove unused argument in lock_release()
From: Will Deacon @ 2019-09-20 9:38 UTC (permalink / raw)
To: Qian Cai
Cc: akpm, mingo, peterz, linux-kernel, linux-api, maarten.lankhorst,
mripard, sean, airlied, daniel, dri-devel, gregkh, jslaby, viro,
linux-fsdevel, joonas.lahtinen, rodrigo.vivi, intel-gfx, tytso,
jack, linux-ext4, tj, mark, jlbec, joseph.qi, ocfs2-devel, davem,
daniel, netdev, bpf, duyuyang, juri.lelli, vincent.guittot,
hannes, mhocko, vdavydov.dev, cgroups, linux-mm, alexander.levin
In-Reply-To: <1568909380-32199-1-git-send-email-cai@lca.pw>
On Thu, Sep 19, 2019 at 12:09:40PM -0400, Qian Cai wrote:
> Since the commit b4adfe8e05f1 ("locking/lockdep: Remove unused argument
> in __lock_release"), @nested is no longer used in lock_release(), so
> remove it from all lock_release() calls and friends.
>
> Signed-off-by: Qian Cai <cai@lca.pw>
> ---
Although this looks fine to me at a first glance, it might be slightly
easier to manage if you hit {spin,rwlock,seqcount,mutex,rwsem}_release()
first with coccinelle scripts, and then hack lock_release() as a final
patch. That way it's easy to regenerate things if needed.
Cheers,
Will
^ permalink raw reply
* Re: [PATCH] netfilter: bridge: drop a broken include
From: Pablo Neira Ayuso @ 2019-09-20 9:49 UTC (permalink / raw)
To: Jeremy Sowden
Cc: Adam Borowski, Jozsef Kadlecsik, Florian Westphal, Roopa Prabhu,
Nikolay Aleksandrov, netfilter-devel, coreteam, netdev
In-Reply-To: <20190917145907.GA2241@azazel.net>
On Tue, Sep 17, 2019 at 03:59:08PM +0100, Jeremy Sowden wrote:
[...]
> The commit in net-next that fixes it is:
>
> 47e640af2e49 ("netfilter: add missing IS_ENABLED(CONFIG_NF_TABLES) check to header-file.")
>
> I applied it to the mainline and compile-tested it to verify that it
> does indeed fix the build failure.
>
> From my reading of stable-kernel-rules.rst and netdev-FAQ.rst, it
> appears that the fix should come from the mainline, so I will wait for
> it to get there.
Thanks, just send this to stable@vger.kernel.org and Cc
netfilter-devel@vger.kernel.org and me when requesting this.
^ permalink raw reply
* Re: [PATCH v2 1/3] cifs: Add support for root file systems
From: Paulo Alcantara @ 2019-09-20 10:04 UTC (permalink / raw)
To: linux-kernel, netdev, linux-cifs, samba-technical,
David S. Miller, Steve French
Cc: Aurelien Aptel
In-Reply-To: <20190919152116.27076-1-pc@cjr.nz>
"Paulo Alcantara (SUSE)" <pc@cjr.nz> writes:
> Introduce a new CONFIG_CIFS_ROOT option to handle root file systems
> over a SMB share.
>
> In order to mount the root file system during the init process, make
> cifs.ko perform non-blocking socket operations while mounting and
> accessing it.
>
> Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
> Signed-off-by: Aurelien Aptel <aaptel@suse.com>
> ---
> Documentation/filesystems/cifs/cifsroot.txt | 97 +++++++++++++++++++++
> fs/cifs/Kconfig | 8 ++
> fs/cifs/Makefile | 2 +
> fs/cifs/cifsglob.h | 2 +
> fs/cifs/cifsroot.c | 94 ++++++++++++++++++++
> fs/cifs/connect.c | 17 +++-
> include/linux/root_dev.h | 1 +
> 7 files changed, 218 insertions(+), 3 deletions(-)
> create mode 100644 Documentation/filesystems/cifs/cifsroot.txt
> create mode 100644 fs/cifs/cifsroot.c
Hi David,
This patch has already been merged into Linus tree. The other two (2/3
and 3/3) still need to be reviewed.
I'm not sure how this works when series touch multiple subsystems --
that is, these changes should go through your tree or Steve's?
Please let me you know if you need anything else.
Thanks!
Paulo
^ permalink raw reply
* Re: [PATCH] rtl8xxxu: prevent leaking urb
From: Chris Chiu @ 2019-09-20 10:23 UTC (permalink / raw)
To: Navid Emamdoost
Cc: emamd001, smccaman, kjlu, Jes Sorensen, Kalle Valo,
David S. Miller, linux-wireless, netdev, Linux Kernel
In-Reply-To: <20190920030043.30137-1-navid.emamdoost@gmail.com>
On Fri, Sep 20, 2019 at 11:01 AM Navid Emamdoost
<navid.emamdoost@gmail.com> wrote:
>
> In rtl8xxxu_submit_int_urb if usb_submit_urb fails the allocated urb
> should be released.
>
> Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
Reviewed-by: Chris Chiu <chiu@endlessm.com>
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -5443,6 +5443,7 @@ static int rtl8xxxu_submit_int_urb(struct ieee80211_hw *hw)
> ret = usb_submit_urb(urb, GFP_KERNEL);
> if (ret) {
> usb_unanchor_urb(urb);
> + usb_free_urb(urb);
> goto error;
> }
You're right. There's a usb_alloc_urb in the beginning of this
function and should be
handled after submit failure.
Chris
^ permalink raw reply
* [PATCH v2] ethernet: lantiq_xrx200: Use devm_platform_ioremap_resource() in xrx200_probe()
From: Markus Elfring @ 2019-09-20 10:57 UTC (permalink / raw)
To: netdev, David S. Miller, Hauke Mehrtens, Radhey Shyam Pandey
Cc: LKML, kernel-janitors
In-Reply-To: <CH2PR02MB700047AFFFE08FE5FD563541C78E0@CH2PR02MB7000.namprd02.prod.outlook.com>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Fri, 20 Sep 2019 11:48:33 +0200
Simplify this function implementation by using the wrapper function
“devm_platform_ioremap_resource” instead of calling the functions
“platform_get_resource” and “devm_ioremap_resource” directly.
* Thus reduce also a bit of exception handling code here.
* Delete the local variable “res”.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
v2:
Further changes were requested by Radhey Shyam Pandey.
https://lore.kernel.org/r/CH2PR02MB700047AFFFE08FE5FD563541C78E0@CH2PR02MB7000.namprd02.prod.outlook.com/
* Updates for three modules were split into a separate patch for each driver.
* The commit description was adjusted.
drivers/net/ethernet/lantiq_xrx200.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c
index 900affbdcc0e..0a7ea45b9e59 100644
--- a/drivers/net/ethernet/lantiq_xrx200.c
+++ b/drivers/net/ethernet/lantiq_xrx200.c
@@ -424,7 +424,6 @@ static int xrx200_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct resource *res;
struct xrx200_priv *priv;
struct net_device *net_dev;
const u8 *mac;
@@ -443,15 +442,7 @@ static int xrx200_probe(struct platform_device *pdev)
SET_NETDEV_DEV(net_dev, dev);
net_dev->min_mtu = ETH_ZLEN;
net_dev->max_mtu = XRX200_DMA_DATA_LEN;
-
- /* load the memory ranges */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "failed to get resources\n");
- return -ENOENT;
- }
-
- priv->pmac_reg = devm_ioremap_resource(dev, res);
+ priv->pmac_reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->pmac_reg)) {
dev_err(dev, "failed to request and remap io ranges\n");
return PTR_ERR(priv->pmac_reg);
--
2.23.0
^ permalink raw reply related
* Re: Bug report (with fix) for DEC Tulip driver (de2104x.c)
From: Thomas Bogendoerfer @ 2019-09-20 10:43 UTC (permalink / raw)
To: Arlie Davis; +Cc: netdev, linux-parisc
In-Reply-To: <CAK-9enMxA68mRYFG=2zD02guvCqe-aa3NO0YZuJcTdBWn5MPqg@mail.gmail.com>
On Mon, Sep 16, 2019 at 02:50:53PM -0700, Arlie Davis wrote:
> See section 4.2.2 for the specs on the transfer descriptor.
>
> Here's my patch that fixes it:
>
> diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c
> b/drivers/net/ethernet/dec/tulip/de2104x.c
> index f1a2da15dd0a..3a420ceb52e5 100644
> --- a/drivers/net/ethernet/dec/tulip/de2104x.c
> +++ b/drivers/net/ethernet/dec/tulip/de2104x.c
> @@ -545,6 +545,7 @@ static void de_tx (struct de_private *de)
> while (tx_tail != tx_head) {
> struct sk_buff *skb;
> u32 status;
> + u32 control;
>
> rmb();
> status = le32_to_cpu(de->tx_ring[tx_tail].opts1);
> @@ -565,7 +566,8 @@ static void de_tx (struct de_private *de)
> pci_unmap_single(de->pdev, de->tx_skb[tx_tail].mapping,
> skb->len, PCI_DMA_TODEVICE);
>
> - if (status & LastFrag) {
> + control = le32_to_cpu(de->tx_ring[tx_tail].opts2);
> + if (control & LastFrag) {
how about just remove the complete if ? We know that we always
use one descriptor per packet and chip doesn't touch control
field. So I see no reason to check it here. Tulip driver for
2114x cards doesn't check it neither.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply
* [PATCH v2] ethernet: axienet: Use devm_platform_ioremap_resource() in axienet_probe()
From: Markus Elfring @ 2019-09-20 11:30 UTC (permalink / raw)
To: netdev, linux-arm-kernel, David S. Miller, Michal Simek,
Radhey Shyam Pandey
Cc: LKML, kernel-janitors
In-Reply-To: <CH2PR02MB700047AFFFE08FE5FD563541C78E0@CH2PR02MB7000.namprd02.prod.outlook.com>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Fri, 20 Sep 2019 13:17:01 +0200
Simplify this function implementation by using the wrapper function
“devm_platform_ioremap_resource” instead of calling the functions
“platform_get_resource” and “devm_ioremap_resource” directly.
* Thus reduce also a bit of exception handling code here.
* Delete the local variable “res”.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
v2:
Further changes were requested by Radhey Shyam Pandey.
https://lore.kernel.org/r/CH2PR02MB700047AFFFE08FE5FD563541C78E0@CH2PR02MB7000.namprd02.prod.outlook.com/
* Updates for three modules were split into a separate patch for each driver.
* The commit description was adjusted.
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 4fc627fb4d11..92783aaaa0a2 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1787,14 +1787,7 @@ static int axienet_probe(struct platform_device *pdev)
of_node_put(np);
lp->eth_irq = platform_get_irq(pdev, 0);
} else {
- /* Check for these resources directly on the Ethernet node. */
- struct resource *res = platform_get_resource(pdev,
- IORESOURCE_MEM, 1);
- if (!res) {
- dev_err(&pdev->dev, "unable to get DMA memory resource\n");
- goto free_netdev;
- }
- lp->dma_regs = devm_ioremap_resource(&pdev->dev, res);
+ lp->dma_regs = devm_platform_ioremap_resource(pdev, 1);
lp->rx_irq = platform_get_irq(pdev, 1);
lp->tx_irq = platform_get_irq(pdev, 0);
lp->eth_irq = platform_get_irq(pdev, 2);
--
2.23.0
^ permalink raw reply related
* RE: [PATCH v2] ethernet: axienet: Use devm_platform_ioremap_resource() in axienet_probe()
From: Radhey Shyam Pandey @ 2019-09-20 11:57 UTC (permalink / raw)
To: Markus Elfring, netdev@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, David S. Miller,
Michal Simek
Cc: LKML, kernel-janitors@vger.kernel.org
In-Reply-To: <604a6376-0298-ebcd-ee84-435945370374@web.de>
> -----Original Message-----
> From: Markus Elfring <Markus.Elfring@web.de>
> Sent: Friday, September 20, 2019 5:01 PM
> To: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; David S.
> Miller <davem@davemloft.net>; Michal Simek <michals@xilinx.com>;
> Radhey Shyam Pandey <radheys@xilinx.com>
> Cc: LKML <linux-kernel@vger.kernel.org>; kernel-janitors@vger.kernel.org
> Subject: [PATCH v2] ethernet: axienet: Use
> devm_platform_ioremap_resource() in axienet_probe()
>
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Fri, 20 Sep 2019 13:17:01 +0200
>
> Simplify this function implementation by using the wrapper function
> “devm_platform_ioremap_resource” instead of calling the functions
> “platform_get_resource” and “devm_ioremap_resource” directly.
>
> * Thus reduce also a bit of exception handling code here.
> * Delete the local variable “res”.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Thanks!
> ---
>
> v2:
> Further changes were requested by Radhey Shyam Pandey.
> https://lore.kernel.org/r/CH2PR02MB700047AFFFE08FE5FD563541C78E0@C
> H2PR02MB7000.namprd02.prod.outlook.com/
>
> * Updates for three modules were split into a separate patch for each driver.
> * The commit description was adjusted.
>
>
> drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 9 +--------
> 1 file changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index 4fc627fb4d11..92783aaaa0a2 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -1787,14 +1787,7 @@ static int axienet_probe(struct platform_device
> *pdev)
> of_node_put(np);
> lp->eth_irq = platform_get_irq(pdev, 0);
> } else {
> - /* Check for these resources directly on the Ethernet node.
> */
> - struct resource *res = platform_get_resource(pdev,
> -
> IORESOURCE_MEM, 1);
> - if (!res) {
> - dev_err(&pdev->dev, "unable to get DMA memory
> resource\n");
> - goto free_netdev;
> - }
> - lp->dma_regs = devm_ioremap_resource(&pdev->dev, res);
> + lp->dma_regs = devm_platform_ioremap_resource(pdev, 1);
> lp->rx_irq = platform_get_irq(pdev, 1);
> lp->tx_irq = platform_get_irq(pdev, 0);
> lp->eth_irq = platform_get_irq(pdev, 2);
> --
> 2.23.0
^ permalink raw reply
* [PATCH] net/core/dev: print rtnl kind as driver name for virtual devices
From: Konstantin Khlebnikov @ 2019-09-20 12:15 UTC (permalink / raw)
To: netdev, David S. Miller
Device kind gives more information than only arbitrary device name.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
net/core/dev.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 71b18e80389f..c84561634afd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9651,17 +9651,14 @@ static int __net_init netdev_init(struct net *net)
*/
const char *netdev_drivername(const struct net_device *dev)
{
- const struct device_driver *driver;
const struct device *parent;
const char *empty = "";
parent = dev->dev.parent;
- if (!parent)
- return empty;
-
- driver = parent->driver;
- if (driver && driver->name)
- return driver->name;
+ if (parent)
+ return dev_driver_string(parent);
+ if (dev->rtnl_link_ops)
+ return dev->rtnl_link_ops->kind;
return empty;
}
@@ -9677,8 +9674,8 @@ static void __netdev_printk(const char *level, const struct net_device *dev,
netdev_name(dev), netdev_reg_state(dev),
vaf);
} else if (dev) {
- printk("%s%s%s: %pV",
- level, netdev_name(dev), netdev_reg_state(dev), vaf);
+ printk("%s%s %s%s: %pV", level, netdev_drivername(dev),
+ netdev_name(dev), netdev_reg_state(dev), vaf);
} else {
printk("%s(NULL net_device): %pV", level, vaf);
}
^ permalink raw reply related
* [PATCH] ipv6/addrconf: use netdev_info()/netdev_warn()/netdev_dbg() for logging
From: Konstantin Khlebnikov @ 2019-09-20 12:16 UTC (permalink / raw)
To: netdev, David S. Miller
Print prefix "<driver> <pci_dev> <dev_name>: " or "<kind> <dev_name>: ".
Add "IPv6: " into format: netdev_info() does not use macro pr_fmt().
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
net/ipv6/addrconf.c | 28 ++++++++++++----------------
net/ipv6/addrconf_core.c | 2 +-
2 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6a576ff92c39..0d1568cf1e89 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -417,7 +417,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
#if IS_ENABLED(CONFIG_IPV6_SIT)
if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
- pr_info("%s: Disabled Multicast RS\n", dev->name);
+ netdev_info(dev, "IPv6: Disabled Multicast RS\n");
ndev->cnf.rtr_solicits = 0;
}
#endif
@@ -951,7 +951,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
WARN_ON(!hlist_unhashed(&ifp->addr_lst));
#ifdef NET_REFCNT_DEBUG
- pr_debug("%s\n", __func__);
+ netdev_dbg(ifp->idev->dev, "%s\n", __func__);
#endif
in6_dev_put(ifp->idev);
@@ -1329,7 +1329,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
in6_dev_hold(idev);
if (idev->cnf.use_tempaddr <= 0) {
write_unlock_bh(&idev->lock);
- pr_info("%s: use_tempaddr is disabled\n", __func__);
+ netdev_info(idev->dev, "IPv6: use_tempaddr is disabled\n");
in6_dev_put(idev);
ret = -1;
goto out;
@@ -1339,8 +1339,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
idev->cnf.use_tempaddr = -1; /*XXX*/
spin_unlock_bh(&ifp->lock);
write_unlock_bh(&idev->lock);
- pr_warn("%s: regeneration time exceeded - disabled temporary address support\n",
- __func__);
+ netdev_warn(idev->dev, "IPv6: regeneration time exceeded - disabled temporary address support\n");
in6_dev_put(idev);
ret = -1;
goto out;
@@ -1412,7 +1411,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
if (IS_ERR(ift)) {
in6_ifa_put(ifp);
in6_dev_put(idev);
- pr_info("%s: retry temporary address regeneration\n", __func__);
+ netdev_info(idev->dev, "IPv6: retry temporary address regeneration\n");
tmpaddr = &addr;
write_lock_bh(&idev->lock);
goto retry;
@@ -3160,7 +3159,7 @@ static void init_loopback(struct net_device *dev)
idev = ipv6_find_idev(dev);
if (IS_ERR(idev)) {
- pr_debug("%s: add_dev failed\n", __func__);
+ netdev_dbg(dev, "IPv6: %s: add_dev failed\n", __func__);
return;
}
@@ -3375,7 +3374,7 @@ static void addrconf_sit_config(struct net_device *dev)
idev = ipv6_find_idev(dev);
if (IS_ERR(idev)) {
- pr_debug("%s: add_dev failed\n", __func__);
+ netdev_dbg(dev, "IPv6: %s: add_dev failed\n", __func__);
return;
}
@@ -3400,7 +3399,7 @@ static void addrconf_gre_config(struct net_device *dev)
idev = ipv6_find_idev(dev);
if (IS_ERR(idev)) {
- pr_debug("%s: add_dev failed\n", __func__);
+ netdev_dbg(dev, "IPv6: %s: add_dev failed\n", __func__);
return;
}
@@ -3534,8 +3533,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
if (!addrconf_link_ready(dev)) {
/* device is not ready yet. */
- pr_debug("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
- dev->name);
+ netdev_dbg(dev, "IPv6: ADDRCONF(NETDEV_UP): link is not ready\n");
break;
}
@@ -3570,8 +3568,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
idev->if_flags |= IF_READY;
}
- pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n",
- dev->name);
+ netdev_info(dev, "IPv6: ADDRCONF(NETDEV_CHANGE): link becomes ready\n");
run_pending = 1;
}
@@ -3894,7 +3891,7 @@ static void addrconf_rs_timer(struct timer_list *t)
* Note: we do not support deprecated "all on-link"
* assumption any longer.
*/
- pr_debug("%s: no IPv6 routers present\n", idev->dev->name);
+ netdev_dbg(dev, "no IPv6 routers present\n");
}
out:
@@ -4054,8 +4051,7 @@ static void addrconf_dad_work(struct work_struct *w)
/* DAD failed for link-local based on MAC */
idev->cnf.disable_ipv6 = 1;
- pr_info("%s: IPv6 being disabled!\n",
- ifp->idev->dev->name);
+ netdev_info(idev->dev, "IPv6 being disabled!\n");
disable_ipv6 = true;
}
}
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c
index 783f3c1466da..d2b589fb6889 100644
--- a/net/ipv6/addrconf_core.c
+++ b/net/ipv6/addrconf_core.c
@@ -243,7 +243,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev)
WARN_ON(timer_pending(&idev->rs_timer));
#ifdef NET_REFCNT_DEBUG
- pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL");
+ netdev_dbg(dev, "%s\n", __func__);
#endif
dev_put(dev);
if (!idev->dead) {
^ permalink raw reply related
* Re: [PATCH -next] treewide: remove unused argument in lock_release()
From: Qian Cai @ 2019-09-20 12:50 UTC (permalink / raw)
To: Will Deacon, torvalds
Cc: ast, akpm, mingo, peterz, linux-kernel, linux-api,
maarten.lankhorst, mripard, sean, airlied, daniel, dri-devel,
gregkh, jslaby, viro, linux-fsdevel, joonas.lahtinen,
rodrigo.vivi, intel-gfx, tytso, jack, linux-ext4, tj, mark, jlbec,
joseph.qi, ocfs2-devel, davem, daniel, netdev, bpf, duyuyang,
juri.lelli, vincent.guittot, hannes, mhocko, vdavydov.dev,
cgroups, linux-mm, alexander.levin
In-Reply-To: <20190920093700.7nfaghxdrmubp2do@willie-the-truck>
On Fri, 2019-09-20 at 10:38 +0100, Will Deacon wrote:
> On Thu, Sep 19, 2019 at 12:09:40PM -0400, Qian Cai wrote:
> > Since the commit b4adfe8e05f1 ("locking/lockdep: Remove unused argument
> > in __lock_release"), @nested is no longer used in lock_release(), so
> > remove it from all lock_release() calls and friends.
> >
> > Signed-off-by: Qian Cai <cai@lca.pw>
> > ---
>
> Although this looks fine to me at a first glance, it might be slightly
> easier to manage if you hit {spin,rwlock,seqcount,mutex,rwsem}_release()
> first with coccinelle scripts, and then hack lock_release() as a final
> patch. That way it's easy to regenerate things if needed.
I am not sure if it worth the extra efforts where I have to retest it on all
architectures, and the patch is really simple, but I can certainly do that if
you insist.
I have just confirmed the patch [1] also applied correctly to the latest
mainline, so it might be the best time just for Linus to merge it directly so it
does not introduce build errors later on?
[1]
https://lore.kernel.org/lkml/1568909380-32199-1-git-send-email-cai@lca.pw/
^ permalink raw reply
* [PATCH] mt7601u: phy: simplify zero check on val
From: Colin King @ 2019-09-20 12:54 UTC (permalink / raw)
To: Jakub Kicinski, Kalle Valo, David S . Miller, Matthias Brugger,
linux-wireless, netdev, linux-arm-kernel, linux-mediatek
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Currently the zero check on val to break out of a loop
is a little obscure. Replace the val is zero and break check
with a loop while value is non-zero.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/wireless/mediatek/mt7601u/phy.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt7601u/phy.c b/drivers/net/wireless/mediatek/mt7601u/phy.c
index 06f5702ab4bd..4e0e473caae1 100644
--- a/drivers/net/wireless/mediatek/mt7601u/phy.c
+++ b/drivers/net/wireless/mediatek/mt7601u/phy.c
@@ -213,9 +213,7 @@ int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev)
do {
val = mt7601u_bbp_rr(dev, MT_BBP_REG_VERSION);
- if (val && ~val)
- break;
- } while (--i);
+ } while (val && --i);
if (!i) {
dev_err(dev->dev, "Error: BBP is not ready\n");
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] mt7601u: phy: simplify zero check on val
From: Robin Murphy @ 2019-09-20 13:25 UTC (permalink / raw)
To: Colin King, Jakub Kicinski, Kalle Valo, David S . Miller,
Matthias Brugger, linux-wireless, netdev, linux-arm-kernel,
linux-mediatek
Cc: kernel-janitors, linux-kernel
In-Reply-To: <20190920125414.15507-1-colin.king@canonical.com>
On 20/09/2019 13:54, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Currently the zero check on val to break out of a loop
> is a little obscure. Replace the val is zero and break check
> with a loop while value is non-zero.
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
> drivers/net/wireless/mediatek/mt7601u/phy.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt7601u/phy.c b/drivers/net/wireless/mediatek/mt7601u/phy.c
> index 06f5702ab4bd..4e0e473caae1 100644
> --- a/drivers/net/wireless/mediatek/mt7601u/phy.c
> +++ b/drivers/net/wireless/mediatek/mt7601u/phy.c
> @@ -213,9 +213,7 @@ int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev)
>
> do {
> val = mt7601u_bbp_rr(dev, MT_BBP_REG_VERSION);
> - if (val && ~val)
> - break;
AFAICS, this effectively implements "while (val == 0 || val == 0xff)",
which is not at all equivalent to "while(val)"... :/
Robin.
> - } while (--i);
> + } while (val && --i);
>
> if (!i) {
> dev_err(dev->dev, "Error: BBP is not ready\n");
>
^ permalink raw reply
* [PATCH] dimlib: make DIMLIB a hidden symbol
From: Uwe Kleine-König @ 2019-09-20 13:31 UTC (permalink / raw)
To: Tal Gilboa, Saeed Mahameed; +Cc: linux-kernel, netdev
According to Tal Gilboa the only benefit from DIM comes from a driver
that uses it. So it doesn't make sense to make this symbol user visible,
instead all drivers that use it should select it (as is already the case
AFAICT).
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
---
lib/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/Kconfig b/lib/Kconfig
index cc04124ed8f7..9fe8a21fd183 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -555,8 +555,7 @@ config SIGNATURE
Implementation is done using GnuPG MPI library
config DIMLIB
- bool "DIM library"
- default y
+ bool
help
Dynamic Interrupt Moderation library.
Implements an algorithm for dynamically change CQ moderation values
--
2.23.0
^ permalink raw reply related
* [PATCH RFC] cfg80211: add new command for reporting wiphy crashes
From: Rafał Miłecki @ 2019-09-20 13:37 UTC (permalink / raw)
To: Johannes Berg, David S . Miller, linux-wireless, netdev,
linux-kernel, Jouni Malinen, hostap, openwrt-devel
Cc: Rafał Miłecki
From: Rafał Miłecki <rafal@milecki.pl>
Hardware or firmware instability may result in unusable wiphy. In such
cases usually a hardware reset is needed. To allow a full recovery
kernel has to indicate problem to the user space.
This new nl80211 command lets user space known wiphy has crashed and has
been just recovered. When applicable it should result in supplicant or
authenticator reconfiguring all interfaces.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
I'd like to use this new cfg80211_crash_report() in brcmfmac after a
successful recovery from a FullMAC firmware crash.
Later on I'd like to modify hostapd to reconfigure wiphy using a
previously used setup.
I'm OpenWrt developer & user and I got annoyed by my devices not auto
recovering after various failures. There are things I cannot fix (hw
failures or closed fw crashes) but I still expect my devices to get
back to operational state as soon as possible on their own.
---
include/net/cfg80211.h | 7 +++++++
include/uapi/linux/nl80211.h | 2 ++
net/wireless/nl80211.c | 29 +++++++++++++++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ff45c3e1abff..668fa27c88cc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7437,6 +7437,13 @@ void cfg80211_pmsr_complete(struct wireless_dev *wdev,
bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
bool is_4addr, u8 check_swif);
+/**
+ * cfg80211_crash_report - report crashed wiphy that requires a setup
+ *
+ * @wiphy: the wiphy
+ * @gfp: allocation flags
+ */
+void cfg80211_crash_report(struct wiphy *wiphy, gfp_t gfp);
/* Logging, debugging and troubleshooting/diagnostic helpers. */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index beee59c831a7..9e17feb03849 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1325,6 +1325,8 @@ enum nl80211_commands {
NL80211_CMD_PROBE_MESH_LINK,
+ NL80211_CMD_CRASH_REPORT,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d21b1581a665..d29785fb0676 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -16940,6 +16940,35 @@ void cfg80211_update_owe_info_event(struct net_device *netdev,
}
EXPORT_SYMBOL(cfg80211_update_owe_info_event);
+void cfg80211_crash_report(struct wiphy *wiphy, gfp_t gfp)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRASH_REPORT);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+ NL80211_MCGRP_CONFIG, gfp);
+
+ return;
+
+nla_put_failure:
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_crash_report);
+
/* initialisation/exit functions */
int __init nl80211_init(void)
--
2.21.0
^ permalink raw reply related
* Re: [PATCH] ARM: dts: imx6dl: SolidRun: add phy node with 100Mb/s max-speed
From: Russell King - ARM Linux admin @ 2019-09-20 13:42 UTC (permalink / raw)
To: tinywrkb, Heiner Kallweit, Florian Fainelli, David S. Miller
Cc: Mark Rutland, Andrew Lunn, Baruch Siach,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Shawn Guo, Sascha Hauer, open list, Rob Herring, NXP Linux Team,
Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel, netdev
In-Reply-To: <20190917214201.GB25745@shell.armlinux.org.uk>
On Tue, Sep 17, 2019 at 10:42:01PM +0100, Russell King - ARM Linux admin wrote:
> On Tue, Sep 17, 2019 at 06:19:13PM +0100, Russell King - ARM Linux admin wrote:
> > whether you can get the link to come up at all. You might need to see
> > whether wiggling the RJ45 helps (I've had that sort of thing with some
> > cables.)
> >
> > You might also need "ethtool -s eth0 advertise ffcf" after trying that
> > if it doesn't work to take the gigabit speeds out of the advertisement.
> >
> > Thanks.
> >
> > drivers/net/phy/at803x.c | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> > index b3893347804d..85cf4a4a5e81 100644
> > --- a/drivers/net/phy/at803x.c
> > +++ b/drivers/net/phy/at803x.c
> > @@ -296,6 +296,11 @@ static int at803x_config_init(struct phy_device *phydev)
> > if (ret < 0)
> > return ret;
> >
> > + /* Disable smartspeed */
> > + ret = phy_modify(phydev, 0x14, BIT(5), 0);
> > + if (ret < 0)
> > + return ret;
> > +
> > /* The RX and TX delay default is:
> > * after HW reset: RX delay enabled and TX delay disabled
> > * after SW reset: RX delay enabled, while TX delay retains the
>
> Hi,
>
> Could you try this patch instead - it seems that the PHY needs to be
> soft-reset for the write to take effect, and _even_ for the clearance
> of the bit to become visible in the register.
>
> I'm not expecting this on its own to solve anything, but it should at
> least mean that the at803x doesn't modify the advertisement registers
> itself. It may mean that the link doesn't even come up without forcing
> the advertisement via the ethtool command I mentioned before.
>
> Thanks.
>
> drivers/net/phy/at803x.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index b3893347804d..69a58c0e6b42 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c
> @@ -296,6 +296,16 @@ static int at803x_config_init(struct phy_device *phydev)
> if (ret < 0)
> return ret;
>
> + /* Disable smartspeed */
> + ret = phy_modify(phydev, 0x14, BIT(5), 0);
> + if (ret < 0)
> + return ret;
> +
> + /* Must soft-reset the PHY for smartspeed disable to take effect */
> + ret = genphy_soft_reset(phydev);
> + if (ret < 0)
> + return ret;
> +
> /* The RX and TX delay default is:
> * after HW reset: RX delay enabled and TX delay disabled
> * after SW reset: RX delay enabled, while TX delay retains the
Bad news I'm afraid. It looks like the AR8035 has a bug in it.
Disabling the SmartSpeed feature appears to make register 9, the
1000BASET control register, read-only.
For example:
Reading 0x0009=0x0200
Writing 0x0014=0x082c <= smartspeed enabled
Writing 0x0000=0xb100 <= soft reset
Writing 0x0009=0x0600
Reading 0x0009=0x0600 <= it took the value
Reading 0x0009=0x0600
Writing 0x0014=0x080c <= smartspeed disabled
Writing 0x0000=0xb100 <= soft reset
Writing 0x0009=0x0200
Reading 0x0009=0x0600 <= it ignored the write
Reading 0x0009=0x0600
Writing 0x0014=0x082c <= smartspeed enabled
Writing 0x0000=0xb100 <= soft reset
Writing 0x0009=0x0200
Reading 0x0009=0x0200 <= it took the value
If it's going to make register 9 read-only when smartspeed is disabled,
then that's another failure mode and autonegotiation cockup just
waiting to happen - which I spotted when trying to configure the
advertisement using ethtool, and finding that it was impossible to stop
1000baseT/Full being advertised.
I think the only sane approach - at least until we have something more
reasonable in place - is to base the negotiation result off what is
actually stored in the PHY registers at the time the link comes up, and
not on the cached versions of what we should be advertising.
5502b218e001 has caused this regression, and where we are now after
more than a week of trying to come up with some fix for this
regression, the only solution that seems to work without introducing
more failures is to revert that commit.
Adding Heiner (original commit author), Florian, David and netdev.
Thoughts?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ 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