From 20e6bb17facdc2a078baa12136910bab2c315519 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 15 Jan 2018 17:10:33 +0100 Subject: [PATCH 01/48] watchdog: rave-sp: add NVMEM dependency We can build this driver with or without NVMEM, but not built-in when NVMEM is a loadable module: drivers/watchdog/rave-sp-wdt.o: In function `rave_sp_wdt_probe': rave-sp-wdt.c:(.text+0x27c): undefined reference to `nvmem_cell_get' rave-sp-wdt.c:(.text+0x290): undefined reference to `nvmem_cell_read' rave-sp-wdt.c:(.text+0x2c4): undefined reference to `nvmem_cell_put' This adds a Kconfig dependency to enforce that. Fixes: c3bb33345721 ("watchdog: Add RAVE SP watchdog driver") Signed-off-by: Arnd Bergmann Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index aff773bcebdb59..a16bad78679b84 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -226,6 +226,7 @@ config ZIIRAVE_WATCHDOG config RAVE_SP_WATCHDOG tristate "RAVE SP Watchdog timer" depends on RAVE_SP_CORE + depends on NVMEM || !NVMEM select WATCHDOG_CORE help Support for the watchdog on RAVE SP device. From 7e2e5158e700f2196dff3b68ac07405575e09c22 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Mon, 19 Feb 2018 02:01:05 +0100 Subject: [PATCH 02/48] watchdog: i6300esb: fix build failure i6300esb uses fuctions defined in watchdog_core.c, and when CONFIG_WATCHDOG_CORE is not set we have this build error: drivers/watchdog/i6300esb.o: In function `esb_remove': i6300esb.c:(.text+0xcc): undefined reference to `watchdog_unregister_device' drivers/watchdog/i6300esb.o: In function `esb_probe': i6300esb.c:(.text+0x2a1): undefined reference to `watchdog_init_timeout' i6300esb.c:(.text+0x388): undefined reference to `watchdog_register_device' make: *** [Makefile:1029: vmlinux] Error 1 Fix this by selecting CONFIG_WATCHDOG_CORE when I6300ESB_WDT is set. Fixes: 7af4ac8772a8f ("watchdog: i6300esb: use the watchdog subsystem") Signed-off-by: Matteo Croce Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index a16bad78679b84..56f9e203049e28 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1009,6 +1009,7 @@ config WAFER_WDT config I6300ESB_WDT tristate "Intel 6300ESB Timer/Watchdog" depends on PCI + select WATCHDOG_CORE ---help--- Hardware driver for the watchdog timer built into the Intel 6300ESB controller hub. From 4cd6764495f2b6c2d3dc4fdd339f78764f7995d5 Mon Sep 17 00:00:00 2001 From: Radu Rendec Date: Mon, 19 Feb 2018 14:38:51 +0000 Subject: [PATCH 03/48] watchdog: xen_wdt: fix potential build failure xen_wdt uses watchdog core functions (from watchdog_core.c) and, when compiled without CONFIG_WATCHDOG_CORE being set, it produces the following build error: ERROR: "devm_watchdog_register_device" [drivers/watchdog/xen_wdt.ko] undefined! ERROR: "watchdog_init_timeout" [drivers/watchdog/xen_wdt.ko] undefined! Fix this by selecting CONFIG_WATCHDOG_CORE when CONFIG_XEN_WDT is set. Fixes: 18cffd68e0c4 ("watchdog: xen_wdt: use the watchdog subsystem") Signed-off-by: Radu Rendec Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 56f9e203049e28..3d984cdea0cad4 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1839,6 +1839,7 @@ config WATCHDOG_SUN4V config XEN_WDT tristate "Xen Watchdog support" depends on XEN + select WATCHDOG_CORE help Say Y here to support the hypervisor watchdog capability provided by Xen 4.0 and newer. The watchdog timeout period is normally one From a17f4f032b61abd998a1f81b206a4517e2e3db2f Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Mon, 19 Feb 2018 17:04:33 +0100 Subject: [PATCH 04/48] watchdog: sp5100_tco.c: fix potential build failure isp5100_tco.c uses watchdog core functions (from watchdog_core.c) and, when compiled without CONFIG_WATCHDOG_CORE being set, it produces the following build error: ERROR: "devm_watchdog_register_device" [drivers/watchdog/sp5100_tco.ko] undefined! ERROR: "watchdog_init_timeout" [drivers/watchdog/sp5100_tco.ko] undefined! Fix this by selecting CONFIG_WATCHDOG_CORE. Fixes: 7cd9d5fff792 ("watchdog: sp5100_tco: Convert to use watchdog subsystem") Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3d984cdea0cad4..37460cd6cabb80 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -904,6 +904,7 @@ config F71808E_WDT config SP5100_TCO tristate "AMD/ATI SP5100 TCO Timer/Watchdog" depends on X86 && PCI + select WATCHDOG_CORE ---help--- Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO (Total Cost of Ownership) timer is a watchdog timer that will reboot From 6d516d6798cdfc073aa2fa11dd5a5d72f3906ae5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 22 Feb 2018 15:00:43 -0600 Subject: [PATCH 05/48] PCI: Update location of pci.ids file Update the URL for the pci.ids file and add locations for its mirrors. Signed-off-by: Randy Dunlap Signed-off-by: Bjorn Helgaas Cc: Martin Mares Cc: Michal Vaner --- Documentation/PCI/pci.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/PCI/pci.txt b/Documentation/PCI/pci.txt index 611a75e4366ed2..badb26ac33dc8e 100644 --- a/Documentation/PCI/pci.txt +++ b/Documentation/PCI/pci.txt @@ -570,7 +570,9 @@ your driver if they're helpful, or just use plain hex constants. The device IDs are arbitrary hex numbers (vendor controlled) and normally used only in a single location, the pci_device_id table. -Please DO submit new vendor/device IDs to http://pciids.sourceforge.net/. +Please DO submit new vendor/device IDs to http://pci-ids.ucw.cz/. +There are mirrors of the pci.ids file at http://pciids.sourceforge.net/ +and https://github.com/pciutils/pciids. From 80dfd71c5ac28542911bd009f3565895e2c94380 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 23 Feb 2018 10:29:46 +0200 Subject: [PATCH 06/48] media: videobuf2: Add VIDEOBUF2_V4L2 Kconfig option for VB2 V4L2 part Videobuf2 is now separate from V4L2 and can be now built without it, at least in principle --- enabling videobuf2 in kernel configuration attempts to compile videobuf2-v4l2.c but that will fail if CONFIG_VIDEO_V4L2 isn't enabled. Solve this by adding a separate Kconfig option for videobuf2-v4l2 and make it a separate module as well. This means that drivers now need to choose both the appropriate videobuf2 memory type (VIDEOBUF2_{VMALLOC,DMA_CONTIG,DMA_SG}) and VIDEOBUF2_V4L2 if they need both. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/videobuf2/Kconfig | 3 +++ drivers/media/common/videobuf2/Makefile | 3 ++- drivers/media/v4l2-core/Kconfig | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/common/videobuf2/Kconfig b/drivers/media/common/videobuf2/Kconfig index 5df05250de947d..17c32ea58395d7 100644 --- a/drivers/media/common/videobuf2/Kconfig +++ b/drivers/media/common/videobuf2/Kconfig @@ -3,6 +3,9 @@ config VIDEOBUF2_CORE select DMA_SHARED_BUFFER tristate +config VIDEOBUF2_V4L2 + tristate + config VIDEOBUF2_MEMOPS tristate select FRAME_VECTOR diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile index 19de5ccda20b3c..7e27bdd44dcc8e 100644 --- a/drivers/media/common/videobuf2/Makefile +++ b/drivers/media/common/videobuf2/Makefile @@ -1,5 +1,6 @@ -obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o +obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o +obj-$(CONFIG_VIDEOBUF2_V4L2) += videobuf2-v4l2.o obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index bf52fbd07aeddc..8e37e7c5e0f7e2 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -7,6 +7,7 @@ config VIDEO_V4L2 tristate depends on (I2C || I2C=n) && VIDEO_DEV select RATIONAL + select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE default (I2C || I2C=n) && VIDEO_DEV config VIDEO_ADV_DEBUG From e77c31ed60d1bbf4879b19309f848e0d8f6df504 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Feb 2018 04:49:30 -0500 Subject: [PATCH 07/48] media: videobuf2: fix build issues with vb2-trace There was a trouble with vb2-trace: instead of being part of VB2 core, it was stored at V4L2 videodev. That was wrong, as it doesn't actually belong to V4L2 core. Now that vb2 is not part of v4l2-core, its trace functions should be moved altogether. So, move it to its rightful place: at videobuf2-core. That fixes those errors: drivers/media/common/videobuf2/videobuf2-core.o: In function `__read_once_size': ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_buf_queue' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_buf_queue' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_buf_done' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_buf_done' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_qbuf' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_qbuf' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_dqbuf' ./include/linux/compiler.h:183: undefined reference to `__tracepoint_vb2_dqbuf' drivers/media/common/videobuf2/videobuf2-core.o:(__jump_table+0x10): undefined reference to `__tracepoint_vb2_buf_queue' drivers/media/common/videobuf2/videobuf2-core.o:(__jump_table+0x28): undefined reference to `__tracepoint_vb2_buf_done' drivers/media/common/videobuf2/videobuf2-core.o:(__jump_table+0x40): undefined reference to `__tracepoint_vb2_qbuf' drivers/media/common/videobuf2/videobuf2-core.o:(__jump_table+0x58): undefined reference to `__tracepoint_vb2_dqbuf' Reported-by: kbuild test robot Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/videobuf2/Makefile | 3 +++ drivers/media/{v4l2-core => common/videobuf2}/vb2-trace.c | 0 drivers/media/v4l2-core/Makefile | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) rename drivers/media/{v4l2-core => common/videobuf2}/vb2-trace.c (100%) diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile index 7e27bdd44dcc8e..067badb1aaa72d 100644 --- a/drivers/media/common/videobuf2/Makefile +++ b/drivers/media/common/videobuf2/Makefile @@ -6,3 +6,6 @@ obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o obj-$(CONFIG_VIDEOBUF2_DVB) += videobuf2-dvb.o +ifeq ($(CONFIG_TRACEPOINTS),y) + obj-$(CONFIG_VIDEOBUF2_CORE) += vb2-trace.o +endif diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/common/videobuf2/vb2-trace.c similarity index 100% rename from drivers/media/v4l2-core/vb2-trace.c rename to drivers/media/common/videobuf2/vb2-trace.c diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 80de2cb9c476a2..7df54582e95689 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -13,7 +13,7 @@ ifeq ($(CONFIG_COMPAT),y) endif obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o ifeq ($(CONFIG_TRACEPOINTS),y) - videodev-objs += vb2-trace.o v4l2-trace.o + videodev-objs += v4l2-trace.o endif videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o @@ -35,4 +35,3 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o ccflags-y += -I$(srctree)/drivers/media/dvb-frontends ccflags-y += -I$(srctree)/drivers/media/tuners - From ec5b100462543aee1f3e139e168699fd3b05cdc6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 4 Jan 2018 05:31:30 -0500 Subject: [PATCH 08/48] media: dvb: fix DVB_MMAP symbol name CONFIG_DVB_MMAP was misspelled either as CONFIG_DVB_MMSP or DVB_MMAP, so it had no effect at all. This fixes that, to make it possible to build it again. Fixes: 4021053ed52d ("media: dvb-core: make DVB mmap API optional") Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/Makefile | 2 +- drivers/media/dvb-core/dmxdev.c | 30 +++++++++++++++--------------- include/media/dvb_vb2.h | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile index 3a105d82019a02..62b028ded9f784 100644 --- a/drivers/media/dvb-core/Makefile +++ b/drivers/media/dvb-core/Makefile @@ -4,7 +4,7 @@ # dvb-net-$(CONFIG_DVB_NET) := dvb_net.o -dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o +dvb-vb2-$(CONFIG_DVB_MMAP) := dvb_vb2.o dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ dvb_ca_en50221.o dvb_frontend.o \ diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 6d53af00190e39..c3054101c23477 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -128,7 +128,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; struct dmx_frontend *front; -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP bool need_ringbuffer = false; #else const bool need_ringbuffer = true; @@ -144,7 +144,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) return -ENODEV; } -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP if ((file->f_flags & O_ACCMODE) == O_RDONLY) need_ringbuffer = true; #else @@ -200,7 +200,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP bool need_ringbuffer = false; #else const bool need_ringbuffer = true; @@ -213,7 +213,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) dmxdev->demux->connect_frontend(dmxdev->demux, dmxdev->dvr_orig_fe); } -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP if ((file->f_flags & O_ACCMODE) == O_RDONLY) need_ringbuffer = true; #endif @@ -426,7 +426,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP struct dvb_vb2_ctx *ctx; #endif int ret; @@ -440,12 +440,12 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, if (dmxdevfilter->params.pes.output == DMX_OUT_TAP || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) { buffer = &dmxdevfilter->buffer; -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP ctx = &dmxdevfilter->vb2_ctx; #endif } else { buffer = &dmxdevfilter->dev->dvr_buffer; -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP ctx = &dmxdevfilter->dev->dvr_vb2_ctx; #endif } @@ -1111,7 +1111,7 @@ static int dvb_demux_do_ioctl(struct file *file, mutex_unlock(&dmxdevfilter->mutex); break; -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP case DMX_REQBUFS: if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { mutex_unlock(&dmxdev->mutex); @@ -1199,7 +1199,7 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait) return mask; } -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) { struct dmxdev_filter *dmxdevfilter = file->private_data; @@ -1249,7 +1249,7 @@ static const struct file_operations dvb_demux_fops = { .release = dvb_demux_release, .poll = dvb_demux_poll, .llseek = default_llseek, -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP .mmap = dvb_demux_mmap, #endif }; @@ -1280,7 +1280,7 @@ static int dvb_dvr_do_ioctl(struct file *file, ret = dvb_dvr_set_buffer_size(dmxdev, arg); break; -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP case DMX_REQBUFS: ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg); break; @@ -1322,7 +1322,7 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; __poll_t mask = 0; -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP bool need_ringbuffer = false; #else const bool need_ringbuffer = true; @@ -1337,7 +1337,7 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait) poll_wait(file, &dmxdev->dvr_buffer.queue, wait); -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP if ((file->f_flags & O_ACCMODE) == O_RDONLY) need_ringbuffer = true; #endif @@ -1353,7 +1353,7 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait) return mask; } -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) { struct dvb_device *dvbdev = file->private_data; @@ -1381,7 +1381,7 @@ static const struct file_operations dvb_dvr_fops = { .release = dvb_dvr_release, .poll = dvb_dvr_poll, .llseek = default_llseek, -#ifdef DVB_MMAP +#ifdef CONFIG_DVB_MMAP .mmap = dvb_dvr_mmap, #endif }; diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h index 01d1202d1a55b8..056adc86027248 100644 --- a/include/media/dvb_vb2.h +++ b/include/media/dvb_vb2.h @@ -103,7 +103,7 @@ struct dvb_vb2_ctx { char name[DVB_VB2_NAME_MAX + 1]; }; -#ifndef DVB_MMAP +#ifndef CONFIG_DVB_MMAP static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking) { From 85e60bd746b71fd8aca4f7e6803f9a5207f53a30 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 4 Jan 2018 05:31:31 -0500 Subject: [PATCH 09/48] media: dvb: fix DVB_MMAP dependency Enabling CONFIG_DVB_MMAP without CONFIG_VIDEOBUF2_VMALLOC results in a link error: drivers/media/dvb-core/dvb_vb2.o: In function `_stop_streaming': dvb_vb2.c:(.text+0x894): undefined reference to `vb2_buffer_done' drivers/media/dvb-core/dvb_vb2.o: In function `dvb_vb2_init': dvb_vb2.c:(.text+0xbec): undefined reference to `vb2_vmalloc_memops' dvb_vb2.c:(.text+0xc4c): undefined reference to `vb2_core_queue_init' drivers/media/dvb-core/dvb_vb2.o: In function `dvb_vb2_release': dvb_vb2.c:(.text+0xe14): undefined reference to `vb2_core_queue_release' drivers/media/dvb-core/dvb_vb2.o: In function `dvb_vb2_stream_on': dvb_vb2.c:(.text+0xeb8): undefined reference to `vb2_core_streamon' drivers/media/dvb-core/dvb_vb2.o: In function `dvb_vb2_stream_off': dvb_vb2.c:(.text+0xfe8): undefined reference to `vb2_core_streamoff' drivers/media/dvb-core/dvb_vb2.o: In function `dvb_vb2_fill_buffer': dvb_vb2.c:(.text+0x13ec): undefined reference to `vb2_plane_vaddr' dvb_vb2.c:(.text+0x149c): undefined reference to `vb2_buffer_done' This adds a 'select' statement for it, plus a dependency that ensures that videobuf2 in turn works, as it in turn depends on VIDEO_V4L2 to link, and that must not be a module if videobuf2 is built-in. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 145e12bfb8190a..372c074bb1b90f 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -147,6 +147,8 @@ config DVB_CORE config DVB_MMAP bool "Enable DVB memory-mapped API (EXPERIMENTAL)" depends on DVB_CORE + depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE + select VIDEOBUF2_VMALLOC default n help This option enables DVB experimental memory-mapped API, with From 0066c764e7cc18784e5edcdeb9831cdefdf4c344 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 4 Jan 2018 05:31:32 -0500 Subject: [PATCH 10/48] media: au0828: add VIDEO_V4L2 dependency After the move of videobuf2 into the common directory, selecting the au0828 driver with CONFIG_V4L2 disabled started causing a link failure, as we now attempt to build videobuf2 but it still requires v4l2: ERROR: "v4l2_event_pending" [drivers/media/common/videobuf/videobuf2-v4l2.ko] undefined! ERROR: "v4l2_fh_release" [drivers/media/common/videobuf/videobuf2-v4l2.ko] undefined! ERROR: "video_devdata" [drivers/media/common/videobuf/videobuf2-v4l2.ko] undefined! ERROR: "__tracepoint_vb2_buf_done" [drivers/media/common/videobuf/videobuf2-core.ko] undefined! ERROR: "__tracepoint_vb2_dqbuf" [drivers/media/common/videobuf/videobuf2-core.ko] undefined! ERROR: "v4l_vb2q_enable_media_source" [drivers/media/common/videobuf/videobuf2-core.ko] undefined! This adds the same dependency in au0828 that the other users of videobuf2 have. Fixes: 03fbdb2fc2b8 ("media: move videobuf2 to drivers/media/common") Fixes: 05439b1a3693 ("[media] media: au0828 - convert to use videobuf2") Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig index 70521e0b4c5348..bfaa806633df74 100644 --- a/drivers/media/usb/au0828/Kconfig +++ b/drivers/media/usb/au0828/Kconfig @@ -1,7 +1,7 @@ config VIDEO_AU0828 tristate "Auvitek AU0828 support" - depends on I2C && INPUT && DVB_CORE && USB + depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 select I2C_ALGOBIT select VIDEO_TVEEPROM select VIDEOBUF2_VMALLOC From b9c97c67fd19262c002d94ced2bfb513083e161e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 10 Feb 2018 06:14:10 -0500 Subject: [PATCH 11/48] media: m88ds3103: don't call a non-initalized function If m88d3103 chip ID is not recognized, the device is not initialized. However, it returns from probe without any error, causing this OOPS: [ 7.689289] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 7.689297] pgd = 7b0bd7a7 [ 7.689302] [00000000] *pgd=00000000 [ 7.689318] Internal error: Oops: 80000005 [#1] SMP ARM [ 7.689322] Modules linked in: dvb_usb_dvbsky(+) m88ds3103 dvb_usb_v2 dvb_core videobuf2_vmalloc videobuf2_memops videobuf2_core crc32_arm_ce videodev media [ 7.689358] CPU: 3 PID: 197 Comm: systemd-udevd Not tainted 4.15.0-mcc+ #23 [ 7.689361] Hardware name: BCM2835 [ 7.689367] PC is at 0x0 [ 7.689382] LR is at m88ds3103_attach+0x194/0x1d0 [m88ds3103] [ 7.689386] pc : [<00000000>] lr : [] psr: 60000013 [ 7.689391] sp : ed8e5c20 ip : ed8c1e00 fp : ed8945c0 [ 7.689395] r10: ed894000 r9 : ed894378 r8 : eda736c0 [ 7.689400] r7 : ed894070 r6 : ed8e5c44 r5 : bf0bb040 r4 : eda77600 [ 7.689405] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : eda77600 [ 7.689412] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 7.689417] Control: 10c5383d Table: 2d8e806a DAC: 00000051 [ 7.689423] Process systemd-udevd (pid: 197, stack limit = 0xe9dbfb63) [ 7.689428] Stack: (0xed8e5c20 to 0xed8e6000) [ 7.689439] 5c20: ed853a80 eda73640 ed894000 ed8942c0 ed853a80 bf0b9e98 ed894070 bf0b9f10 [ 7.689449] 5c40: 00000000 00000000 bf08c17c c08dfc50 00000000 00000000 00000000 00000000 [ 7.689459] 5c60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 7.689468] 5c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 7.689479] 5ca0: 00000000 00000000 ed8945c0 ed8942c0 ed894000 ed894830 bf0b9e98 00000000 [ 7.689490] 5cc0: ed894378 bf0a3cb4 bf0bc3b0 0000533b ed920540 00000000 00000034 bf0a6434 [ 7.689500] 5ce0: ee952070 ed826600 bf0a7038 bf0a2dd8 00000001 bf0a6768 bf0a2f90 ed8943c0 [ 7.689511] 5d00: 00000000 c08eca68 ed826620 ed826620 00000000 ee952070 bf0bc034 ee952000 [ 7.689521] 5d20: ed826600 bf0bb080 ffffffed c0aa9e9c c0aa9dac ed826620 c16edf6c c168c2c8 [ 7.689531] 5d40: c16edf70 00000000 bf0bc034 0000000d 00000000 c08e268c bf0bb080 ed826600 [ 7.689541] 5d60: bf0bc034 ed826654 ed826620 bf0bc034 c164c8bc 00000000 00000001 00000000 [ 7.689553] 5d80: 00000028 c08e2948 00000000 bf0bc034 c08e2848 c08e0778 ee9f0a58 ed88bab4 [ 7.689563] 5da0: bf0bc034 ed90ba80 c168c1f0 c08e1934 bf0bb3bc c17045ac bf0bc034 c164c8bc [ 7.689574] 5dc0: bf0bc034 bf0bb3bc ed91f564 c08e34ec bf0bc000 c164c8bc bf0bc034 c0aa8dc4 [ 7.689584] 5de0: ffffe000 00000000 bf0bf000 ed91f600 ed91f564 c03021e4 00000001 00000000 [ 7.689595] 5e00: c166e040 8040003f ed853a80 bf0bc448 00000000 c1678174 ed853a80 f0f22000 [ 7.689605] 5e20: f0f21fff 8040003f 014000c0 ed91e700 ed91e700 c16d8e68 00000001 ed91e6c0 [ 7.689615] 5e40: bf0bc400 00000001 bf0bc400 ed91f564 00000001 00000000 00000028 c03c9a24 [ 7.689625] 5e60: 00000001 c03c8c94 ed8e5f50 ed8e5f50 00000001 bf0bc400 ed91f540 c03c8cb0 [ 7.689637] 5e80: bf0bc40c 00007fff bf0bc400 c03c60b0 00000000 bf0bc448 00000028 c0e09684 [ 7.689647] 5ea0: 00000002 bf0bc530 c1234bf8 bf0bc5dc bf0bc514 c10ebbe8 ffffe000 bf000000 [ 7.689657] 5ec0: 00011538 00000000 ed8e5f48 00000000 00000000 00000000 00000000 00000000 [ 7.689666] 5ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 7.689676] 5f00: 00000000 00000000 7fffffff 00000000 00000013 b6e55a18 0000017b c0309104 [ 7.689686] 5f20: ed8e4000 00000000 00510af0 c03c9430 7fffffff 00000000 00000003 00000000 [ 7.689697] 5f40: 00000000 f0f0f000 00011538 00000000 f0f107b0 f0f0f000 00011538 f0f1fdb8 [ 7.689707] 5f60: f0f1fbe8 f0f1b974 00004000 000041e0 bf0bc3d0 00000001 00000000 000024c4 [ 7.689717] 5f80: 0000002d 0000002e 00000019 00000000 00000010 00000000 16894000 00000000 [ 7.689727] 5fa0: 00000000 c0308f20 16894000 00000000 00000013 b6e55a18 00000000 b6e5652c [ 7.689737] 5fc0: 16894000 00000000 00000000 0000017b 00020000 00508110 00000000 00510af0 [ 7.689748] 5fe0: bef68948 bef68938 b6e4d3d0 b6d32590 60000010 00000013 00000000 00000000 [ 7.689790] [] (m88ds3103_attach [m88ds3103]) from [] (dvbsky_s960c_attach+0x78/0x280 [dvb_usb_dvbsky]) [ 7.689821] [] (dvbsky_s960c_attach [dvb_usb_dvbsky]) from [] (dvb_usbv2_probe+0xa3c/0x1024 [dvb_usb_v2]) [ 7.689849] [] (dvb_usbv2_probe [dvb_usb_v2]) from [] (usb_probe_interface+0xf0/0x2a8) [ 7.689869] [] (usb_probe_interface) from [] (driver_probe_device+0x2f8/0x4b4) [ 7.689881] [] (driver_probe_device) from [] (__driver_attach+0x100/0x11c) [ 7.689895] [] (__driver_attach) from [] (bus_for_each_dev+0x4c/0x9c) [ 7.689909] [] (bus_for_each_dev) from [] (bus_add_driver+0x1c0/0x264) [ 7.689919] [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [ 7.689931] [] (driver_register) from [] (usb_register_driver+0x70/0x134) [ 7.689946] [] (usb_register_driver) from [] (do_one_initcall+0x44/0x168) [ 7.689963] [] (do_one_initcall) from [] (do_init_module+0x64/0x1f4) [ 7.689979] [] (do_init_module) from [] (load_module+0x20a0/0x25c8) [ 7.689993] [] (load_module) from [] (SyS_finit_module+0xb4/0xec) [ 7.690007] [] (SyS_finit_module) from [] (ret_fast_syscall+0x0/0x54) [ 7.690018] Code: bad PC value This may happen on normal circumstances, if, for some reason, the demod hangs and start returning an invalid chip ID: [ 10.394395] m88ds3103 3-0068: Unknown device. Chip_id=00 So, change the logic to cause probe to fail with -ENODEV, preventing the OOPS. Detected while testing DVB MMAP patches on Raspberry Pi 3 with DVBSky S960CI. Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 50bce68ffd6646..65d157fe76d19d 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1262,11 +1262,12 @@ static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan) * New users must use I2C client binding directly! */ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, - struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter) + struct i2c_adapter *i2c, + struct i2c_adapter **tuner_i2c_adapter) { struct i2c_client *client; struct i2c_board_info board_info; - struct m88ds3103_platform_data pdata; + struct m88ds3103_platform_data pdata = {}; pdata.clk = cfg->clock; pdata.i2c_wr_max = cfg->i2c_wr_max; @@ -1409,6 +1410,8 @@ static int m88ds3103_probe(struct i2c_client *client, case M88DS3103_CHIP_ID: break; default: + ret = -ENODEV; + dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id); goto err_kfree; } From a145f64c6107d3aa5a7cec9f8977d04ac2a896c9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 11 Feb 2018 05:44:21 -0500 Subject: [PATCH 12/48] media: dmxdev: fix error code for invalid ioctls Returning -EINVAL when an ioctl is not implemented is a very bad idea, as it is hard to distinguish from other error contitions that an ioctl could lead. Replace it by its right error code: -ENOTTY. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index c3054101c23477..d87b69b86a59a8 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -1160,7 +1160,7 @@ static int dvb_demux_do_ioctl(struct file *file, break; #endif default: - ret = -EINVAL; + ret = -ENOTTY; break; } mutex_unlock(&dmxdev->mutex); From 0b23498aacc658e4d0f6b240f0b905908695a132 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Feb 2018 10:44:49 -0500 Subject: [PATCH 13/48] media: dmxdev: Fix the logic that enables DMA mmap support Some conditions required for DVB mmap support to work are reversed. Also, the logic is not too clear. So, improve the logic, making it easier to be handled. PS.: I'm pretty sure that I fixed it while testing, but, somehow, the change got lost. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 75 ++++++++++++++++++--------------- include/media/dmxdev.h | 2 + 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index d87b69b86a59a8..09c2626b5bf912 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -128,11 +128,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; struct dmx_frontend *front; -#ifndef CONFIG_DVB_MMAP bool need_ringbuffer = false; -#else - const bool need_ringbuffer = true; -#endif dprintk("%s\n", __func__); @@ -144,17 +140,31 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) return -ENODEV; } -#ifndef CONFIG_DVB_MMAP + dmxdev->may_do_mmap = 0; + + /* + * The logic here is a little tricky due to the ifdef. + * + * The ringbuffer is used for both read and mmap. + * + * It is not needed, however, on two situations: + * - Write devices (access with O_WRONLY); + * - For duplex device nodes, opened with O_RDWR. + */ + if ((file->f_flags & O_ACCMODE) == O_RDONLY) need_ringbuffer = true; -#else - if ((file->f_flags & O_ACCMODE) == O_RDWR) { + else if ((file->f_flags & O_ACCMODE) == O_RDWR) { if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { +#ifdef CONFIG_DVB_MMAP + dmxdev->may_do_mmap = 1; + need_ringbuffer = true; +#else mutex_unlock(&dmxdev->mutex); return -EOPNOTSUPP; +#endif } } -#endif if (need_ringbuffer) { void *mem; @@ -169,8 +179,9 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) return -ENOMEM; } dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); - dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr", - file->f_flags & O_NONBLOCK); + if (dmxdev->may_do_mmap) + dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr", + file->f_flags & O_NONBLOCK); dvbdev->readers--; } @@ -200,11 +211,6 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; -#ifndef CONFIG_DVB_MMAP - bool need_ringbuffer = false; -#else - const bool need_ringbuffer = true; -#endif mutex_lock(&dmxdev->mutex); @@ -213,15 +219,14 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) dmxdev->demux->connect_frontend(dmxdev->demux, dmxdev->dvr_orig_fe); } -#ifndef CONFIG_DVB_MMAP - if ((file->f_flags & O_ACCMODE) == O_RDONLY) - need_ringbuffer = true; -#endif - if (need_ringbuffer) { - if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) - dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx); - dvb_vb2_release(&dmxdev->dvr_vb2_ctx); + if (((file->f_flags & O_ACCMODE) == O_RDONLY) || + dmxdev->may_do_mmap) { + if (dmxdev->may_do_mmap) { + if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) + dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx); + dvb_vb2_release(&dmxdev->dvr_vb2_ctx); + } dvbdev->readers++; if (dmxdev->dvr_buffer.data) { void *mem = dmxdev->dvr_buffer.data; @@ -802,6 +807,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file) mutex_init(&dmxdevfilter->mutex); file->private_data = dmxdevfilter; +#ifdef CONFIG_DVB_MMAP + dmxdev->may_do_mmap = 1; +#else + dmxdev->may_do_mmap = 0; +#endif + dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter", file->f_flags & O_NONBLOCK); @@ -1206,6 +1217,9 @@ static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) struct dmxdev *dmxdev = dmxdevfilter->dev; int ret; + if (!dmxdev->may_do_mmap) + return -EOPNOTSUPP; + if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -1322,11 +1336,6 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; __poll_t mask = 0; -#ifndef CONFIG_DVB_MMAP - bool need_ringbuffer = false; -#else - const bool need_ringbuffer = true; -#endif dprintk("%s\n", __func__); @@ -1337,11 +1346,8 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait) poll_wait(file, &dmxdev->dvr_buffer.queue, wait); -#ifndef CONFIG_DVB_MMAP - if ((file->f_flags & O_ACCMODE) == O_RDONLY) - need_ringbuffer = true; -#endif - if (need_ringbuffer) { + if (((file->f_flags & O_ACCMODE) == O_RDONLY) || + dmxdev->may_do_mmap) { if (dmxdev->dvr_buffer.error) mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR); @@ -1360,6 +1366,9 @@ static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) struct dmxdev *dmxdev = dvbdev->priv; int ret; + if (!dmxdev->may_do_mmap) + return -EOPNOTSUPP; + if (dmxdev->exit) return -ENODEV; diff --git a/include/media/dmxdev.h b/include/media/dmxdev.h index 2f5cb2c7b6a75d..baafa3b8aca414 100644 --- a/include/media/dmxdev.h +++ b/include/media/dmxdev.h @@ -163,6 +163,7 @@ struct dmxdev_filter { * @demux: pointer to &struct dmx_demux. * @filternum: number of filters. * @capabilities: demux capabilities as defined by &enum dmx_demux_caps. + * @may_do_mmap: flag used to indicate if the device may do mmap. * @exit: flag to indicate that the demux is being released. * @dvr_orig_fe: pointer to &struct dmx_frontend. * @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output. @@ -180,6 +181,7 @@ struct dmxdev { int filternum; int capabilities; + unsigned int may_do_mmap:1; unsigned int exit:1; #define DMXDEV_CAP_DUPLEX 1 struct dmx_frontend *dvr_orig_fe; From 9c171cdf22d1486da1608abd7612fabe2a8262ca Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Feb 2018 05:51:19 -0500 Subject: [PATCH 14/48] media: dvb: add continuity error indicators for memory mapped buffers While userspace can detect discontinuity errors, it is useful to also let Kernelspace reporting discontinuity, as it can help to identify if the data loss happened either at Kernel or userspace side. Update documentation accordingly. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/dmx.h.rst.exceptions | 14 ++++++--- Documentation/media/uapi/dvb/dmx-qbuf.rst | 7 +++-- include/uapi/linux/dvb/dmx.h | 35 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions index 63f55a9ae2b1ff..a8c4239ed95bab 100644 --- a/Documentation/media/dmx.h.rst.exceptions +++ b/Documentation/media/dmx.h.rst.exceptions @@ -50,9 +50,15 @@ replace typedef dmx_filter_t :c:type:`dmx_filter` replace typedef dmx_pes_type_t :c:type:`dmx_pes_type` replace typedef dmx_input_t :c:type:`dmx_input` -ignore symbol DMX_OUT_DECODER -ignore symbol DMX_OUT_TAP -ignore symbol DMX_OUT_TS_TAP -ignore symbol DMX_OUT_TSDEMUX_TAP +replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags` +replace symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags` +replace symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags` +replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags` +replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags` + +replace symbol DMX_OUT_DECODER :c:type:`dmx_output` +replace symbol DMX_OUT_TAP :c:type:`dmx_output` +replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output` +replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output` replace ioctl DMX_DQBUF dmx_qbuf diff --git a/Documentation/media/uapi/dvb/dmx-qbuf.rst b/Documentation/media/uapi/dvb/dmx-qbuf.rst index b48c4931658eda..be5a4c6f19040c 100644 --- a/Documentation/media/uapi/dvb/dmx-qbuf.rst +++ b/Documentation/media/uapi/dvb/dmx-qbuf.rst @@ -51,9 +51,10 @@ out to disk. Buffers remain locked until dequeued, until the the device is closed. Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled -(capturing) buffer from the driver's outgoing queue. They just set the ``reserved`` field array to zero. When ``DMX_DQBUF`` is called with a -pointer to this structure, the driver fills the remaining fields or -returns an error code. +(capturing) buffer from the driver's outgoing queue. +They just set the ``index`` field withe the buffer ID to be queued. +When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`, +the driver fills the remaining fields or returns an error code. By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing queue. When the ``O_NONBLOCK`` flag was given to the diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h index 5f3c5a918f00d5..b4112f0b6dd36c 100644 --- a/include/uapi/linux/dvb/dmx.h +++ b/include/uapi/linux/dvb/dmx.h @@ -211,6 +211,32 @@ struct dmx_stc { __u64 stc; }; +/** + * enum dmx_buffer_flags - DMX memory-mapped buffer flags + * + * @DMX_BUFFER_FLAG_HAD_CRC32_DISCARD: + * Indicates that the Kernel discarded one or more frames due to wrong + * CRC32 checksum. + * @DMX_BUFFER_FLAG_TEI: + * Indicates that the Kernel has detected a Transport Error indicator + * (TEI) on a filtered pid. + * @DMX_BUFFER_PKT_COUNTER_MISMATCH: + * Indicates that the Kernel has detected a packet counter mismatch + * on a filtered pid. + * @DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED: + * Indicates that the Kernel has detected one or more frame discontinuity. + * @DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR: + * Received at least one packet with a frame discontinuity indicator. + */ + +enum dmx_buffer_flags { + DMX_BUFFER_FLAG_HAD_CRC32_DISCARD = 1 << 0, + DMX_BUFFER_FLAG_TEI = 1 << 1, + DMX_BUFFER_PKT_COUNTER_MISMATCH = 1 << 2, + DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED = 1 << 3, + DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR = 1 << 4, +}; + /** * struct dmx_buffer - dmx buffer info * @@ -220,15 +246,24 @@ struct dmx_stc { * offset from the start of the device memory for this plane, * (or a "cookie" that should be passed to mmap() as offset) * @length: size in bytes of the buffer + * @flags: bit array of buffer flags as defined by &enum dmx_buffer_flags. + * Filled only at &DMX_DQBUF. + * @count: monotonic counter for filled buffers. Helps to identify + * data stream loses. Filled only at &DMX_DQBUF. * * Contains data exchanged by application and driver using one of the streaming * I/O methods. + * + * Please notice that, for &DMX_QBUF, only @index should be filled. + * On &DMX_DQBUF calls, all fields will be filled by the Kernel. */ struct dmx_buffer { __u32 index; __u32 bytesused; __u32 offset; __u32 length; + __u32 flags; + __u32 count; }; /** From fdbeb96258141d911ca8ba98931b9024038b84e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Feb 2018 07:30:46 -0500 Subject: [PATCH 15/48] media: dvb: update buffer mmaped flags and frame counter Now that we have support for a buffer counter and for error flags, update them at DMX_DQBUF. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 24 +++-- drivers/media/dvb-core/dvb_demux.c | 112 +++++++++++++++--------- drivers/media/dvb-core/dvb_net.c | 5 +- drivers/media/dvb-core/dvb_vb2.c | 31 +++++-- drivers/media/pci/ttpci/av7110.c | 5 +- drivers/media/pci/ttpci/av7110_av.c | 6 +- drivers/media/usb/ttusb-dec/ttusb_dec.c | 10 +-- include/media/demux.h | 21 +++-- include/media/dvb_demux.h | 4 + include/media/dvb_vb2.h | 18 +++- 10 files changed, 160 insertions(+), 76 deletions(-) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 09c2626b5bf912..61a750fae4653b 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -385,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *filter) + struct dmx_section_filter *filter, + u32 *buffer_flags) { struct dmxdev_filter *dmxdevfilter = filter->priv; int ret; @@ -404,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, dprintk("section callback %*ph\n", 6, buffer1); if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) { ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, - buffer1, buffer1_len); + buffer1, buffer1_len, + buffer_flags); if (ret == buffer1_len) ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, - buffer2, buffer2_len); + buffer2, buffer2_len, + buffer_flags); } else { ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len); @@ -427,7 +430,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - struct dmx_ts_feed *feed) + struct dmx_ts_feed *feed, + u32 *buffer_flags) { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; @@ -456,9 +460,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, } if (dvb_vb2_is_streaming(ctx)) { - ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len); + ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len, + buffer_flags); if (ret == buffer1_len) - ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len); + ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len, + buffer_flags); } else { if (buffer->error) { spin_unlock(&dmxdevfilter->dev->lock); @@ -1218,7 +1224,7 @@ static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) int ret; if (!dmxdev->may_do_mmap) - return -EOPNOTSUPP; + return -ENOTTY; if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -1318,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file, break; #endif default: - ret = -EINVAL; + ret = -ENOTTY; break; } mutex_unlock(&dmxdev->mutex); @@ -1367,7 +1373,7 @@ static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) int ret; if (!dmxdev->may_do_mmap) - return -EOPNOTSUPP; + return -ENOTTY; if (dmxdev->exit) return -ENODEV; diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 210eed0269b085..f45091246bdca9 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts, dprintk(x); \ } while (0) +#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG +# define dprintk_sect_loss(x...) dprintk(x) +#else +# define dprintk_sect_loss(x...) +#endif + +#define set_buf_flags(__feed, __flag) \ + do { \ + (__feed)->buffer_flags |= (__flag); \ + } while (0) + /****************************************************************************** * static inlined helper functions ******************************************************************************/ @@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, { int count = payload(buf); int p; -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG int ccok; u8 cc; -#endif if (count == 0) return -1; p = 188 - count; -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG cc = buf[3] & 0x0f; ccok = ((feed->cc + 1) & 0x0f) == cc; feed->cc = cc; - if (!ccok) - dprintk("missed packet: %d instead of %d!\n", - cc, (feed->cc + 1) & 0x0f); -#endif + if (!ccok) { + set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("missed packet: %d instead of %d!\n", + cc, (feed->cc + 1) & 0x0f); + } if (buf[1] & 0x40) // PUSI ? feed->peslen = 0xfffa; feed->peslen += count; - return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts); + return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, + &feed->buffer_flags); } static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, @@ -150,7 +160,7 @@ static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, return 0; return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen, - NULL, 0, &f->filter); + NULL, 0, &f->filter, &feed->buffer_flags); } static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) @@ -169,8 +179,10 @@ static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) if (sec->check_crc) { section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0); if (section_syntax_indicator && - demux->check_crc32(feed, sec->secbuf, sec->seclen)) + demux->check_crc32(feed, sec->secbuf, sec->seclen)) { + set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD); return -1; + } } do { @@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) { struct dmx_section_feed *sec = &feed->feed.sec; -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG if (sec->secbufp < sec->tsfeedp) { int n = sec->tsfeedp - sec->secbufp; @@ -197,12 +208,13 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) * but just first and last. */ if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { - dprintk("section ts padding loss: %d/%d\n", - n, sec->tsfeedp); - dprintk("pad data: %*ph\n", n, sec->secbuf); + set_buf_flags(feed, + DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("section ts padding loss: %d/%d\n", + n, sec->tsfeedp); + dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf); } } -#endif sec->tsfeedp = sec->secbufp = sec->seclen = 0; sec->secbuf = sec->secbuf_base; @@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, return 0; if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG - dprintk("section buffer full loss: %d/%d\n", - sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, - DMX_MAX_SECFEED_SIZE); -#endif + set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("section buffer full loss: %d/%d\n", + sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, + DMX_MAX_SECFEED_SIZE); len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; } @@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, sec->seclen = seclen; sec->crc_val = ~0; /* dump [secbuf .. secbuf+seclen) */ - if (feed->pusi_seen) + if (feed->pusi_seen) { dvb_dmx_swfilter_section_feed(feed); -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG - else - dprintk("pusi not seen, discarding section data\n"); -#endif + } else { + set_buf_flags(feed, + DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("pusi not seen, discarding section data\n"); + } sec->secbufp += seclen; /* secbufp and secbuf moving together is */ sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ } @@ -307,18 +319,22 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, } if (!ccok || dc_i) { -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG - if (dc_i) - dprintk("%d frame with disconnect indicator\n", + if (dc_i) { + set_buf_flags(feed, + DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR); + dprintk_sect_loss("%d frame with disconnect indicator\n", cc); - else - dprintk("discontinuity: %d instead of %d. %d bytes lost\n", + } else { + set_buf_flags(feed, + DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("discontinuity: %d instead of %d. %d bytes lost\n", cc, (feed->cc + 1) & 0x0f, count + 4); + } /* - * those bytes under sume circumstances will again be reported + * those bytes under some circumstances will again be reported * in the following dvb_dmx_swfilter_section_new */ -#endif + /* * Discontinuity detected. Reset pusi_seen to * stop feeding of suspicious data until next PUSI=1 arrives @@ -326,6 +342,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, * FIXME: does it make sense if the MPEG-TS is the one * reporting discontinuity? */ + feed->pusi_seen = false; dvb_dmx_swfilter_section_new(feed); } @@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, dvb_dmx_swfilter_section_new(feed); dvb_dmx_swfilter_section_copy_dump(feed, after, after_len); + } else if (count > 0) { + set_buf_flags(feed, + DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); + dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count); } -#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG - else if (count > 0) - dprintk("PUSI=1 but %d bytes lost\n", count); -#endif } else { /* PUSI=0 (is not set), no section boundary */ dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count); @@ -369,7 +386,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, if (feed->ts_type & TS_PAYLOAD_ONLY) dvb_dmx_swfilter_payload(feed, buf); else - feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts); + feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, + &feed->buffer_flags); } /* Used only on full-featured devices */ if (feed->ts_type & TS_DECODER) @@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) } if (buf[1] & 0x80) { + list_for_each_entry(feed, &demux->feed_list, list_head) { + if ((feed->pid != pid) && (feed->pid != 0x2000)) + continue; + set_buf_flags(feed, DMX_BUFFER_FLAG_TEI); + } dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n", pid, buf[1]); /* data in this packet can't be trusted - drop it unless @@ -445,6 +468,13 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) (demux->cnt_storage[pid] + 1) & 0xf; if ((buf[3] & 0xf) != demux->cnt_storage[pid]) { + list_for_each_entry(feed, &demux->feed_list, list_head) { + if ((feed->pid != pid) && (feed->pid != 0x2000)) + continue; + set_buf_flags(feed, + DMX_BUFFER_PKT_COUNTER_MISMATCH); + } + dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", pid, demux->cnt_storage[pid], buf[3] & 0xf); @@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) if (feed->pid == pid) dvb_dmx_swfilter_packet_type(feed, buf); else if (feed->pid == 0x2000) - feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts); + feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, + &feed->buffer_flags); } } @@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count) spin_lock_irqsave(&demux->lock, flags); - demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts); + demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, + &demux->feed->buffer_flags); spin_unlock_irqrestore(&demux->lock, flags); } @@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, feed->demux = demux; feed->pid = 0xffff; feed->peslen = 0xfffa; + feed->buffer_flags = 0; (*ts_feed) = &feed->feed.ts; (*ts_feed)->parent = dmx; @@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, dvbdmxfeed->cb.sec = callback; dvbdmxfeed->demux = dvbdmx; dvbdmxfeed->pid = 0xffff; + dvbdmxfeed->buffer_flags = 0; dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; dvbdmxfeed->feed.sec.tsfeedp = 0; diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index b6c7eec863b923..ba39f9942e1db0 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -883,7 +883,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - struct dmx_ts_feed *feed) + struct dmx_ts_feed *feed, + u32 *buffer_flags) { struct net_device *dev = feed->priv; @@ -992,7 +993,7 @@ static void dvb_net_sec(struct net_device *dev, static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *filter) + struct dmx_section_filter *filter, u32 *buffer_flags) { struct net_device *dev = filter->priv; diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c index 763145d74e836a..b811adf88afa34 100644 --- a/drivers/media/dvb-core/dvb_vb2.c +++ b/drivers/media/dvb-core/dvb_vb2.c @@ -256,7 +256,8 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx) } int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, - const unsigned char *src, int len) + const unsigned char *src, int len, + enum dmx_buffer_flags *buffer_flags) { unsigned long flags = 0; void *vbuf = NULL; @@ -264,15 +265,17 @@ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, unsigned char *psrc = (unsigned char *)src; int ll = 0; - dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len); - if (!src) { - dprintk(3, "[%s]:NULL pointer src\n", ctx->name); - /**normal case: This func is called twice from demux driver - * once with valid src pointer, second time with NULL pointer - */ + /* + * normal case: This func is called twice from demux driver + * one with valid src pointer, second time with NULL pointer + */ + if (!src || !len) return 0; - } spin_lock_irqsave(&ctx->slock, flags); + if (buffer_flags && *buffer_flags) { + ctx->flags |= *buffer_flags; + *buffer_flags = 0; + } while (todo) { if (!ctx->buf) { if (list_empty(&ctx->dvb_q)) { @@ -395,6 +398,7 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) { + unsigned long flags; int ret; ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking); @@ -402,7 +406,16 @@ int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) dprintk(1, "[%s] errno=%d\n", ctx->name, ret); return ret; } - dprintk(5, "[%s] index=%d\n", ctx->name, b->index); + + spin_lock_irqsave(&ctx->slock, flags); + b->count = ctx->count++; + b->flags = ctx->flags; + ctx->flags = 0; + spin_unlock_irqrestore(&ctx->slock, flags); + + dprintk(5, "[%s] index=%d, count=%d, flags=%d\n", + ctx->name, b->index, ctx->count, b->flags); + return 0; } diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index dc8e577b2f748a..d6816effb87866 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -324,14 +324,15 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len, } return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, buffer2, buffer2_len, - &dvbdmxfilter->filter); + &dvbdmxfilter->filter, NULL); case DMX_TYPE_TS: if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) return 0; if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, buffer2, buffer2_len, - &dvbdmxfilter->feed->feed.ts); + &dvbdmxfilter->feed->feed.ts, + NULL); else av7110_p2t_write(buffer1, buffer1_len, dvbdmxfilter->feed->pid, diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index 4daba76ec240bc..ef1bc17cdc4d37 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c @@ -99,7 +99,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) buf[4] = buf[5] = 0; if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) return dvbdmxfeed->cb.ts(buf, len, NULL, 0, - &dvbdmxfeed->feed.ts); + &dvbdmxfeed->feed.ts, NULL); else return dvb_filter_pes2ts(p2t, buf, len, 1); } @@ -109,7 +109,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; dvbdmxfeed->cb.ts(data, 188, NULL, 0, - &dvbdmxfeed->feed.ts); + &dvbdmxfeed->feed.ts, NULL); return 0; } @@ -814,7 +814,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, memcpy(obuf + l, buf + c, TS_SIZE - l); c = length; } - feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts); + feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, NULL); pes_start = 0; } } diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index a8900f5571f784..44ca66cb9b8f14 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -428,7 +428,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) struct ttusb_dec *dec = priv; dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, - &dec->audio_filter->feed->feed.ts); + &dec->audio_filter->feed->feed.ts, NULL); return 0; } @@ -438,7 +438,7 @@ static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) struct ttusb_dec *dec = priv; dec->video_filter->feed->cb.ts(data, 188, NULL, 0, - &dec->video_filter->feed->feed.ts); + &dec->video_filter->feed->feed.ts, NULL); return 0; } @@ -490,7 +490,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) if (output_pva) { dec->video_filter->feed->cb.ts(pva, length, NULL, 0, - &dec->video_filter->feed->feed.ts); + &dec->video_filter->feed->feed.ts, NULL); return; } @@ -551,7 +551,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) case 0x02: /* MainAudioStream */ if (output_pva) { dec->audio_filter->feed->cb.ts(pva, length, NULL, 0, - &dec->audio_filter->feed->feed.ts); + &dec->audio_filter->feed->feed.ts, NULL); return; } @@ -589,7 +589,7 @@ static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet, if (filter) filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, - &filter->filter); + &filter->filter, NULL); } static void ttusb_dec_process_packet(struct ttusb_dec *dec) diff --git a/include/media/demux.h b/include/media/demux.h index c4df6cee48e6ab..bf00a5a41a9064 100644 --- a/include/media/demux.h +++ b/include/media/demux.h @@ -117,7 +117,7 @@ struct dmx_ts_feed { * specified by @filter_value that will be used on the filter * match logic. * @filter_mode: Contains a 16 bytes (128 bits) filter mode. - * @parent: Pointer to struct dmx_section_feed. + * @parent: Back-pointer to struct dmx_section_feed. * @priv: Pointer to private data of the API client. * * @@ -130,8 +130,9 @@ struct dmx_section_filter { u8 filter_value[DMX_MAX_FILTER_SIZE]; u8 filter_mask[DMX_MAX_FILTER_SIZE]; u8 filter_mode[DMX_MAX_FILTER_SIZE]; - struct dmx_section_feed *parent; /* Back-pointer */ - void *priv; /* Pointer to private data of the API client */ + struct dmx_section_feed *parent; + + void *priv; }; /** @@ -193,6 +194,10 @@ struct dmx_section_feed { * @buffer2: Pointer to the tail of the filtered TS packets, or NULL. * @buffer2_length: Length of the TS data in buffer2. * @source: Indicates which TS feed is the source of the callback. + * @buffer_flags: Address where buffer flags are stored. Those are + * used to report discontinuity users via DVB + * memory mapped API, as defined by + * &enum dmx_buffer_flags. * * This function callback prototype, provided by the client of the demux API, * is called from the demux code. The function is only called when filtering @@ -245,7 +250,8 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1, size_t buffer1_length, const u8 *buffer2, size_t buffer2_length, - struct dmx_ts_feed *source); + struct dmx_ts_feed *source, + u32 *buffer_flags); /** * typedef dmx_section_cb - DVB demux TS filter callback function prototype @@ -261,6 +267,10 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1, * including headers and CRC. * @source: Indicates which section feed is the source of the * callback. + * @buffer_flags: Address where buffer flags are stored. Those are + * used to report discontinuity users via DVB + * memory mapped API, as defined by + * &enum dmx_buffer_flags. * * This function callback prototype, provided by the client of the demux API, * is called from the demux code. The function is only called when @@ -286,7 +296,8 @@ typedef int (*dmx_section_cb)(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *source); + struct dmx_section_filter *source, + u32 *buffer_flags); /* * DVB Front-End diff --git a/include/media/dvb_demux.h b/include/media/dvb_demux.h index b07092038f4bde..3b6aeca7a49e44 100644 --- a/include/media/dvb_demux.h +++ b/include/media/dvb_demux.h @@ -115,6 +115,8 @@ struct dvb_demux_filter { * @pid: PID to be filtered. * @timeout: feed timeout. * @filter: pointer to &struct dvb_demux_filter. + * @buffer_flags: Buffer flags used to report discontinuity users via DVB + * memory mapped API, as defined by &enum dmx_buffer_flags. * @ts_type: type of TS, as defined by &enum ts_filter_type. * @pes_type: type of PES, as defined by &enum dmx_ts_pes. * @cc: MPEG-TS packet continuity counter @@ -145,6 +147,8 @@ struct dvb_demux_feed { ktime_t timeout; struct dvb_demux_filter *filter; + u32 buffer_flags; + enum ts_filter_type ts_type; enum dmx_ts_pes pes_type; diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h index 056adc86027248..8cb88452cd6c28 100644 --- a/include/media/dvb_vb2.h +++ b/include/media/dvb_vb2.h @@ -85,6 +85,12 @@ struct dvb_buffer { * @nonblocking: * If different than zero, device is operating on non-blocking * mode. + * @flags: buffer flags as defined by &enum dmx_buffer_flags. + * Filled only at &DMX_DQBUF. &DMX_QBUF should zero this field. + * @count: monotonic counter for filled buffers. Helps to identify + * data stream loses. Filled only at &DMX_DQBUF. &DMX_QBUF should + * zero this field. + * * @name: name of the device type. Currently, it can either be * "dvr" or "demux_filter". */ @@ -100,6 +106,10 @@ struct dvb_vb2_ctx { int buf_siz; int buf_cnt; int nonblocking; + + enum dmx_buffer_flags flags; + u32 count; + char name[DVB_VB2_NAME_MAX + 1]; }; @@ -114,7 +124,7 @@ static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx) return 0; }; #define dvb_vb2_is_streaming(ctx) (0) -#define dvb_vb2_fill_buffer(ctx, file, wait) (0) +#define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0) static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file, @@ -153,9 +163,13 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx); * @ctx: control struct for VB2 handler * @src: place where the data is stored * @len: number of bytes to be copied from @src + * @buffer_flags: + * pointer to buffer flags as defined by &enum dmx_buffer_flags. + * can be NULL. */ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, - const unsigned char *src, int len); + const unsigned char *src, int len, + enum dmx_buffer_flags *buffer_flags); /** * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV From 3dd6b560dc5d59e7cb6dbda6e85dc9af7925fcf8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 19 Feb 2018 13:23:39 -0500 Subject: [PATCH 16/48] media: Don't let tvp5150_get_vbi() go out of vbi_ram_default array As pointed by Dan, possible values for bits[3:0] of te Line Mode Registers can range from 0x0 to 0xf, but the check logic allow values ranging from 0x0 to 0xe. As static arrays are initialized with zero, using a value without an explicit initializer at the array won't cause any harm. Reported-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 88 +++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 3c1851984b907a..2476d812f66947 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -505,80 +505,77 @@ static struct i2c_vbi_ram_value vbi_ram_default[] = /* FIXME: Current api doesn't handle all VBI types, those not yet supported are placed under #if 0 */ #if 0 - {0x010, /* Teletext, SECAM, WST System A */ + [0] = {0x010, /* Teletext, SECAM, WST System A */ {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } }, #endif - {0x030, /* Teletext, PAL, WST System B */ + [1] = {0x030, /* Teletext, PAL, WST System B */ {V4L2_SLICED_TELETEXT_B,6,22,1}, { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } }, #if 0 - {0x050, /* Teletext, PAL, WST System C */ + [2] = {0x050, /* Teletext, PAL, WST System C */ {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, - {0x070, /* Teletext, NTSC, WST System B */ + [3] = {0x070, /* Teletext, NTSC, WST System B */ {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, - {0x090, /* Tetetext, NTSC NABTS System C */ + [4] = {0x090, /* Tetetext, NTSC NABTS System C */ {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } }, - {0x0b0, /* Teletext, NTSC-J, NABTS System D */ + [5] = {0x0b0, /* Teletext, NTSC-J, NABTS System D */ {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } }, - {0x0d0, /* Closed Caption, PAL/SECAM */ + [6] = {0x0d0, /* Closed Caption, PAL/SECAM */ {V4L2_SLICED_CAPTION_625,22,22,1}, { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } }, #endif - {0x0f0, /* Closed Caption, NTSC */ + [7] = {0x0f0, /* Closed Caption, NTSC */ {V4L2_SLICED_CAPTION_525,21,21,1}, { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } }, - {0x110, /* Wide Screen Signal, PAL/SECAM */ + [8] = {0x110, /* Wide Screen Signal, PAL/SECAM */ {V4L2_SLICED_WSS_625,23,23,1}, { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } }, #if 0 - {0x130, /* Wide Screen Signal, NTSC C */ + [9] = {0x130, /* Wide Screen Signal, NTSC C */ {V4L2_SLICED_WSS_525,20,20,1}, { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } }, - {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ + [10] = {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ {V4l2_SLICED_VITC_625,6,22,0}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } }, - {0x170, /* Vertical Interval Timecode (VITC), NTSC */ + [11] = {0x170, /* Vertical Interval Timecode (VITC), NTSC */ {V4l2_SLICED_VITC_525,10,20,0}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } }, #endif - {0x190, /* Video Program System (VPS), PAL */ + [12] = {0x190, /* Video Program System (VPS), PAL */ {V4L2_SLICED_VPS,16,16,0}, { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 } }, /* 0x1d0 User programmable */ - - /* End of struct */ - { (u16)-1 } }; static int tvp5150_write_inittab(struct v4l2_subdev *sd, @@ -591,10 +588,10 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd, return 0; } -static int tvp5150_vdp_init(struct v4l2_subdev *sd, - const struct i2c_vbi_ram_value *regs) +static int tvp5150_vdp_init(struct v4l2_subdev *sd) { unsigned int i; + int j; /* Disable Full Field */ tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); @@ -604,14 +601,17 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd, tvp5150_write(sd, i, 0xff); /* Load Ram Table */ - while (regs->reg != (u16)-1) { + for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) { + const struct i2c_vbi_ram_value *regs = &vbi_ram_default[j]; + + if (!regs->type.vbi_type) + continue; + tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); for (i = 0; i < 16; i++) tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]); - - regs++; } return 0; } @@ -620,19 +620,23 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd, static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap) { - const struct i2c_vbi_ram_value *regs = vbi_ram_default; - int line; + int line, i; dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n"); memset(cap, 0, sizeof *cap); - while (regs->reg != (u16)-1 ) { - for (line=regs->type.ini_line;line<=regs->type.end_line;line++) { + for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) { + const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i]; + + if (!regs->type.vbi_type) + continue; + + for (line = regs->type.ini_line; + line <= regs->type.end_line; + line++) { cap->service_lines[0][line] |= regs->type.vbi_type; } cap->service_set |= regs->type.vbi_type; - - regs++; } return 0; } @@ -651,14 +655,13 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, * MSB = field2 */ static int tvp5150_set_vbi(struct v4l2_subdev *sd, - const struct i2c_vbi_ram_value *regs, unsigned int type,u8 flags, int line, const int fields) { struct tvp5150 *decoder = to_tvp5150(sd); v4l2_std_id std = decoder->norm; u8 reg; - int pos = 0; + int i, pos = 0; if (std == V4L2_STD_ALL) { dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n"); @@ -671,19 +674,19 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd, if (line < 6 || line > 27) return 0; - while (regs->reg != (u16)-1) { + for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) { + const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i]; + + if (!regs->type.vbi_type) + continue; + if ((type & regs->type.vbi_type) && (line >= regs->type.ini_line) && (line <= regs->type.end_line)) break; - - regs++; pos++; } - if (regs->reg == (u16)-1) - return 0; - type = pos | (flags & 0xf0); reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; @@ -696,8 +699,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd, return type; } -static int tvp5150_get_vbi(struct v4l2_subdev *sd, - const struct i2c_vbi_ram_value *regs, int line) +static int tvp5150_get_vbi(struct v4l2_subdev *sd, int line) { struct tvp5150 *decoder = to_tvp5150(sd); v4l2_std_id std = decoder->norm; @@ -726,8 +728,8 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd, return 0; } pos = ret & 0x0f; - if (pos < 0x0f) - type |= regs[pos].type.vbi_type; + if (pos < ARRAY_SIZE(vbi_ram_default)) + type |= vbi_ram_default[pos].type.vbi_type; } return type; @@ -788,7 +790,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) tvp5150_write_inittab(sd, tvp5150_init_default); /* Initializes VDP registers */ - tvp5150_vdp_init(sd, vbi_ram_default); + tvp5150_vdp_init(sd); /* Selects decoder input */ tvp5150_selmux(sd); @@ -1121,8 +1123,8 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f for (i = 0; i <= 23; i++) { svbi->service_lines[1][i] = 0; svbi->service_lines[0][i] = - tvp5150_set_vbi(sd, vbi_ram_default, - svbi->service_lines[0][i], 0xf0, i, 3); + tvp5150_set_vbi(sd, svbi->service_lines[0][i], + 0xf0, i, 3); } /* Enables FIFO */ tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1); @@ -1148,7 +1150,7 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f for (i = 0; i <= 23; i++) { svbi->service_lines[0][i] = - tvp5150_get_vbi(sd, vbi_ram_default, i); + tvp5150_get_vbi(sd, i); mask |= svbi->service_lines[0][i]; } svbi->service_set = mask; From 7dbdd16a79a9d27d7dca0a49029fc8966dcfecc5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 26 Feb 2018 11:30:40 -0500 Subject: [PATCH 17/48] media: vb2: Makefile: place vb2-trace together with vb2-core We don't want a separate module for vb2-trace. That fixes this warning: WARNING: modpost: missing MODULE_LICENSE() in drivers/media/common/videobuf2/vb2-trace.o When building as module. While here, add a SPDX header. Reported-by: Stephen Rothwell Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/videobuf2/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile index 067badb1aaa72d..77bebe8b202f46 100644 --- a/drivers/media/common/videobuf2/Makefile +++ b/drivers/media/common/videobuf2/Makefile @@ -1,11 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +videobuf2-common-objs := videobuf2-core.o -obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o +ifeq ($(CONFIG_TRACEPOINTS),y) + videobuf2-common-objs += vb2-trace.o +endif + +obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-common.o obj-$(CONFIG_VIDEOBUF2_V4L2) += videobuf2-v4l2.o obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o obj-$(CONFIG_VIDEOBUF2_DVB) += videobuf2-dvb.o -ifeq ($(CONFIG_TRACEPOINTS),y) - obj-$(CONFIG_VIDEOBUF2_CORE) += vb2-trace.o -endif From 9d4949b4935831be10534d5432bf611285a572a5 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 26 Feb 2018 18:50:35 +0200 Subject: [PATCH 18/48] dax: ->direct_access does not sleep anymore In Patch: [7a862fb] brd: remove dax support Dan Williams has removed the only might_sleep implementation of ->direct_access. So we no longer need to check for it. CC: Dan Williams Signed-off-by: Boaz Harrosh Signed-off-by: Dan Williams --- drivers/dax/super.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/dax/super.c b/drivers/dax/super.c index 473af694ad1cbe..ecdc292aa4e4d8 100644 --- a/drivers/dax/super.c +++ b/drivers/dax/super.c @@ -246,12 +246,6 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages, { long avail; - /* - * The device driver is allowed to sleep, in order to make the - * memory directly accessible. - */ - might_sleep(); - if (!dax_dev) return -EOPNOTSUPP; From 230f5a8969d8345fc9bbe3683f068246cf1be4b8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 21 Feb 2018 17:08:01 -0800 Subject: [PATCH 19/48] dax: fix vma_is_fsdax() helper Gerd reports that ->i_mode may contain other bits besides S_IFCHR. Use S_ISCHR() instead. Otherwise, get_user_pages_longterm() may fail on device-dax instances when those are meant to be explicitly allowed. Fixes: 2bb6d2837083 ("mm: introduce get_user_pages_longterm") Cc: Reported-by: Gerd Rausch Acked-by: Jane Chu Reported-by: Haozhong Zhang Reviewed-by: Jan Kara Signed-off-by: Dan Williams --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index 2a815560fda0e1..79c4139853057e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3198,7 +3198,7 @@ static inline bool vma_is_fsdax(struct vm_area_struct *vma) if (!vma_is_dax(vma)) return false; inode = file_inode(vma->vm_file); - if (inode->i_mode == S_IFCHR) + if (S_ISCHR(inode->i_mode)) return false; /* device-dax */ return true; } From c37406e05d1e541df40b8b81c4bd40753fcaf414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 26 Feb 2018 14:51:13 -0600 Subject: [PATCH 20/48] PCI: Allow release of resources that were never assigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is entirely possible that the BIOS wasn't able to assign resources to a device. In this case don't crash in pci_release_resource() when we try to resize the resource. Fixes: 8bb705e3e79d ("PCI: Add pci_resize_resource() for resizing BARs") Signed-off-by: Christian König Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko CC: stable@vger.kernel.org # v4.15+ --- drivers/pci/setup-res.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 369d48d6c6f1a5..365447240d95fe 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -401,6 +401,10 @@ void pci_release_resource(struct pci_dev *dev, int resno) struct resource *res = dev->resource + resno; pci_info(dev, "BAR %d: releasing %pR\n", resno, res); + + if (!res->parent) + return; + release_resource(res); res->end = resource_size(res) - 1; res->start = 0; From 377999caf72233af4abebb511359647f312c4e6e Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Tue, 16 Jan 2018 17:06:15 +0100 Subject: [PATCH 21/48] dt-bindings: at24: sort manufacturers alphabetically Makes them easier to find. Signed-off-by: Peter Rosin Acked-by: Rob Herring Signed-off-by: Bartosz Golaszewski --- Documentation/devicetree/bindings/eeprom/at24.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/eeprom/at24.txt b/Documentation/devicetree/bindings/eeprom/at24.txt index 1812c848e369e2..abfae1beca2b4d 100644 --- a/Documentation/devicetree/bindings/eeprom/at24.txt +++ b/Documentation/devicetree/bindings/eeprom/at24.txt @@ -38,9 +38,9 @@ Required properties: "catalyst", "microchip", + "nxp", "ramtron", "renesas", - "nxp", "st", Some vendors use different model names for chips which are just From 61277981dd535ee4b5947b6069badb16f3a21ace Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Tue, 13 Feb 2018 08:58:20 +0100 Subject: [PATCH 22/48] Makefile: Fix lying comment re. silentoldconfig The comment above the silentoldconfig invocation is outdated. 'make oldconfig' updates just .config and doesn't touch the include/config/ tree. This came up in https://lkml.org/lkml/2018/2/12/415. While fixing the comment, make it more informative by explaining the purpose of the unfortunately named silentoldconfig. I can't make sense of the comment re. auto.conf.cmd and a cleaned tree. include/config/auto.conf and include/config/auto.conf.cmd are both created simultaneously by silentoldconfig (in scripts/kconfig/confdata.c, by conf_write_autoconf()), and nothing seems to remove auto.conf.cmd that wouldn't remove auto.conf. Remove that part of the comment rather than blindly copying it. It might be a leftover from an older way of doing things. The include/config/auto.conf.cmd prerequisite might be there to ensure that silentoldconfig gets rerun if conf_write_autoconf() fails between writing out auto.conf.cmd and auto.conf (a comment in the function indicates that auto.conf is deliberately written out last to mark completion of the operation). It seems the Makefile dependency between include/config/auto.conf and .config would already take care of that though, since include/config/auto.conf would still be out of date re. .config if the operation fails. Cop out and leave the prerequisite in for now. Signed-off-by: Ulf Magnusson Signed-off-by: Masahiro Yamada --- Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 659a7780aeb3c7..ae07c704ba6f22 100644 --- a/Makefile +++ b/Makefile @@ -579,10 +579,9 @@ ifeq ($(KBUILD_EXTMOD),) # To avoid any implicit rule to kick in, define an empty command $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; -# If .config is newer than include/config/auto.conf, someone tinkered -# with it and forgot to run make oldconfig. -# if auto.conf.cmd is missing then we are probably in a cleaned tree so -# we execute the config step to be sure to catch updated Kconfig files +# The actual configuration files used during the build are stored in +# include/generated/ and include/config/. Update them if .config is newer than +# include/config/auto.conf (which mirrors .config). include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else From 6c49f359ca14f973970324afc9b20208fa0bbad5 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Thu, 15 Feb 2018 22:07:50 +0100 Subject: [PATCH 23/48] kbuild: disable sparse warnings about unknown attributes Currently, sparse issues warnings on code using an attribute it doesn't know about. One of the problem with this is that these warnings have no value for the developer, it's just noise for him. At best these warnings tell something about some deficiencies of sparse itself but not about a potential problem with code analyzed. A second problem with this is that sparse release are, alas, less frequent than new attributes are added to GCC. So, avoid the noise by asking sparse to not warn about attributes it doesn't know about. Reference: https://marc.info/?l=linux-sparse&m=151871600016790 Reference: https://marc.info/?l=linux-sparse&m=151871725417322 Signed-off-by: Luc Van Oostenryck Acked-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ae07c704ba6f22..7b3080423b8a1c 100644 --- a/Makefile +++ b/Makefile @@ -388,7 +388,7 @@ PYTHON = python CHECK = sparse CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ - -Wbitwise -Wno-return-void $(CF) + -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) NOSTDINC_FLAGS = CFLAGS_MODULE = AFLAGS_MODULE = From cd81fc82b93fa408c30e08f59e5ef8caaa91d1d2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Feb 2018 03:38:31 +0900 Subject: [PATCH 24/48] kconfig: add xstrdup() helper We already have xmalloc(), xcalloc(), and xrealloc((). Add xstrdup() as well to save tedious error handling. Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 2 +- scripts/kconfig/kxgettext.c | 2 +- scripts/kconfig/lkc.h | 1 + scripts/kconfig/symbol.c | 4 ++-- scripts/kconfig/util.c | 11 +++++++++++ scripts/kconfig/zconf.y | 2 +- 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 5c12dc91ef348e..df26c7b0fe13b6 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -178,7 +178,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) case S_HEX: done: if (sym_string_valid(sym, p)) { - sym->def[def].val = strdup(p); + sym->def[def].val = xstrdup(p); sym->flags |= def_flags; } else { if (def != S_DEF_AUTO) diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c index 2858738b22d5ae..240880a89111df 100644 --- a/scripts/kconfig/kxgettext.c +++ b/scripts/kconfig/kxgettext.c @@ -101,7 +101,7 @@ static struct message *message__new(const char *msg, char *option, if (self->files == NULL) goto out_fail; - self->msg = strdup(msg); + self->msg = xstrdup(msg); if (self->msg == NULL) goto out_fail_msg; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 4e23febbe4b283..2d5ec2d0e95293 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -115,6 +115,7 @@ int file_write_dep(const char *name); void *xmalloc(size_t size); void *xcalloc(size_t nmemb, size_t size); void *xrealloc(void *p, size_t size); +char *xstrdup(const char *s); struct gstr { size_t len; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index cca9663be5ddd9..2220bc4b051bd9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -183,7 +183,7 @@ static void sym_validate_range(struct symbol *sym) sprintf(str, "%lld", val2); else sprintf(str, "0x%llx", val2); - sym->curr.val = strdup(str); + sym->curr.val = xstrdup(str); } static void sym_set_changed(struct symbol *sym) @@ -849,7 +849,7 @@ struct symbol *sym_lookup(const char *name, int flags) : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) return symbol; } - new_name = strdup(name); + new_name = xstrdup(name); } else { new_name = NULL; hash = 0; diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index b98a79e30e04a4..c6f6e21b809ffe 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -154,3 +154,14 @@ void *xrealloc(void *p, size_t size) fprintf(stderr, "Out of memory.\n"); exit(1); } + +char *xstrdup(const char *s) +{ + char *p; + + p = strdup(s); + if (p) + return p; + fprintf(stderr, "Out of memory.\n"); + exit(1); +} diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 4be98050b961fe..f5cb55f03ce59b 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -127,7 +127,7 @@ no_mainmenu_stmt: /* empty */ * later regardless of whether it comes from the 'prompt' in * mainmenu_stmt or here */ - menu_add_prompt(P_MENU, strdup("Linux Kernel Configuration"), NULL); + menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL); }; From 801e459a6f3a63af9d447e6249088c76ae16efc4 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Wed, 21 Feb 2018 13:39:51 -0600 Subject: [PATCH 25/48] KVM: x86: Add a framework for supporting MSR-based features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide a new KVM capability that allows bits within MSRs to be recognized as features. Two new ioctls are added to the /dev/kvm ioctl routine to retrieve the list of these MSRs and then retrieve their values. A kvm_x86_ops callback is used to determine support for the listed MSR-based features. Signed-off-by: Tom Lendacky Signed-off-by: Paolo Bonzini [Tweaked documentation. - Radim] Signed-off-by: Radim Krčmář --- Documentation/virtual/kvm/api.txt | 40 ++++++++++++----- arch/x86/include/asm/kvm_host.h | 2 + arch/x86/kvm/svm.c | 6 +++ arch/x86/kvm/vmx.c | 6 +++ arch/x86/kvm/x86.c | 75 ++++++++++++++++++++++++++++--- include/uapi/linux/kvm.h | 2 + 6 files changed, 114 insertions(+), 17 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 792fa8717d133e..d6b3ff51a14fd9 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -123,14 +123,15 @@ memory layout to fit in user mode), check KVM_CAP_MIPS_VZ and use the flag KVM_VM_MIPS_VZ. -4.3 KVM_GET_MSR_INDEX_LIST +4.3 KVM_GET_MSR_INDEX_LIST, KVM_GET_MSR_FEATURE_INDEX_LIST -Capability: basic +Capability: basic, KVM_CAP_GET_MSR_FEATURES for KVM_GET_MSR_FEATURE_INDEX_LIST Architectures: x86 -Type: system +Type: system ioctl Parameters: struct kvm_msr_list (in/out) Returns: 0 on success; -1 on error Errors: + EFAULT: the msr index list cannot be read from or written to E2BIG: the msr index list is to be to fit in the array specified by the user. @@ -139,16 +140,23 @@ struct kvm_msr_list { __u32 indices[0]; }; -This ioctl returns the guest msrs that are supported. The list varies -by kvm version and host processor, but does not change otherwise. The -user fills in the size of the indices array in nmsrs, and in return -kvm adjusts nmsrs to reflect the actual number of msrs and fills in -the indices array with their numbers. +The user fills in the size of the indices array in nmsrs, and in return +kvm adjusts nmsrs to reflect the actual number of msrs and fills in the +indices array with their numbers. + +KVM_GET_MSR_INDEX_LIST returns the guest msrs that are supported. The list +varies by kvm version and host processor, but does not change otherwise. Note: if kvm indicates supports MCE (KVM_CAP_MCE), then the MCE bank MSRs are not returned in the MSR list, as different vcpus can have a different number of banks, as set via the KVM_X86_SETUP_MCE ioctl. +KVM_GET_MSR_FEATURE_INDEX_LIST returns the list of MSRs that can be passed +to the KVM_GET_MSRS system ioctl. This lets userspace probe host capabilities +and processor features that are exposed via MSRs (e.g., VMX capabilities). +This list also varies by kvm version and host processor, but does not change +otherwise. + 4.4 KVM_CHECK_EXTENSION @@ -475,14 +483,22 @@ Support for this has been removed. Use KVM_SET_GUEST_DEBUG instead. 4.18 KVM_GET_MSRS -Capability: basic +Capability: basic (vcpu), KVM_CAP_GET_MSR_FEATURES (system) Architectures: x86 -Type: vcpu ioctl +Type: system ioctl, vcpu ioctl Parameters: struct kvm_msrs (in/out) -Returns: 0 on success, -1 on error +Returns: number of msrs successfully returned; + -1 on error + +When used as a system ioctl: +Reads the values of MSR-based features that are available for the VM. This +is similar to KVM_GET_SUPPORTED_CPUID, but it returns MSR indices and values. +The list of msr-based features can be obtained using KVM_GET_MSR_FEATURE_INDEX_LIST +in a system ioctl. +When used as a vcpu ioctl: Reads model-specific registers from the vcpu. Supported msr indices can -be obtained using KVM_GET_MSR_INDEX_LIST. +be obtained using KVM_GET_MSR_INDEX_LIST in a system ioctl. struct kvm_msrs { __u32 nmsrs; /* number of msrs in entries */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 0a9e330b34f029..bab0694b35c3d2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1095,6 +1095,8 @@ struct kvm_x86_ops { int (*mem_enc_op)(struct kvm *kvm, void __user *argp); int (*mem_enc_reg_region)(struct kvm *kvm, struct kvm_enc_region *argp); int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region *argp); + + int (*get_msr_feature)(struct kvm_msr_entry *entry); }; struct kvm_arch_async_pf { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 3d8377f75eda2d..d8db947acf7025 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3869,6 +3869,11 @@ static int cr8_write_interception(struct vcpu_svm *svm) return 0; } +static int svm_get_msr_feature(struct kvm_msr_entry *msr) +{ + return 1; +} + static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct vcpu_svm *svm = to_svm(vcpu); @@ -6832,6 +6837,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .vcpu_unblocking = svm_vcpu_unblocking, .update_bp_intercept = update_bp_intercept, + .get_msr_feature = svm_get_msr_feature, .get_msr = svm_get_msr, .set_msr = svm_set_msr, .get_segment_base = svm_get_segment_base, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ec14f2319a87d2..fafc1f6d8987c2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3226,6 +3226,11 @@ static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu, return !(val & ~valid_bits); } +static int vmx_get_msr_feature(struct kvm_msr_entry *msr) +{ + return 1; +} + /* * Reads an msr value (of 'msr_index') into 'pdata'. * Returns 0 on success, non-0 otherwise. @@ -12296,6 +12301,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { .vcpu_put = vmx_vcpu_put, .update_bp_intercept = update_exception_bitmap, + .get_msr_feature = vmx_get_msr_feature, .get_msr = vmx_get_msr, .set_msr = vmx_set_msr, .get_segment_base = vmx_get_segment_base, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 96edda878dbf43..239fc1fd784535 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1049,6 +1049,28 @@ static u32 emulated_msrs[] = { static unsigned num_emulated_msrs; +/* + * List of msr numbers which are used to expose MSR-based features that + * can be used by a hypervisor to validate requested CPU features. + */ +static u32 msr_based_features[] = { +}; + +static unsigned int num_msr_based_features; + +static int do_get_msr_feature(struct kvm_vcpu *vcpu, unsigned index, u64 *data) +{ + struct kvm_msr_entry msr; + + msr.index = index; + if (kvm_x86_ops->get_msr_feature(&msr)) + return 1; + + *data = msr.data; + + return 0; +} + bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer) { if (efer & efer_reserved_bits) @@ -2680,13 +2702,11 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs, int (*do_msr)(struct kvm_vcpu *vcpu, unsigned index, u64 *data)) { - int i, idx; + int i; - idx = srcu_read_lock(&vcpu->kvm->srcu); for (i = 0; i < msrs->nmsrs; ++i) if (do_msr(vcpu, entries[i].index, &entries[i].data)) break; - srcu_read_unlock(&vcpu->kvm->srcu, idx); return i; } @@ -2785,6 +2805,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_SET_BOOT_CPU_ID: case KVM_CAP_SPLIT_IRQCHIP: case KVM_CAP_IMMEDIATE_EXIT: + case KVM_CAP_GET_MSR_FEATURES: r = 1; break; case KVM_CAP_ADJUST_CLOCK: @@ -2899,6 +2920,31 @@ long kvm_arch_dev_ioctl(struct file *filp, goto out; r = 0; break; + case KVM_GET_MSR_FEATURE_INDEX_LIST: { + struct kvm_msr_list __user *user_msr_list = argp; + struct kvm_msr_list msr_list; + unsigned int n; + + r = -EFAULT; + if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list))) + goto out; + n = msr_list.nmsrs; + msr_list.nmsrs = num_msr_based_features; + if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list))) + goto out; + r = -E2BIG; + if (n < msr_list.nmsrs) + goto out; + r = -EFAULT; + if (copy_to_user(user_msr_list->indices, &msr_based_features, + num_msr_based_features * sizeof(u32))) + goto out; + r = 0; + break; + } + case KVM_GET_MSRS: + r = msr_io(NULL, argp, do_get_msr_feature, 1); + break; } default: r = -EINVAL; @@ -3636,12 +3682,18 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = 0; break; } - case KVM_GET_MSRS: + case KVM_GET_MSRS: { + int idx = srcu_read_lock(&vcpu->kvm->srcu); r = msr_io(vcpu, argp, do_get_msr, 1); + srcu_read_unlock(&vcpu->kvm->srcu, idx); break; - case KVM_SET_MSRS: + } + case KVM_SET_MSRS: { + int idx = srcu_read_lock(&vcpu->kvm->srcu); r = msr_io(vcpu, argp, do_set_msr, 0); + srcu_read_unlock(&vcpu->kvm->srcu, idx); break; + } case KVM_TPR_ACCESS_REPORTING: { struct kvm_tpr_access_ctl tac; @@ -4464,6 +4516,19 @@ static void kvm_init_msr_list(void) j++; } num_emulated_msrs = j; + + for (i = j = 0; i < ARRAY_SIZE(msr_based_features); i++) { + struct kvm_msr_entry msr; + + msr.index = msr_based_features[i]; + if (kvm_x86_ops->get_msr_feature(&msr)) + continue; + + if (j < i) + msr_based_features[j] = msr_based_features[i]; + j++; + } + num_msr_based_features = j; } static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len, diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 0fb5ef93973251..7b26d4b0b05296 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -761,6 +761,7 @@ struct kvm_ppc_resize_hpt { #define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 #define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 #define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2) +#define KVM_GET_MSR_FEATURE_INDEX_LIST _IOWR(KVMIO, 0x0a, struct kvm_msr_list) /* * Extension capability list. @@ -934,6 +935,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_S390_AIS_MIGRATION 150 #define KVM_CAP_PPC_GET_CPU_CHAR 151 #define KVM_CAP_S390_BPB 152 +#define KVM_CAP_GET_MSR_FEATURES 153 #ifdef KVM_CAP_IRQ_ROUTING From d1d93fa90f1afa926cb060b7f78ab01a65705b4d Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Sat, 24 Feb 2018 00:18:20 +0100 Subject: [PATCH 26/48] KVM: SVM: Add MSR-based feature support for serializing LFENCE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to determine if LFENCE is a serializing instruction on AMD processors, MSR 0xc0011029 (MSR_F10H_DECFG) must be read and the state of bit 1 checked. This patch will add support to allow a guest to properly make this determination. Add the MSR feature callback operation to svm.c and add MSR 0xc0011029 to the list of MSR-based features. If LFENCE is serializing, then the feature is supported, allowing the hypervisor to set the value of the MSR that guest will see. Support is also added to write (hypervisor only) and read the MSR value for the guest. A write by the guest will result in a #GP. A read by the guest will return the value as set by the host. In this way, the support to expose the feature to the guest is controlled by the hypervisor. Reviewed-by: Paolo Bonzini Signed-off-by: Tom Lendacky Signed-off-by: Paolo Bonzini Signed-off-by: Radim Krčmář --- arch/x86/kvm/svm.c | 36 +++++++++++++++++++++++++++++++++++- arch/x86/kvm/x86.c | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d8db947acf7025..f874798f820992 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -178,6 +178,8 @@ struct vcpu_svm { uint64_t sysenter_eip; uint64_t tsc_aux; + u64 msr_decfg; + u64 next_rip; u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; @@ -3871,7 +3873,18 @@ static int cr8_write_interception(struct vcpu_svm *svm) static int svm_get_msr_feature(struct kvm_msr_entry *msr) { - return 1; + msr->data = 0; + + switch (msr->index) { + case MSR_F10H_DECFG: + if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) + msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE; + break; + default: + return 1; + } + + return 0; } static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) @@ -3969,6 +3982,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = 0x1E; } break; + case MSR_F10H_DECFG: + msr_info->data = svm->msr_decfg; + break; default: return kvm_get_msr_common(vcpu, msr_info); } @@ -4147,6 +4163,24 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) case MSR_VM_IGNNE: vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); break; + case MSR_F10H_DECFG: { + struct kvm_msr_entry msr_entry; + + msr_entry.index = msr->index; + if (svm_get_msr_feature(&msr_entry)) + return 1; + + /* Check the supported bits */ + if (data & ~msr_entry.data) + return 1; + + /* Don't allow the guest to change a bit, #GP */ + if (!msr->host_initiated && (data ^ msr_entry.data)) + return 1; + + svm->msr_decfg = data; + break; + } case MSR_IA32_APICBASE: if (kvm_vcpu_apicv_active(vcpu)) avic_update_vapic_bar(to_svm(vcpu), data); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 239fc1fd784535..54b4ed55945b67 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1054,6 +1054,7 @@ static unsigned num_emulated_msrs; * can be used by a hypervisor to validate requested CPU features. */ static u32 msr_based_features[] = { + MSR_F10H_DECFG, }; static unsigned int num_msr_based_features; From 66421c1ec340096b291af763ed5721314cdd9c5c Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Wed, 28 Feb 2018 14:03:30 +0800 Subject: [PATCH 27/48] KVM: X86: Introduce kvm_get_msr_feature() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce kvm_get_msr_feature() to handle the msrs which are supported by different vendors and sharing the same emulation logic. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Liran Alon Cc: Nadav Amit Cc: Borislav Petkov Cc: Tom Lendacky Signed-off-by: Wanpeng Li Reviewed-by: Paolo Bonzini Signed-off-by: Radim Krčmář --- arch/x86/kvm/x86.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 54b4ed55945b67..d97620eeb394f5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1059,13 +1059,25 @@ static u32 msr_based_features[] = { static unsigned int num_msr_based_features; +static int kvm_get_msr_feature(struct kvm_msr_entry *msr) +{ + switch (msr->index) { + default: + if (kvm_x86_ops->get_msr_feature(msr)) + return 1; + } + return 0; +} + static int do_get_msr_feature(struct kvm_vcpu *vcpu, unsigned index, u64 *data) { struct kvm_msr_entry msr; + int r; msr.index = index; - if (kvm_x86_ops->get_msr_feature(&msr)) - return 1; + r = kvm_get_msr_feature(&msr); + if (r) + return r; *data = msr.data; @@ -4522,7 +4534,7 @@ static void kvm_init_msr_list(void) struct kvm_msr_entry msr; msr.index = msr_based_features[i]; - if (kvm_x86_ops->get_msr_feature(&msr)) + if (kvm_get_msr_feature(&msr)) continue; if (j < i) From 518e7b94817abed94becfe6a44f1ece0d4745afe Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Wed, 28 Feb 2018 14:03:31 +0800 Subject: [PATCH 28/48] KVM: X86: Allow userspace to define the microcode version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux (among the others) has checks to make sure that certain features aren't enabled on a certain family/model/stepping if the microcode version isn't greater than or equal to a known good version. By exposing the real microcode version, we're preventing buggy guests that don't check that they are running virtualized (i.e., they should trust the hypervisor) from disabling features that are effectively not buggy. Suggested-by: Filippo Sironi Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Liran Alon Cc: Nadav Amit Cc: Borislav Petkov Cc: Tom Lendacky Signed-off-by: Wanpeng Li Reviewed-by: Paolo Bonzini Signed-off-by: Radim Krčmář --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/svm.c | 4 +--- arch/x86/kvm/vmx.c | 1 + arch/x86/kvm/x86.c | 11 +++++++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index bab0694b35c3d2..b605a5b6a30c38 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -507,6 +507,7 @@ struct kvm_vcpu_arch { u64 smi_count; bool tpr_access_reporting; u64 ia32_xss; + u64 microcode_version; /* * Paging state of the vcpu diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f874798f820992..312f33f4ed36ac 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1907,6 +1907,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) u32 dummy; u32 eax = 1; + vcpu->arch.microcode_version = 0x01000065; svm->spec_ctrl = 0; if (!init_event) { @@ -3962,9 +3963,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = svm->spec_ctrl; break; - case MSR_IA32_UCODE_REV: - msr_info->data = 0x01000065; - break; case MSR_F15H_IC_CFG: { int family, model; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fafc1f6d8987c2..59121484304655 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5771,6 +5771,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmx->rmode.vm86_active = 0; vmx->spec_ctrl = 0; + vcpu->arch.microcode_version = 0x100000000ULL; vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); kvm_set_cr8(vcpu, 0); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d97620eeb394f5..11649d290b9363 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1055,6 +1055,7 @@ static unsigned num_emulated_msrs; */ static u32 msr_based_features[] = { MSR_F10H_DECFG, + MSR_IA32_UCODE_REV, }; static unsigned int num_msr_based_features; @@ -1062,6 +1063,9 @@ static unsigned int num_msr_based_features; static int kvm_get_msr_feature(struct kvm_msr_entry *msr) { switch (msr->index) { + case MSR_IA32_UCODE_REV: + rdmsrl(msr->index, msr->data); + break; default: if (kvm_x86_ops->get_msr_feature(msr)) return 1; @@ -2257,7 +2261,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) switch (msr) { case MSR_AMD64_NB_CFG: - case MSR_IA32_UCODE_REV: case MSR_IA32_UCODE_WRITE: case MSR_VM_HSAVE_PA: case MSR_AMD64_PATCH_LOADER: @@ -2265,6 +2268,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_AMD64_DC_CFG: break; + case MSR_IA32_UCODE_REV: + if (msr_info->host_initiated) + vcpu->arch.microcode_version = data; + break; case MSR_EFER: return set_efer(vcpu, data); case MSR_K7_HWCR: @@ -2560,7 +2567,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = 0; break; case MSR_IA32_UCODE_REV: - msr_info->data = 0x100000000ULL; + msr_info->data = vcpu->arch.microcode_version; break; case MSR_MTRRcap: case 0x200 ... 0x2ff: From b7e31be385584afe7f073130e8e570d53c95f7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 1 Mar 2018 15:24:25 +0100 Subject: [PATCH 29/48] KVM: x86: fix vcpu initialization with userspace lapic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moving the code around broke this rare configuration. Use this opportunity to finally call lapic reset from vcpu reset. Reported-by: syzbot+fb7a33a4b6c35007a72b@syzkaller.appspotmail.com Suggested-by: Paolo Bonzini Fixes: 0b2e9904c159 ("KVM: x86: move LAPIC initialization after VMCS creation") Cc: stable@vger.kernel.org Signed-off-by: Radim Krčmář --- arch/x86/kvm/lapic.c | 10 ++++------ arch/x86/kvm/x86.c | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index cc5fe7a50dde2b..391dda8d43b7a4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2002,14 +2002,13 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) { - struct kvm_lapic *apic; + struct kvm_lapic *apic = vcpu->arch.apic; int i; - apic_debug("%s\n", __func__); + if (!apic) + return; - ASSERT(vcpu); - apic = vcpu->arch.apic; - ASSERT(apic != NULL); + apic_debug("%s\n", __func__); /* Stop the timer in case it's a reset to an active apic */ hrtimer_cancel(&apic->lapic_timer.timer); @@ -2568,7 +2567,6 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) pe = xchg(&apic->pending_events, 0); if (test_bit(KVM_APIC_INIT, &pe)) { - kvm_lapic_reset(vcpu, true); kvm_vcpu_reset(vcpu, true); if (kvm_vcpu_is_bsp(apic->vcpu)) vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 11649d290b9363..18b5ca7a319747 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8060,7 +8060,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) kvm_vcpu_mtrr_init(vcpu); vcpu_load(vcpu); kvm_vcpu_reset(vcpu, false); - kvm_lapic_reset(vcpu, false); kvm_mmu_setup(vcpu); vcpu_put(vcpu); return 0; @@ -8103,6 +8102,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { + kvm_lapic_reset(vcpu, init_event); + vcpu->arch.hflags = 0; vcpu->arch.smi_pending = 0; From f4bc1eefc1608e9a7d40f5fdfc3acd560ba6f477 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Feb 2018 03:38:32 +0900 Subject: [PATCH 30/48] kconfig: set SYMBOL_AUTO to the symbol marked with defconfig_list The 'defconfig_list' is a weird attribute. If the '.config' is missing, conf_read_simple() iterates over all visible defaults, then it uses the first one for which fopen() succeeds. config DEFCONFIG_LIST string depends on !UML option defconfig_list default "/lib/modules/$UNAME_RELEASE/.config" default "/etc/kernel-config" default "/boot/config-$UNAME_RELEASE" default "$ARCH_DEFCONFIG" default "arch/$ARCH/defconfig" However, like other symbols, the first visible default is always written out to the .config file. This might be different from what has been actually used. For example, on my machine, the third one "/boot/config-$UNAME_RELEASE" is opened, like follows: $ rm .config $ make oldconfig 2>/dev/null scripts/kconfig/conf --oldconfig Kconfig # # using defaults found in /boot/config-4.4.0-112-generic # * * Restart config... * * * IRQ subsystem * Expose irq internals in debugfs (GENERIC_IRQ_DEBUGFS) [N/y/?] (NEW) However, the resulted .config file contains the first one since it is visible: $ grep CONFIG_DEFCONFIG_LIST .config CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" In order to stop confusing people, prevent this CONFIG option from being written to the .config file. Signed-off-by: Masahiro Yamada Reviewed-by: Ulf Magnusson --- scripts/kconfig/menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 99222855544c3a..36cd3e1f1c2889 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -212,6 +212,7 @@ void menu_add_option(int token, char *arg) sym_defconfig_list = current_entry->sym; else if (sym_defconfig_list != current_entry->sym) zconf_error("trying to redefine defconfig symbol"); + sym_defconfig_list->flags |= SYMBOL_AUTO; break; case T_OPT_ENV: prop_add_env(arg); From 1b1e4ee86e0064ea2a8b8e5ead13734b1e813a92 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 20 Feb 2018 02:09:42 +0900 Subject: [PATCH 31/48] sh: fix build error for empty CONFIG_BUILTIN_DTB_SOURCE If CONFIG_USE_BUILTIN_DTB is enabled, but CONFIG_BUILTIN_DTB_SOURCE is empty (for example, allmodconfig), it fails to build, like this: make[2]: *** No rule to make target 'arch/sh/boot/dts/.dtb.o', needed by 'arch/sh/boot/dts/built-in.o'. Stop. Surround obj-y with ifneq ... endif. I replaced $(CONFIG_USE_BUILTIN_DTB) with 'y' since this is always the case from the following code from arch/sh/Makefile: core-$(CONFIG_USE_BUILTIN_DTB) += arch/sh/boot/dts/ Signed-off-by: Masahiro Yamada --- arch/sh/boot/dts/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/sh/boot/dts/Makefile b/arch/sh/boot/dts/Makefile index 715def00a436c2..01d0f7fb14cce7 100644 --- a/arch/sh/boot/dts/Makefile +++ b/arch/sh/boot/dts/Makefile @@ -1 +1,3 @@ -obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o +ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"") +obj-y += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o +endif From bf0bbdcf1003220b7ca9a6aa00a84e27e94287e8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 20 Feb 2018 20:40:29 +0900 Subject: [PATCH 32/48] kconfig: Don't leak choice names during parsing The named choice is not used in the kernel tree, but if it were used, it would not be freed. The intention of the named choice can be seen in the log of commit 5a1aa8a1aff6 ("kconfig: add named choice group"). Signed-off-by: Masahiro Yamada Reviewed-by: Ulf Magnusson --- scripts/kconfig/zconf.y | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index f5cb55f03ce59b..ad6305b0f40cb9 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -276,6 +276,7 @@ choice: T_CHOICE word_opt T_EOL sym->flags |= SYMBOL_AUTO; menu_add_entry(sym); menu_add_expr(P_CHOICE, NULL, NULL); + free($2); printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); }; From a7b151fffbf5236dd24b60aa0a83dc1c53c9f6c0 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Wed, 21 Feb 2018 12:25:07 +0800 Subject: [PATCH 33/48] kbuild: drop superfluous GCC_PLUGINS_CFLAGS assignment GCC_PLUGINS_CFLAGS is already in the environment, so it is superfluous to add it in commandline of final build of init/. Signed-off-by: Cao jin Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index c0d129d7f4304a..be56a1153014af 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -246,7 +246,7 @@ else fi; # final build of init/ -${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}" +${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init archive_builtin From 0da4fabdf40a36e22b50f9a4143be18a0d98963f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 23 Feb 2018 13:56:52 +0900 Subject: [PATCH 34/48] kbuild: test --build-id linker flag by ld-option instead of cc-ldoption '--build-id' is passed to $(LD), so it should be tested by 'ld-option'. This seems a kind of misconversion when ld-option was renamed to cc-ldoption. Commit f86fd3066052 ("kbuild: rename ld-option to cc-ldoption") renamed all instances of 'ld-option' to 'cc-ldoption'. Then, commit 691ef3e7fdc1 ("kbuild: introduce ld-option") re-added 'ld-option' as a new implementation. Signed-off-by: Masahiro Yamada --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7b3080423b8a1c..20c01bd3acb304 100644 --- a/Makefile +++ b/Makefile @@ -856,8 +856,7 @@ KBUILD_AFLAGS += $(ARCH_AFLAGS) $(KAFLAGS) KBUILD_CFLAGS += $(ARCH_CFLAGS) $(KCFLAGS) # Use --build-id when available. -LDFLAGS_BUILD_ID := $(patsubst -Wl$(comma)%,%,\ - $(call cc-ldoption, -Wl$(comma)--build-id,)) +LDFLAGS_BUILD_ID := $(call ld-option, --build-id) KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID) LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID) From cbf7a90e304c4f2e1a867b2245edd408a7a0ed8b Mon Sep 17 00:00:00 2001 From: Cao jin Date: Tue, 27 Feb 2018 16:16:19 +0800 Subject: [PATCH 35/48] kbuild/kallsyms: trivial typo fix Signed-off-by: Cao jin Signed-off-by: Masahiro Yamada --- scripts/kallsyms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 9ee9bf7fd1a211..65792650c63057 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -595,7 +595,7 @@ static void optimize_result(void) * original char code */ if (!best_table_len[i]) { - /* find the token with the breates profit value */ + /* find the token with the best profit value */ best = find_best_token(); if (token_profit[best] == 0) break; From 1a90ce36c6eff6fe989eabf0516beb12fc59e067 Mon Sep 17 00:00:00 2001 From: Arvind Prasanna Date: Wed, 28 Feb 2018 16:32:19 -0500 Subject: [PATCH 36/48] kconfig: Update ncurses package names for menuconfig The package name is ncurses-devel for Redhat based distros and libncurses-dev for Debian based distros. Signed-off-by: Arvind Prasanna Acked-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/kconfig/lxdialog/check-lxdialog.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index a10bd9d6fafd00..6c0bcd9c472d6b 100755 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -55,7 +55,8 @@ EOF echo " *** required header files." 1>&2 echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 echo " *** " 1>&2 - echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 + echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2 + echo " *** depending on your distribution) and try again." 1>&2 echo " *** " 1>&2 exit 1 fi From 0adb24e03a124b79130c9499731936b11ce2677d Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Tue, 27 Feb 2018 08:16:07 -0500 Subject: [PATCH 37/48] parisc: Fix ordering of cache and TLB flushes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The change to flush_kernel_vmap_range() wasn't sufficient to avoid the SMP stalls.  The problem is some drivers call these routines with interrupts disabled.  Interrupts need to be enabled for flush_tlb_all() and flush_cache_all() to work.  This version adds checks to ensure interrupts are not disabled before calling routines that need IPI interrupts.  When interrupts are disabled, we now drop into slower code. The attached change fixes the ordering of cache and TLB flushes in several cases.  When we flush the cache using the existing PTE/TLB entries, we need to flush the TLB after doing the cache flush.  We don't need to do this when we flush the entire instruction and data caches as these flushes don't use the existing TLB entries.  The same is true for tmpalias region flushes. The flush_kernel_vmap_range() and invalidate_kernel_vmap_range() routines have been updated. Secondly, we added a new purge_kernel_dcache_range_asm() routine to pacache.S and use it in invalidate_kernel_vmap_range().  Nominally, purges are faster than flushes as the cache lines don't have to be written back to memory. Hopefully, this is sufficient to resolve the remaining problems due to cache speculation.  So far, testing indicates that this is the case.  I did work up a patch using tmpalias flushes, but there is a performance hit because we need the physical address for each page, and we also need to sequence access to the tmpalias flush code.  This increases the probability of stalls. Signed-off-by: John David Anglin  Cc: stable@vger.kernel.org # 4.9+ Signed-off-by: Helge Deller --- arch/parisc/include/asm/cacheflush.h | 1 + arch/parisc/kernel/cache.c | 57 +++++++++++++++------------- arch/parisc/kernel/pacache.S | 22 +++++++++++ 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index 3742508cc53458..bd5ce31936f5b1 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h @@ -26,6 +26,7 @@ void flush_user_icache_range_asm(unsigned long, unsigned long); void flush_kernel_icache_range_asm(unsigned long, unsigned long); void flush_user_dcache_range_asm(unsigned long, unsigned long); void flush_kernel_dcache_range_asm(unsigned long, unsigned long); +void purge_kernel_dcache_range_asm(unsigned long, unsigned long); void flush_kernel_dcache_page_asm(void *); void flush_kernel_icache_page(void *); diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 19c0c141bc3f9f..79089778725b31 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -465,10 +465,10 @@ EXPORT_SYMBOL(copy_user_page); int __flush_tlb_range(unsigned long sid, unsigned long start, unsigned long end) { - unsigned long flags, size; + unsigned long flags; - size = (end - start); - if (size >= parisc_tlb_flush_threshold) { + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + end - start >= parisc_tlb_flush_threshold) { flush_tlb_all(); return 1; } @@ -539,13 +539,11 @@ void flush_cache_mm(struct mm_struct *mm) struct vm_area_struct *vma; pgd_t *pgd; - /* Flush the TLB to avoid speculation if coherency is required. */ - if (parisc_requires_coherency()) - flush_tlb_all(); - /* Flushing the whole cache on each cpu takes forever on rp3440, etc. So, avoid it if the mm isn't too big. */ - if (mm_total_size(mm) >= parisc_cache_flush_threshold) { + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + mm_total_size(mm) >= parisc_cache_flush_threshold) { + flush_tlb_all(); flush_cache_all(); return; } @@ -553,9 +551,9 @@ void flush_cache_mm(struct mm_struct *mm) if (mm->context == mfsp(3)) { for (vma = mm->mmap; vma; vma = vma->vm_next) { flush_user_dcache_range_asm(vma->vm_start, vma->vm_end); - if ((vma->vm_flags & VM_EXEC) == 0) - continue; - flush_user_icache_range_asm(vma->vm_start, vma->vm_end); + if (vma->vm_flags & VM_EXEC) + flush_user_icache_range_asm(vma->vm_start, vma->vm_end); + flush_tlb_range(vma, vma->vm_start, vma->vm_end); } return; } @@ -581,14 +579,9 @@ void flush_cache_mm(struct mm_struct *mm) void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - BUG_ON(!vma->vm_mm->context); - - /* Flush the TLB to avoid speculation if coherency is required. */ - if (parisc_requires_coherency()) + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + end - start >= parisc_cache_flush_threshold) { flush_tlb_range(vma, start, end); - - if ((end - start) >= parisc_cache_flush_threshold - || vma->vm_mm->context != mfsp(3)) { flush_cache_all(); return; } @@ -596,6 +589,7 @@ void flush_cache_range(struct vm_area_struct *vma, flush_user_dcache_range_asm(start, end); if (vma->vm_flags & VM_EXEC) flush_user_icache_range_asm(start, end); + flush_tlb_range(vma, start, end); } void @@ -604,8 +598,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long BUG_ON(!vma->vm_mm->context); if (pfn_valid(pfn)) { - if (parisc_requires_coherency()) - flush_tlb_page(vma, vmaddr); + flush_tlb_page(vma, vmaddr); __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); } } @@ -613,21 +606,33 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long void flush_kernel_vmap_range(void *vaddr, int size) { unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; - if ((unsigned long)size > parisc_cache_flush_threshold) + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + (unsigned long)size >= parisc_cache_flush_threshold) { + flush_tlb_kernel_range(start, end); flush_data_cache(); - else - flush_kernel_dcache_range_asm(start, start + size); + return; + } + + flush_kernel_dcache_range_asm(start, end); + flush_tlb_kernel_range(start, end); } EXPORT_SYMBOL(flush_kernel_vmap_range); void invalidate_kernel_vmap_range(void *vaddr, int size) { unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; - if ((unsigned long)size > parisc_cache_flush_threshold) + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + (unsigned long)size >= parisc_cache_flush_threshold) { + flush_tlb_kernel_range(start, end); flush_data_cache(); - else - flush_kernel_dcache_range_asm(start, start + size); + return; + } + + purge_kernel_dcache_range_asm(start, end); + flush_tlb_kernel_range(start, end); } EXPORT_SYMBOL(invalidate_kernel_vmap_range); diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 2d40c4ff3f6918..67b0f7532e835f 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -1110,6 +1110,28 @@ ENTRY_CFI(flush_kernel_dcache_range_asm) .procend ENDPROC_CFI(flush_kernel_dcache_range_asm) +ENTRY_CFI(purge_kernel_dcache_range_asm) + .proc + .callinfo NO_CALLS + .entry + + ldil L%dcache_stride, %r1 + ldw R%dcache_stride(%r1), %r23 + ldo -1(%r23), %r21 + ANDCM %r26, %r21, %r26 + +1: cmpb,COND(<<),n %r26, %r25,1b + pdc,m %r23(%r26) + + sync + syncdma + bv %r0(%r2) + nop + .exit + + .procend +ENDPROC_CFI(purge_kernel_dcache_range_asm) + ENTRY_CFI(flush_user_icache_range_asm) .proc .callinfo NO_CALLS From fd8d0ca2563151204f3fe555dc8ca4bcfe8677a3 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 12 Jan 2018 22:57:15 +0100 Subject: [PATCH 38/48] parisc: Hide virtual kernel memory layout For security reasons do not expose the virtual kernel memory layout to userspace. Signed-off-by: Helge Deller Suggested-by: Kees Cook Cc: stable@vger.kernel.org # 4.15 Reviewed-by: Kees Cook --- arch/parisc/mm/init.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 48f41399fc0b8b..cab32ee824d2ac 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -629,7 +629,12 @@ void __init mem_init(void) #endif mem_init_print_info(NULL); -#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */ + +#if 0 + /* + * Do not expose the virtual kernel memory layout to userspace. + * But keep code for debugging purposes. + */ printk("virtual kernel memory layout:\n" " vmalloc : 0x%px - 0x%px (%4ld MB)\n" " memory : 0x%px - 0x%px (%4ld MB)\n" From 0ed1fe4ad394e54783bbffa84102faf435661a2e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 12 Jan 2018 22:51:22 +0100 Subject: [PATCH 39/48] parisc: Check if secondary CPUs want own PDC calls The architecture specification says (for 64-bit systems): PDC is a per processor resource, and operating system software must be prepared to manage separate pointers to PDCE_PROC for each processor. The address of PDCE_PROC for the monarch processor is stored in the Page Zero location MEM_PDC. The address of PDCE_PROC for each non-monarch processor is passed in gr26 when PDCE_RESET invokes OS_RENDEZ. Currently we still use one PDC for all CPUs, but in case we face a machine which is following the specification let's warn about it. Signed-off-by: Helge Deller --- arch/parisc/kernel/head.S | 18 ++++++++++++------ arch/parisc/kernel/smp.c | 7 ++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index bbbe360b458f51..fbb4e43fda0533 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -138,6 +138,16 @@ $pgt_fill_loop: std %dp,0x18(%r10) #endif +#ifdef CONFIG_64BIT + /* Get PDCE_PROC for monarch CPU. */ +#define MEM_PDC_LO 0x388 +#define MEM_PDC_HI 0x35C + ldw MEM_PDC_LO(%r0),%r3 + ldw MEM_PDC_HI(%r0),%r10 + depd %r10, 31, 32, %r3 /* move to upper word */ +#endif + + #ifdef CONFIG_SMP /* Set the smp rendezvous address into page zero. ** It would be safer to do this in init_smp_config() but @@ -196,12 +206,6 @@ common_stext: ** Someday, palo might not do this for the Monarch either. */ 2: -#define MEM_PDC_LO 0x388 -#define MEM_PDC_HI 0x35C - ldw MEM_PDC_LO(%r0),%r3 - ldw MEM_PDC_HI(%r0),%r6 - depd %r6, 31, 32, %r3 /* move to upper word */ - mfctl %cr30,%r6 /* PCX-W2 firmware bug */ ldo PDC_PSW(%r0),%arg0 /* 21 */ @@ -268,6 +272,8 @@ $install_iva: aligned_rfi: pcxt_ssm_bug + copy %r3, %arg0 /* PDCE_PROC for smp_callin() */ + rsm PSW_SM_QUIET,%r0 /* off troublesome PSW bits */ /* Don't need NOPs, have 8 compliant insn before rfi */ diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 30c28ab145409b..4065b5e48c9d68 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -292,10 +292,15 @@ smp_cpu_init(int cpunum) * Slaves start using C here. Indirectly called from smp_slave_stext. * Do what start_kernel() and main() do for boot strap processor (aka monarch) */ -void __init smp_callin(void) +void __init smp_callin(unsigned long pdce_proc) { int slave_id = cpu_now_booting; +#ifdef CONFIG_64BIT + WARN_ON(((unsigned long)(PAGE0->mem_pdc_hi) << 32 + | PAGE0->mem_pdc) != pdce_proc); +#endif + smp_cpu_init(slave_id); preempt_disable(); From 5ffa8518851f1401817c15d2a7eecc0373c26ff9 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 12 Jan 2018 22:44:00 +0100 Subject: [PATCH 40/48] parisc: Use cr16 interval timers unconditionally on qemu When running on qemu we know that the (emulated) cr16 cpu-internal clocks are syncronized. So let's use them unconditionally on qemu. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # 4.14+ --- arch/parisc/include/asm/processor.h | 2 ++ arch/parisc/kernel/time.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 0e6ab6e4a4e9f8..2dbe5580a1a442 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -316,6 +316,8 @@ extern int _parisc_requires_coherency; #define parisc_requires_coherency() (0) #endif +extern int running_on_qemu; + #endif /* __ASSEMBLY__ */ #endif /* __ASM_PARISC_PROCESSOR_H */ diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 4b8fd6dc22dabe..68e88e5c08985f 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -248,7 +248,7 @@ static int __init init_cr16_clocksource(void) * different sockets, so mark them unstable and lower rating on * multi-socket SMP systems. */ - if (num_online_cpus() > 1) { + if (num_online_cpus() > 1 && !running_on_qemu) { int cpu; unsigned long cpu0_loc; cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; From 636a415bcc7f4fd020ece8fd5fc648c4cef19c34 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Feb 2018 21:43:55 +0100 Subject: [PATCH 41/48] parisc: Reduce irq overhead when run in qemu When run under QEMU, calling mfctl(16) creates some overhead because the qemu timer has to be scaled and moved into the register. This patch reduces the number of calls to mfctl(16) by moving the calls out of the loops. Additionally, increase the minimal time interval to 8000 cycles instead of 500 to compensate possible QEMU delays when delivering interrupts. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # 4.14+ --- arch/parisc/kernel/time.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 68e88e5c08985f..f7e684560186f9 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -76,10 +76,10 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) next_tick = cpuinfo->it_value; /* Calculate how many ticks have elapsed. */ + now = mfctl(16); do { ++ticks_elapsed; next_tick += cpt; - now = mfctl(16); } while (next_tick - now > cpt); /* Store (in CR16 cycles) up to when we are accounting right now. */ @@ -103,16 +103,17 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) * if one or the other wrapped. If "now" is "bigger" we'll end up * with a very large unsigned number. */ - while (next_tick - mfctl(16) > cpt) + now = mfctl(16); + while (next_tick - now > cpt) next_tick += cpt; /* Program the IT when to deliver the next interrupt. * Only bottom 32-bits of next_tick are writable in CR16! * Timer interrupt will be delivered at least a few hundred cycles - * after the IT fires, so if we are too close (<= 500 cycles) to the + * after the IT fires, so if we are too close (<= 8000 cycles) to the * next cycle, simply skip it. */ - if (next_tick - mfctl(16) <= 500) + if (next_tick - now <= 8000) next_tick += cpt; mtctl(next_tick, 16); From 7c4246797b84e55e2dfaaf8a18033de9df7c18c1 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Tue, 27 Feb 2018 16:42:13 +0100 Subject: [PATCH 42/48] i2c: octeon: Prevent error message on bus error The error message: [Fri Feb 16 13:42:13 2018] i2c-thunderx 0000:01:09.4: unhandled state: 0 is mis-leading as state 0 (bus error) is not an unknown state. Return -EIO as before but avoid printing the message. Also rename STAT_ERROR to STATE_BUS_ERROR. Signed-off-by: Jan Glauber Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-octeon-core.c | 1 + drivers/i2c/busses/i2c-octeon-core.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c index 1d87757990568c..d9607905dc2f1d 100644 --- a/drivers/i2c/busses/i2c-octeon-core.c +++ b/drivers/i2c/busses/i2c-octeon-core.c @@ -233,6 +233,7 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read) return -EOPNOTSUPP; case STAT_TXDATA_NAK: + case STAT_BUS_ERROR: return -EIO; case STAT_TXADDR_NAK: case STAT_RXADDR_NAK: diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h index a7ef19855bb8fa..9bb9f64fdda039 100644 --- a/drivers/i2c/busses/i2c-octeon-core.h +++ b/drivers/i2c/busses/i2c-octeon-core.h @@ -43,7 +43,7 @@ #define TWSI_CTL_AAK 0x04 /* Assert ACK */ /* Status values */ -#define STAT_ERROR 0x00 +#define STAT_BUS_ERROR 0x00 #define STAT_START 0x08 #define STAT_REP_START 0x10 #define STAT_TXADDR_ACK 0x18 From a11761c2dda64737bfe47e7c15545d4648f8573c Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 1 Mar 2018 10:57:21 +0200 Subject: [PATCH 43/48] Coccinelle: memdup: Fix typo in warning messages Replace 'kmemdep' with 'kmemdup' in warning messages. Signed-off-by: Dafna Hirschfeld Acked-by: Julia Lawall Acked-by: Nicolas Palix Signed-off-by: Masahiro Yamada --- scripts/coccinelle/api/memdup.cocci | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci index 1249b727644b74..8fd6437beda807 100644 --- a/scripts/coccinelle/api/memdup.cocci +++ b/scripts/coccinelle/api/memdup.cocci @@ -56,10 +56,10 @@ statement S; p << r.p; @@ -coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep") +coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdup") @script:python depends on report@ p << r.p; @@ -coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep") +coccilib.report.print_report(p[0], "WARNING opportunity for kmemdup") From 5ae6fcc4bb82bd05996cc685b8786c586637e56d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 2 Mar 2018 16:05:12 +0900 Subject: [PATCH 44/48] kconfig: fix line number in recursive inclusion error message When recursive inclusion is detected, the line number of the last 'included from:' is wrong. [Test Case] Kconfig: -------->8-------- source "Kconfig2" -------->8-------- Kconfig2: -------->8-------- source "Kconfig3" -------->8-------- Kconfig3: -------->8-------- source "Kconfig" -------->8-------- [Result] $ make allyesconfig scripts/kconfig/conf --allyesconfig Kconfig Kconfig:1: recursive inclusion detected. Inclusion path: current file : 'Kconfig' included from: 'Kconfig3:1' included from: 'Kconfig2:1' included from: 'Kconfig:3' scripts/kconfig/Makefile:89: recipe for target 'allyesconfig' failed make[1]: *** [allyesconfig] Error 1 Makefile:512: recipe for target 'allyesconfig' failed make: *** [allyesconfig] Error 2 where we expect current file : 'Kconfig' included from: 'Kconfig3:1' included from: 'Kconfig2:1' included from: 'Kconfig:1' The 'iter->lineno+1' in the second fpinrtf() should be 'iter->lineno-1'. I refactored the code to merge the two fprintf() calls. Signed-off-by: Masahiro Yamada Reviewed-by: Ulf Magnusson --- scripts/kconfig/zconf.l | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 02de6fe302a9ae..88b650eb9cc914 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -332,16 +332,12 @@ void zconf_nextfile(const char *name) "Inclusion path:\n current file : '%s'\n", zconf_curname(), zconf_lineno(), zconf_curname()); - iter = current_file->parent; - while (iter && \ - strcmp(iter->name,current_file->name)) { - fprintf(stderr, " included from: '%s:%d'\n", - iter->name, iter->lineno-1); + iter = current_file; + do { iter = iter->parent; - } - if (iter) fprintf(stderr, " included from: '%s:%d'\n", - iter->name, iter->lineno+1); + iter->name, iter->lineno - 1); + } while (strcmp(iter->name, current_file->name)); exit(1); } } From 94db151dc89262bfa82922c44e8320cea2334667 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 4 Feb 2018 10:34:02 -0800 Subject: [PATCH 45/48] vfio: disable filesystem-dax page pinning Filesystem-DAX is incompatible with 'longterm' page pinning. Without page cache indirection a DAX mapping maps filesystem blocks directly. This means that the filesystem must not modify a file's block map while any page in a mapping is pinned. In order to prevent the situation of userspace holding of filesystem operations indefinitely, disallow 'longterm' Filesystem-DAX mappings. RDMA has the same conflict and the plan there is to add a 'with lease' mechanism to allow the kernel to notify userspace that the mapping is being torn down for block-map maintenance. Perhaps something similar can be put in place for vfio. Note that xfs and ext4 still report: "DAX enabled. Warning: EXPERIMENTAL, use at your own risk" ...at mount time, and resolving the dax-dma-vs-truncate problem is one of the last hurdles to remove that designation. Acked-by: Alex Williamson Cc: Michal Hocko Cc: kvm@vger.kernel.org Cc: Reported-by: Haozhong Zhang Tested-by: Haozhong Zhang Fixes: d475c6346a38 ("dax,ext2: replace XIP read and write with DAX I/O") Reviewed-by: Christoph Hellwig Signed-off-by: Dan Williams --- drivers/vfio/vfio_iommu_type1.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index e30e29ae4819f6..45657e2b1ff77b 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -338,11 +338,12 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, { struct page *page[1]; struct vm_area_struct *vma; + struct vm_area_struct *vmas[1]; int ret; if (mm == current->mm) { - ret = get_user_pages_fast(vaddr, 1, !!(prot & IOMMU_WRITE), - page); + ret = get_user_pages_longterm(vaddr, 1, !!(prot & IOMMU_WRITE), + page, vmas); } else { unsigned int flags = 0; @@ -351,7 +352,18 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, down_read(&mm->mmap_sem); ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page, - NULL, NULL); + vmas, NULL); + /* + * The lifetime of a vaddr_get_pfn() page pin is + * userspace-controlled. In the fs-dax case this could + * lead to indefinite stalls in filesystem operations. + * Disallow attempts to pin fs-dax pages via this + * interface. + */ + if (ret > 0 && vma_is_fsdax(vmas[0])) { + ret = -EOPNOTSUPP; + put_page(page[0]); + } up_read(&mm->mmap_sem); } From 50186e121ea1adcc43d0f9f790ee45e0b0f1202f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 2 Mar 2018 22:04:59 +0900 Subject: [PATCH 46/48] MAINTAINERS: take over Kconfig maintainership I have recently picked up Kconfig patches to my tree without any declaration. Making it official now. Signed-off-by: Masahiro Yamada Acked-by: Linus Torvalds --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 93a12af4f180b1..b708b6daff7925 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7600,8 +7600,10 @@ F: mm/kasan/ F: scripts/Makefile.kasan KCONFIG +M: Masahiro Yamada +T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kconfig L: linux-kbuild@vger.kernel.org -S: Orphan +S: Maintained F: Documentation/kbuild/kconfig-language.txt F: scripts/kconfig/ From 5fdf8e5ba5666fe153bd61f851a40078a6347822 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 2 Mar 2018 19:31:40 -0800 Subject: [PATCH 47/48] libnvdimm: re-enable deep flush for pmem devices via fsync() Re-enable deep flush so that users always have a way to be sure that a write makes it all the way out to media. Writes from the PMEM driver always arrive at the NVDIMM since movnt is used to bypass the cache, and the driver relies on the ADR (Asynchronous DRAM Refresh) mechanism to flush write buffers on power failure. The Deep Flush mechanism is there to explicitly write buffers to protect against (rare) ADR failure. This change prevents a regression in deep flush behavior so that applications can continue to depend on fsync() as a mechanism to trigger deep flush in the filesystem-DAX case. Fixes: 06e8ccdab15f4 ("acpi: nfit: Add support for detect platform CPU cache...") Reviewed-by: Jeff Moyer Signed-off-by: Dave Jiang Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 10041ac4032c03..06f8dcc52ca648 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -335,8 +335,7 @@ static int pmem_attach_disk(struct device *dev, dev_warn(dev, "unable to guarantee persistence of writes\n"); fua = 0; } - wbc = nvdimm_has_cache(nd_region) && - !test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags); + wbc = nvdimm_has_cache(nd_region); if (!devm_request_mem_region(dev, res->start, resource_size(res), dev_name(&ndns->dev))) { From 949b93250a566cc7a578b4f829cf76b70d19a62c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 6 Feb 2018 19:34:11 -0800 Subject: [PATCH 48/48] memremap: fix softlockup reports at teardown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cond_resched() currently in the setup path needs to be duplicated in the teardown path. Rather than require each instance of for_each_device_pfn() to open code the same sequence, embed it in the helper. Link: https://github.com/intel/ixpdimm_sw/issues/11 Cc: "Jérôme Glisse" Cc: Michal Hocko Cc: Christoph Hellwig Cc: Fixes: 71389703839e ("mm, zone_device: Replace {get, put}_zone_device_page()...") Signed-off-by: Dan Williams --- kernel/memremap.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/kernel/memremap.c b/kernel/memremap.c index 4849be5f9b3c30..4dd4274cabe252 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c @@ -275,8 +275,15 @@ static unsigned long pfn_end(struct dev_pagemap *pgmap) return (res->start + resource_size(res)) >> PAGE_SHIFT; } +static unsigned long pfn_next(unsigned long pfn) +{ + if (pfn % 1024 == 0) + cond_resched(); + return pfn + 1; +} + #define for_each_device_pfn(pfn, map) \ - for (pfn = pfn_first(map); pfn < pfn_end(map); pfn++) + for (pfn = pfn_first(map); pfn < pfn_end(map); pfn = pfn_next(pfn)) static void devm_memremap_pages_release(void *data) { @@ -337,10 +344,10 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) resource_size_t align_start, align_size, align_end; struct vmem_altmap *altmap = pgmap->altmap_valid ? &pgmap->altmap : NULL; + struct resource *res = &pgmap->res; unsigned long pfn, pgoff, order; pgprot_t pgprot = PAGE_KERNEL; - int error, nid, is_ram, i = 0; - struct resource *res = &pgmap->res; + int error, nid, is_ram; align_start = res->start & ~(SECTION_SIZE - 1); align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE) @@ -409,8 +416,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) list_del(&page->lru); page->pgmap = pgmap; percpu_ref_get(pgmap->ref); - if (!(++i % 1024)) - cond_resched(); } devm_add_action(dev, devm_memremap_pages_release, pgmap);