From 15f9f63f4d74c084d32663065e36e57fdc2e47fd Mon Sep 17 00:00:00 2001 From: Chucheng Luo Date: Sat, 14 Mar 2020 12:13:11 +0800 Subject: [PATCH 01/88] fs: Fix missing 'bit' in comment The missing word may make it hard for other developers to understand it. Signed-off-by: Chucheng Luo Acked-by: Hans de Goede Acked-by: Andreas Dilger Signed-off-by: Jiri Kosina --- fs/vboxsf/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c index dd147b490982..4d569f14a8d8 100644 --- a/fs/vboxsf/dir.c +++ b/fs/vboxsf/dir.c @@ -134,7 +134,7 @@ static bool vboxsf_dir_emit(struct file *dir, struct dir_context *ctx) d_type = vboxsf_get_d_type(info->info.attr.mode); /* - * On 32 bit systems pos is 64 signed, while ino is 32 bit + * On 32-bit systems pos is 64-bit signed, while ino is 32-bit * unsigned so fake_ino may overflow, check for this. */ if ((ino_t)(ctx->pos + 1) != (u64)(ctx->pos + 1)) { From 20607434113b8f7d74cfc98e27a4199535c1d4fa Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 30 Mar 2020 17:22:11 -0700 Subject: [PATCH 02/88] lib/bitmap.c: fix spello Fix typo/spello for whitespaces. Signed-off-by: Randy Dunlap Signed-off-by: Jiri Kosina --- lib/bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bitmap.c b/lib/bitmap.c index 89260aa342d6..a801379e9354 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -551,7 +551,7 @@ static inline bool end_of_region(char c) } /* - * The format allows commas and whitespases at the beginning + * The format allows commas and whitespaces at the beginning * of the region. */ static const char *bitmap_find_region(const char *str) From c1a371cf80fbc06280cc0064ca99a39d0428ded3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 13 Apr 2020 09:14:35 -0700 Subject: [PATCH 03/88] printk: fix global comment Fix typo/spello. Signed-off-by: Randy Dunlap Reviewed-by: Sergey Senozhatsky Signed-off-by: Jiri Kosina --- kernel/printk/printk_safe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index b4045e782743..08a8bf778990 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -20,7 +20,7 @@ * is later flushed into the main ring buffer via IRQ work. * * The alternative implementation is chosen transparently - * by examinig current printk() context mask stored in @printk_context + * by examining current printk() context mask stored in @printk_context * per-CPU variable. * * The implementation allows to flush the strings also from another CPU. From 6bfa31756ae905e23050ee10a3b4d3d435122c97 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 22 Jul 2020 09:56:32 +0200 Subject: [PATCH 04/88] HID: cp2112: Use irqchip template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the driver use the irqchip template to assign properties to the gpio_irq_chip instead of using the explicit calls to gpiochip_irqchip_add(). The irqchip is instead added while adding the gpiochip. Cc: Eudean Sun Cc: Benjamin Tissoires Cc: Sébastien Szymanski Signed-off-by: Linus Walleij Signed-off-by: Jiri Kosina --- drivers/hid/hid-cp2112.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index f64517bc33e2..21e15627a461 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c @@ -1235,6 +1235,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) struct cp2112_device *dev; u8 buf[3]; struct cp2112_smbus_config_report config; + struct gpio_irq_chip *girq; int ret; dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); @@ -1338,6 +1339,15 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) dev->gc.can_sleep = 1; dev->gc.parent = &hdev->dev; + girq = &dev->gc.irq; + girq->chip = &cp2112_gpio_irqchip; + /* The event comes from the outside so no parent handler */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + ret = gpiochip_add_data(&dev->gc, dev); if (ret < 0) { hid_err(hdev, "error registering gpio chip\n"); @@ -1353,17 +1363,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) chmod_sysfs_attrs(hdev); hid_hw_power(hdev, PM_HINT_NORMAL); - ret = gpiochip_irqchip_add(&dev->gc, &cp2112_gpio_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); - if (ret) { - dev_err(dev->gc.parent, "failed to add IRQ chip\n"); - goto err_sysfs_remove; - } - return ret; -err_sysfs_remove: - sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group); err_gpiochip_remove: gpiochip_remove(&dev->gc); err_free_i2c: From 4c9454267e019212b466810bc68281fb25424af2 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Mon, 20 Jul 2020 22:53:46 +0200 Subject: [PATCH 05/88] HID: apple: Add support for Matias wireless keyboard The Matias Wireless keyboard has an Apple like layout and identifies as ISO RevB Alu keyboard. Use hid-apple for it so Fn key and media control functions work as expected. Signed-off-by: BALATON Zoltan Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index e82f604d33e9..6b8f0d004d34 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -503,6 +503,8 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), .driver_data = APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), + .driver_data = APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS), .driver_data = APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), From 884ee754f5aedbe54406a4d308a6cc57335747ce Mon Sep 17 00:00:00 2001 From: Miroslav Benes Date: Thu, 27 Aug 2020 13:07:09 +0200 Subject: [PATCH 06/88] selftests/livepatch: Do not check order when using "comm" for dmesg checking check_result() uses "comm" to check expected results of selftests output in dmesg. Everything works fine if timestamps in dmesg are unique. If not, like in this example [ 86.844422] test_klp_callbacks_demo: pre_unpatch_callback: test_klp_callbacks_mod -> [MODULE_STATE_LIVE] Normal state [ 86.844422] livepatch: 'test_klp_callbacks_demo': starting unpatching transition , "comm" fails with "comm: file 2 is not in sorted order". Suppress the order checking with --nocheck-order option. Fixes: 2f3f651f3756 ("selftests/livepatch: Use "comm" instead of "diff" for dmesg") Signed-off-by: Miroslav Benes Acked-by: Joe Lawrence Signed-off-by: Jiri Kosina --- tools/testing/selftests/livepatch/functions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh index 1aba83c87ad3..846c7ed71556 100644 --- a/tools/testing/selftests/livepatch/functions.sh +++ b/tools/testing/selftests/livepatch/functions.sh @@ -278,7 +278,7 @@ function check_result { # help differentiate repeated testing runs. Remove them with a # post-comparison sed filter. - result=$(dmesg | comm -13 "$SAVED_DMESG" - | \ + result=$(dmesg | comm --nocheck-order -13 "$SAVED_DMESG" - | \ grep -e 'livepatch:' -e 'test_klp' | \ grep -v '\(tainting\|taints\) kernel' | \ sed 's/^\[[ 0-9.]*\] //') From 25094ede57d4c5b7ad6474b0b4490f12d21b3702 Mon Sep 17 00:00:00 2001 From: Wang Hai Date: Wed, 19 Aug 2020 10:54:34 +0800 Subject: [PATCH 07/88] ext2: remove duplicate include Remove linux/fiemap.h which is included more than once Link: https://lore.kernel.org/r/20200819025434.65763-1-wanghai38@huawei.com Reported-by: Hulk Robot Reviewed-by: Ritesh Harjani Signed-off-by: Wang Hai Signed-off-by: Jan Kara --- fs/ext2/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 415c21f0e750..11c5c6fe75bb 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "ext2.h" #include "acl.h" #include "xattr.h" From 256ccb9baeaba2b1a4ed5324c02b8d723497ca5a Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Fri, 28 Aug 2020 01:16:52 +0300 Subject: [PATCH 08/88] udf: Use kvzalloc() in udf_sb_alloc_bitmap() Use kvzalloc() in udf_sb_alloc_bitmap() instead of open-coding it. Size computation wrapped in struct_size() macro to prevent potential integer overflows. Link: https://lore.kernel.org/r/20200827221652.64660-1-efremov@linux.com Signed-off-by: Denis Efremov Reviewed-by: Gustavo A. R. Silva Signed-off-by: Jan Kara --- fs/udf/super.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 1c42f544096d..d9eabbe368ff 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1006,18 +1006,10 @@ int udf_compute_nr_groups(struct super_block *sb, u32 partition) static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) { struct udf_bitmap *bitmap; - int nr_groups; - int size; - - nr_groups = udf_compute_nr_groups(sb, index); - size = sizeof(struct udf_bitmap) + - (sizeof(struct buffer_head *) * nr_groups); - - if (size <= PAGE_SIZE) - bitmap = kzalloc(size, GFP_KERNEL); - else - bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ + int nr_groups = udf_compute_nr_groups(sb, index); + bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups), + GFP_KERNEL); if (!bitmap) return NULL; From e9d4709fcc26353df12070566970f080e651f0c9 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 4 Mar 2020 14:01:44 +0100 Subject: [PATCH 09/88] reiserfs: Fix memory leak in reiserfs_parse_options() When a usrjquota or grpjquota mount option is used multiple times, we will leak memory allocated for the file name. Make sure the last setting is used and all the previous ones are properly freed. Reported-by: syzbot+c9e294bbe0333a6b7640@syzkaller.appspotmail.com Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index a6bce5b1fb1d..1b9c7a387dc7 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1258,6 +1258,10 @@ static int reiserfs_parse_options(struct super_block *s, "turned on."); return 0; } + if (qf_names[qtype] != + REISERFS_SB(s)->s_qf_names[qtype]) + kfree(qf_names[qtype]); + qf_names[qtype] = NULL; if (*arg) { /* Some filename specified? */ if (REISERFS_SB(s)->s_qf_names[qtype] && strcmp(REISERFS_SB(s)->s_qf_names[qtype], @@ -1287,10 +1291,6 @@ static int reiserfs_parse_options(struct super_block *s, else *mount_options |= 1 << REISERFS_GRPQUOTA; } else { - if (qf_names[qtype] != - REISERFS_SB(s)->s_qf_names[qtype]) - kfree(qf_names[qtype]); - qf_names[qtype] = NULL; if (qtype == USRQUOTA) *mount_options &= ~(1 << REISERFS_USRQUOTA); else From 75fa677260be6acf326afc5c466c211b07aee92f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 Aug 2020 17:09:46 +0200 Subject: [PATCH 10/88] selftests: use "$(MAKE)" instead of "make" for headers_install If top make invocation uses -j4 or larger, this patch reduces "make headers_install" subtask run time from 30 to 7 seconds. CC: Shuah Khan CC: Shuah Khan CC: linux-kselftest@vger.kernel.org CC: linux-kernel@vger.kernel.org Signed-off-by: Denys Vlasenko Signed-off-by: Shuah Khan --- tools/testing/selftests/lib.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 7a17ea815736..51124b962d56 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -47,9 +47,9 @@ ARCH ?= $(SUBARCH) khdr: ifndef KSFT_KHDR_INSTALL_DONE ifeq (1,$(DEFAULT_INSTALL_HDR_PATH)) - make --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install + $(MAKE) --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install else - make --no-builtin-rules INSTALL_HDR_PATH=$$OUTPUT/usr \ + $(MAKE) --no-builtin-rules INSTALL_HDR_PATH=$$OUTPUT/usr \ ARCH=$(ARCH) -C $(top_srcdir) headers_install endif endif From f69237e1e954b469175de4af8487c303d36c5467 Mon Sep 17 00:00:00 2001 From: Greg Thelen Date: Tue, 28 Jul 2020 00:32:41 -0700 Subject: [PATCH 11/88] selftests: more general make nesting support selftests can be built from the toplevel kernel makefile (e.g. make kselftest-all) or directly (make -C tools/testing/selftests all). The toplevel kernel makefile explicitly disables implicit rules with "MAKEFLAGS += -rR", which is passed to tools/testing/selftests. Some selftest makefiles require implicit make rules, which is why commit 67d8712dcc70 ("selftests: Fix build failures when invoked from kselftest target") reenables implicit rules by clearing MAKEFLAGS if MAKELEVEL=1. So far so good. However, if the toplevel makefile is called from an outer makefile then MAKELEVEL will be elevated, which breaks the MAKELEVEL equality test. Example wrapped makefile error: $ cat ~/Makefile all: $(MAKE) defconfig $(MAKE) kselftest-all $ make -sf ~/Makefile futex_wait_timeout.c /src/tools/testing/selftests/kselftest_harness.h /src/tools/testing/selftests/kselftest.h ../include/futextest.h ../include/atomic.h ../include/logging.h -lpthread -lrt -o /src/tools/testing/selftests/futex/functional/futex_wait_timeout make[4]: futex_wait_timeout.c: Command not found Rather than checking $(MAKELEVEL), check for $(LINK.c), which is a more direct side effect of "make -R". This enables arbitrary makefile nesting. Signed-off-by: Greg Thelen Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 9018f45d631d..15c1c1359c50 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -88,10 +88,10 @@ endif # of the targets gets built. FORCE_TARGETS ?= -# Clear LDFLAGS and MAKEFLAGS if called from main -# Makefile to avoid test build failures when test -# Makefile doesn't have explicit build rules. -ifeq (1,$(MAKELEVEL)) +# Clear LDFLAGS and MAKEFLAGS when implicit rules are missing. This provides +# implicit rules to sub-test Makefiles which avoids build failures in test +# Makefile that don't have explicit build rules. +ifeq (,$(LINK.c)) override LDFLAGS = override MAKEFLAGS = endif From 5578d008d9e06bb531fb3e62dd17096d9fd9c853 Mon Sep 17 00:00:00 2001 From: Brendan Higgins Date: Tue, 11 Aug 2020 14:27:55 -0700 Subject: [PATCH 12/88] kunit: tool: fix running kunit_tool from outside kernel tree Currently kunit_tool does not work correctly when executed from a path outside of the kernel tree, so make sure that the current working directory is correct and the kunit_dir is properly initialized before running. Signed-off-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 425ef40067e7..e2caf4e24ecb 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -237,9 +237,13 @@ def main(argv, linux=None): cli_args = parser.parse_args(argv) + if get_kernel_root_path(): + os.chdir(get_kernel_root_path()) + if cli_args.subcommand == 'run': if not os.path.exists(cli_args.build_dir): os.mkdir(cli_args.build_dir) + create_default_kunitconfig() if not linux: linux = kunit_kernel.LinuxSourceTree() @@ -257,6 +261,7 @@ def main(argv, linux=None): if cli_args.build_dir: if not os.path.exists(cli_args.build_dir): os.mkdir(cli_args.build_dir) + create_default_kunitconfig() if not linux: linux = kunit_kernel.LinuxSourceTree() @@ -270,10 +275,6 @@ def main(argv, linux=None): if result.status != KunitStatus.SUCCESS: sys.exit(1) elif cli_args.subcommand == 'build': - if cli_args.build_dir: - if not os.path.exists(cli_args.build_dir): - os.mkdir(cli_args.build_dir) - if not linux: linux = kunit_kernel.LinuxSourceTree() @@ -288,10 +289,6 @@ def main(argv, linux=None): if result.status != KunitStatus.SUCCESS: sys.exit(1) elif cli_args.subcommand == 'exec': - if cli_args.build_dir: - if not os.path.exists(cli_args.build_dir): - os.mkdir(cli_args.build_dir) - if not linux: linux = kunit_kernel.LinuxSourceTree() From 21a6d1780d5bbfca0ce9b8104ca6233502fcbf86 Mon Sep 17 00:00:00 2001 From: Heidi Fahim Date: Tue, 11 Aug 2020 14:27:56 -0700 Subject: [PATCH 13/88] kunit: tool: allow generating test results in JSON Add a --json flag, which when specified generates JSON formatted test results conforming to the KernelCI API test_group spec[1]. The user can use the new flag to specify a filename to print the json formatted results to. Link[1]: https://api.kernelci.org/schema-test-group.html#post Signed-off-by: Heidi Fahim Signed-off-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 35 +++++++++++--- tools/testing/kunit/kunit_json.py | 63 ++++++++++++++++++++++++++ tools/testing/kunit/kunit_tool_test.py | 33 ++++++++++++++ 3 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 tools/testing/kunit/kunit_json.py diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index e2caf4e24ecb..3c95a0eb0d04 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -17,6 +17,7 @@ from collections import namedtuple from enum import Enum, auto import kunit_config +import kunit_json import kunit_kernel import kunit_parser @@ -30,9 +31,9 @@ KunitBuildRequest = namedtuple('KunitBuildRequest', KunitExecRequest = namedtuple('KunitExecRequest', ['timeout', 'build_dir', 'alltests']) KunitParseRequest = namedtuple('KunitParseRequest', - ['raw_output', 'input_data']) + ['raw_output', 'input_data', 'build_dir', 'json']) KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs', - 'build_dir', 'alltests', + 'build_dir', 'alltests', 'json', 'make_options']) KernelDirectoryPath = sys.argv[0].split('tools/testing/kunit/')[0] @@ -113,12 +114,22 @@ def parse_tests(request: KunitParseRequest) -> KunitResult: test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS, [], 'Tests not Parsed.') + if request.raw_output: kunit_parser.raw_output(request.input_data) else: test_result = kunit_parser.parse_run_tests(request.input_data) parse_end = time.time() + if request.json: + json_obj = kunit_json.get_json_result( + test_result=test_result, + def_config='kunit_defconfig', + build_dir=request.build_dir, + json_path=request.json) + if request.json == 'stdout': + print(json_obj) + if test_result.status != kunit_parser.TestStatus.SUCCESS: return KunitResult(KunitStatus.TEST_FAILURE, test_result, parse_end - parse_start) @@ -151,7 +162,9 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree, return exec_result parse_request = KunitParseRequest(request.raw_output, - exec_result.result) + exec_result.result, + request.build_dir, + request.json) parse_result = parse_tests(parse_request) run_end = time.time() @@ -195,7 +208,12 @@ def add_exec_opts(parser): def add_parse_opts(parser): parser.add_argument('--raw_output', help='don\'t format output from kernel', action='store_true') - + parser.add_argument('--json', + nargs='?', + help='Stores test results in a JSON, and either ' + 'prints to stdout or saves to file if a ' + 'filename is specified', + type=str, const='stdout', default=None) def main(argv, linux=None): parser = argparse.ArgumentParser( @@ -253,6 +271,7 @@ def main(argv, linux=None): cli_args.jobs, cli_args.build_dir, cli_args.alltests, + cli_args.json, cli_args.make_options) result = run_tests(linux, request) if result.status != KunitStatus.SUCCESS: @@ -297,7 +316,9 @@ def main(argv, linux=None): cli_args.alltests) exec_result = exec_tests(linux, exec_request) parse_request = KunitParseRequest(cli_args.raw_output, - exec_result.result) + exec_result.result, + cli_args.build_dir, + cli_args.json) result = parse_tests(parse_request) kunit_parser.print_with_timestamp(( 'Elapsed time: %.3fs\n') % ( @@ -311,7 +332,9 @@ def main(argv, linux=None): with open(cli_args.file, 'r') as f: kunit_output = f.read().splitlines() request = KunitParseRequest(cli_args.raw_output, - kunit_output) + kunit_output, + cli_args.build_dir, + cli_args.json) result = parse_tests(request) if result.status != KunitStatus.SUCCESS: sys.exit(1) diff --git a/tools/testing/kunit/kunit_json.py b/tools/testing/kunit/kunit_json.py new file mode 100644 index 000000000000..624b31b2dbd6 --- /dev/null +++ b/tools/testing/kunit/kunit_json.py @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Generates JSON from KUnit results according to +# KernelCI spec: https://github.com/kernelci/kernelci-doc/wiki/Test-API +# +# Copyright (C) 2020, Google LLC. +# Author: Heidi Fahim + +import json +import os + +import kunit_parser + +from kunit_parser import TestStatus + +def get_json_result(test_result, def_config, build_dir, json_path): + sub_groups = [] + + # Each test suite is mapped to a KernelCI sub_group + for test_suite in test_result.suites: + sub_group = { + "name": test_suite.name, + "arch": "UM", + "defconfig": def_config, + "build_environment": build_dir, + "test_cases": [], + "lab_name": None, + "kernel": None, + "job": None, + "git_branch": "kselftest", + } + test_cases = [] + # TODO: Add attachments attribute in test_case with detailed + # failure message, see https://api.kernelci.org/schema-test-case.html#get + for case in test_suite.cases: + test_case = {"name": case.name, "status": "FAIL"} + if case.status == TestStatus.SUCCESS: + test_case["status"] = "PASS" + elif case.status == TestStatus.TEST_CRASHED: + test_case["status"] = "ERROR" + test_cases.append(test_case) + sub_group["test_cases"] = test_cases + sub_groups.append(sub_group) + test_group = { + "name": "KUnit Test Group", + "arch": "UM", + "defconfig": def_config, + "build_environment": build_dir, + "sub_groups": sub_groups, + "lab_name": None, + "kernel": None, + "job": None, + "git_branch": "kselftest", + } + json_obj = json.dumps(test_group, indent=4) + if json_path != 'stdout': + with open(json_path, 'w') as result_path: + result_path.write(json_obj) + root = __file__.split('tools/testing/kunit/')[0] + kunit_parser.print_with_timestamp( + "Test results stored in %s" % + os.path.join(root, result_path.name)) + return json_obj diff --git a/tools/testing/kunit/kunit_tool_test.py b/tools/testing/kunit/kunit_tool_test.py index 287c74d821c3..99c3c5671ea4 100755 --- a/tools/testing/kunit/kunit_tool_test.py +++ b/tools/testing/kunit/kunit_tool_test.py @@ -11,11 +11,13 @@ from unittest import mock import tempfile, shutil # Handling test_tmpdir +import json import os import kunit_config import kunit_parser import kunit_kernel +import kunit_json import kunit test_tmpdir = '' @@ -230,6 +232,37 @@ class KUnitParserTest(unittest.TestCase): result = kunit_parser.parse_run_tests(file.readlines()) self.assertEqual('kunit-resource-test', result.suites[0].name) +class KUnitJsonTest(unittest.TestCase): + + def _json_for(self, log_file): + with(open(get_absolute_path(log_file))) as file: + test_result = kunit_parser.parse_run_tests(file) + json_obj = kunit_json.get_json_result( + test_result=test_result, + def_config='kunit_defconfig', + build_dir=None, + json_path='stdout') + return json.loads(json_obj) + + def test_failed_test_json(self): + result = self._json_for( + 'test_data/test_is_test_passed-failure.log') + self.assertEqual( + {'name': 'example_simple_test', 'status': 'FAIL'}, + result["sub_groups"][1]["test_cases"][0]) + + def test_crashed_test_json(self): + result = self._json_for( + 'test_data/test_is_test_passed-crash.log') + self.assertEqual( + {'name': 'example_simple_test', 'status': 'ERROR'}, + result["sub_groups"][1]["test_cases"][0]) + + def test_no_tests_json(self): + result = self._json_for( + 'test_data/test_is_test_passed-no_tests_run.log') + self.assertEqual(0, len(result['sub_groups'])) + class StrContains(str): def __eq__(self, other): return self in other From f53fa968a7344970b8f8a5707c39cdcf17a6f367 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 5 May 2020 15:42:35 +0200 Subject: [PATCH 14/88] scif: Fix spelling of EACCES As per POSIX, the correct spelling is EACCES: include/uapi/asm-generic/errno-base.h:#define EACCES 13 /* Permission denied */ Signed-off-by: Geert Uytterhoeven Signed-off-by: Jiri Kosina --- include/linux/scif.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/scif.h b/include/linux/scif.h index eeb250b73c4b..329e695b8fe5 100644 --- a/include/linux/scif.h +++ b/include/linux/scif.h @@ -657,7 +657,7 @@ int scif_unregister(scif_epd_t epd, off_t offset, size_t len); * the negative of one of the following errors is returned. * * Errors: - * EACCESS - Attempt to write to a read-only range + * EACCES - Attempt to write to a read-only range * EBADF, ENOTTY - epd is not a valid endpoint descriptor * ECONNRESET - Connection reset by peer * EINVAL - rma_flags is invalid @@ -733,7 +733,7 @@ int scif_readfrom(scif_epd_t epd, off_t loffset, size_t len, off_t * the negative of one of the following errors is returned. * * Errors: - * EACCESS - Attempt to write to a read-only range + * EACCES - Attempt to write to a read-only range * EBADF, ENOTTY - epd is not a valid endpoint descriptor * ECONNRESET - Connection reset by peer * EINVAL - rma_flags is invalid @@ -815,7 +815,7 @@ int scif_writeto(scif_epd_t epd, off_t loffset, size_t len, off_t * the negative of one of the following errors is returned. * * Errors: - * EACCESS - Attempt to write to a read-only range + * EACCES - Attempt to write to a read-only range * EBADF, ENOTTY - epd is not a valid endpoint descriptor * ECONNRESET - Connection reset by peer * EINVAL - rma_flags is invalid @@ -895,7 +895,7 @@ int scif_vreadfrom(scif_epd_t epd, void *addr, size_t len, off_t roffset, * the negative of one of the following errors is returned. * * Errors: - * EACCESS - Attempt to write to a read-only range + * EACCES - Attempt to write to a read-only range * EBADF, ENOTTY - epd is not a valid endpoint descriptor * ECONNRESET - Connection reset by peer * EINVAL - rma_flags is invalid From 2f078a0fe08d2f8a4fd030367663f808b6e21b34 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 6 May 2020 07:34:31 +0200 Subject: [PATCH 15/88] MAINTAINERS: rectify MMP SUPPORT after moving cputype.h Commit 32adcaa010fa ("ARM: mmp: move cputype.h to include/linux/soc/") added a file entry that does not point to the intended file location. Since then, ./scripts/get_maintainer.pl --self-test complains: warning: no file matches F: linux/soc/mmp/ Rectify the MAINTAINERS entry now. Fixes: 32adcaa010fa ("ARM: mmp: move cputype.h to include/linux/soc/") Signed-off-by: Lukas Bulwahn Signed-off-by: Jiri Kosina --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 7119165796c7..ee7d2111c951 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11638,7 +11638,7 @@ S: Odd Fixes T: git git://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/linux-mmp.git F: arch/arm/boot/dts/mmp* F: arch/arm/mach-mmp/ -F: linux/soc/mmp/ +F: include/linux/soc/mmp/ MMP USB PHY DRIVERS R: Lubomir Rintel From 36c6aa26e9ca393b31af166965cf51536176703b Mon Sep 17 00:00:00 2001 From: Shaokun Zhang Date: Sat, 9 May 2020 16:33:55 +0800 Subject: [PATCH 16/88] bootconfig: Fix kernel message mentioning CONFIG_BOOT_CONFIG Fix up one typo: CONFIG_BOOTCONFIG -> CONFIG_BOOT_CONFIG Cc: Steven Rostedt Cc: Masami Hiramatsu Signed-off-by: Shaokun Zhang Acked-by: Masami Hiramatsu Signed-off-by: Jiri Kosina --- init/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/main.c b/init/main.c index ae78fb68d231..92773a5daf8d 100644 --- a/init/main.c +++ b/init/main.c @@ -467,7 +467,7 @@ static void __init setup_boot_config(const char *cmdline) static int __init warn_bootconfig(char *str) { - pr_warn("WARNING: 'bootconfig' found on the kernel command line but CONFIG_BOOTCONFIG is not set.\n"); + pr_warn("WARNING: 'bootconfig' found on the kernel command line but CONFIG_BOOT_CONFIG is not set.\n"); return 0; } early_param("bootconfig", warn_bootconfig); From 53ed4cf6519def01ea49af7609ee585a7b2d38c3 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Tue, 26 May 2020 11:02:01 +1200 Subject: [PATCH 17/88] HID: logitech-dj: Fix spelling in comment Change 'unhandeled' to 'unhandled'. Signed-off-by: Chris Packham Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 38ee25a813b9..72fb6e54a50a 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -820,7 +820,7 @@ static void logi_dj_recv_queue_unknown_work(struct dj_receiver_dev *djrcv_dev) { struct dj_workitem workitem = { .type = WORKITEM_TYPE_UNKNOWN }; - /* Rate limit queries done because of unhandeled reports to 2/sec */ + /* Rate limit queries done because of unhandled reports to 2/sec */ if (time_before(jiffies, djrcv_dev->last_query + HZ / 2)) return; From b784a88e523a7c1912fc75486ce8c029ee6fe523 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Wed, 3 Jun 2020 13:32:34 +0100 Subject: [PATCH 18/88] perf: Fix opt help text for --no-bpf-event The opt name was once inverted but the help text didn't reflect the change. Fixes: 71184c6ab7e6 ("perf record: Replace option --bpf-event with --no-bpf-event") Signed-off-by: Fam Zheng Signed-off-by: Jiri Kosina --- tools/perf/builtin-record.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f91352f847c0..772f1057647f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2452,7 +2452,7 @@ static struct option __record_options[] = { OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize, "synthesize non-sample events at the end of output"), OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"), - OPT_BOOLEAN(0, "no-bpf-event", &record.opts.no_bpf_event, "record bpf events"), + OPT_BOOLEAN(0, "no-bpf-event", &record.opts.no_bpf_event, "do not record bpf events"), OPT_BOOLEAN(0, "strict-freq", &record.opts.strict_freq, "Fail if the specified frequency can't be used"), OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'", From cae1d5a2c5a491141faa747e9944ba40ab4ab786 Mon Sep 17 00:00:00 2001 From: Anatoly Pugachev Date: Tue, 16 Jun 2020 15:26:18 +0300 Subject: [PATCH 19/88] selftests: vm: add fragment CONFIG_GUP_BENCHMARK When running gup_benchmark test the following output states that the config options is missing. $ sudo ./gup_benchmark open: No such file or directory $ sudo strace -e trace=file ./gup_benchmark 2>&1 | tail -3 openat(AT_FDCWD, "/sys/kernel/debug/gup_benchmark", O_RDWR) = -1 ENOENT (No such file or directory) open: No such file or directory +++ exited with 1 +++ Fix it by adding config option fragment. Fixes: 64c349f4ae78 ("mm: add infrastructure for get_user_pages_fast() benchmarking") Signed-off-by: Anatoly Pugachev CC: Jiri Kosina CC: Shuah Khan Signed-off-by: Jiri Kosina --- tools/testing/selftests/vm/config | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/vm/config b/tools/testing/selftests/vm/config index 3ba674b64fa9..69dd0d1aa30b 100644 --- a/tools/testing/selftests/vm/config +++ b/tools/testing/selftests/vm/config @@ -3,3 +3,4 @@ CONFIG_USERFAULTFD=y CONFIG_TEST_VMALLOC=m CONFIG_DEVICE_PRIVATE=y CONFIG_TEST_HMM=m +CONFIG_GUP_BENCHMARK=y From 552a028f6d3a7f2755048dd30dd7b15fcda2b958 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 24 Jul 2020 10:38:25 +0200 Subject: [PATCH 20/88] mtd: rawnand: oxnas: cleanup/simplify code Simplify oxnas_nand_probe. Signed-off-by: Pavel Machek (CIP) Acked-by: Neil Armstrong Signed-off-by: Jiri Kosina --- drivers/mtd/nand/raw/oxnas_nand.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/oxnas_nand.c b/drivers/mtd/nand/raw/oxnas_nand.c index 8d0d76ad319d..f44947043e5a 100644 --- a/drivers/mtd/nand/raw/oxnas_nand.c +++ b/drivers/mtd/nand/raw/oxnas_nand.c @@ -144,8 +144,7 @@ static int oxnas_nand_probe(struct platform_device *pdev) if (err) goto err_cleanup_nand; - oxnas->chips[oxnas->nchips] = chip; - ++oxnas->nchips; + oxnas->chips[oxnas->nchips++] = chip; } /* Exit if no chips found */ From 4fcadb39c6b298e105d827741e0b7a6b146633e5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 5 Aug 2020 11:14:38 -0700 Subject: [PATCH 21/88] spelling.txt: Remove some duplicate entries Found when Colin King fixed a typo for falied/failed and a git grep showed 2 entries in this file. Signed-off-by: Joe Perches Acked-by: Colin Ian King Signed-off-by: Jiri Kosina --- scripts/spelling.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/spelling.txt b/scripts/spelling.txt index f253681e7e2a..b703e4fd51e8 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -596,7 +596,6 @@ extenstion||extension extracter||extractor faied||failed faield||failed -falied||failed faild||failed failded||failed failer||failure @@ -793,7 +792,6 @@ interrup||interrupt interrups||interrupts interruptted||interrupted interupted||interrupted -interupt||interrupt intial||initial intialisation||initialisation intialised||initialised @@ -968,7 +966,6 @@ occurd||occurred occured||occurred occurence||occurrence occure||occurred -occured||occurred occuring||occurring offser||offset offet||offset @@ -1437,7 +1434,6 @@ udpate||update uesd||used uknown||unknown usccess||success -usupported||unsupported uncommited||uncommitted uncompatible||incompatible unconditionaly||unconditionally From 2a9b29b289833e42e13fdfb7e082499c1464f25c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 29 Aug 2020 22:57:51 -0700 Subject: [PATCH 22/88] xtensa: fix Kconfig typo Correct trivial typo (ful -> full). Fixes: 76743c0e0915 ("xtensa: move kernel memory layout to platform options") Signed-off-by: Randy Dunlap Cc: Chris Zankel Cc: Max Filippov Cc: linux-xtensa@linux-xtensa.org Acked-by: Max Filippov Signed-off-by: Jiri Kosina --- arch/xtensa/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index e997e0119c02..5da1ba7a9949 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -537,7 +537,7 @@ config MEMMAP_CACHEATTR 2: cache bypass, 4: WB cached, f: illegal. - For ful MMU: + For full MMU: bit 0: executable, bit 1: writable, bits 2..3: From aeeba45a9df34a00113f96f9f52c45e250ff7b7d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 4 Sep 2020 14:21:42 +0100 Subject: [PATCH 23/88] HID: wiimote: make handlers[] const The `handlers[]` array contents are never modified, so use the `const` qualifier. Signed-off-by: Ian Abbott Reviewed-by: David Rheinsberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index e484c3618dec..e03a0ba5611a 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c @@ -1586,7 +1586,7 @@ struct wiiproto_handler { void (*func)(struct wiimote_data *wdata, const __u8 *payload); }; -static struct wiiproto_handler handlers[] = { +static const struct wiiproto_handler handlers[] = { { .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status }, { .id = WIIPROTO_REQ_STATUS, .size = 2, .func = handler_status_K }, { .id = WIIPROTO_REQ_DATA, .size = 21, .func = handler_data }, @@ -1618,7 +1618,7 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, u8 *raw_data, int size) { struct wiimote_data *wdata = hid_get_drvdata(hdev); - struct wiiproto_handler *h; + const struct wiiproto_handler *h; int i; unsigned long flags; From 5eae59cc876c8c1043d3eb55a2e965bb36e90bba Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 4 Sep 2020 14:21:43 +0100 Subject: [PATCH 24/88] HID: wiimote: narrow spinlock range in wiimote_hid_event() In `wiimote_hid_event()`, the `wdata->state.lock` spinlock does not need to be held while searching `handlers[]` for a suitable handler function. Change it so the spinlock is only held during the call to the handler function itself. Signed-off-by: Ian Abbott Reviewed-by: David Rheinsberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index e03a0ba5611a..41012681cafd 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c @@ -1625,12 +1625,12 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, if (size < 1) return -EINVAL; - spin_lock_irqsave(&wdata->state.lock, flags); - for (i = 0; handlers[i].id; ++i) { h = &handlers[i]; if (h->id == raw_data[0] && h->size < size) { + spin_lock_irqsave(&wdata->state.lock, flags); h->func(wdata, &raw_data[1]); + spin_unlock_irqrestore(&wdata->state.lock, flags); break; } } @@ -1639,8 +1639,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, hid_warn(hdev, "Unhandled report %hhu size %d\n", raw_data[0], size); - spin_unlock_irqrestore(&wdata->state.lock, flags); - return 0; } From d4f98dbfe717490e771b6e701904bfcf4b4557f0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 24 Aug 2020 11:57:35 +0300 Subject: [PATCH 25/88] HID: roccat: add bounds checking in kone_sysfs_write_settings() This code doesn't check if "settings->startup_profile" is within bounds and that could result in an out of bounds array access. What the code does do is it checks if the settings can be written to the firmware, so it's possible that the firmware has a bounds check? It's safer and easier to verify when the bounds checking is done in the kernel. Fixes: 14bf62cde794 ("HID: add driver for Roccat Kone gaming mouse") Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 1a6e600197d0..509b9bb1362c 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -294,31 +294,40 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0, difference, old_profile; + struct kone_settings *settings = (struct kone_settings *)buf; /* I need to get my data in one piece */ if (off != 0 || count != sizeof(struct kone_settings)) return -EINVAL; mutex_lock(&kone->kone_lock); - difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings)); + difference = memcmp(settings, &kone->settings, + sizeof(struct kone_settings)); if (difference) { - retval = kone_set_settings(usb_dev, - (struct kone_settings const *)buf); - if (retval) { - mutex_unlock(&kone->kone_lock); - return retval; + if (settings->startup_profile < 1 || + settings->startup_profile > 5) { + retval = -EINVAL; + goto unlock; } + retval = kone_set_settings(usb_dev, settings); + if (retval) + goto unlock; + old_profile = kone->settings.startup_profile; - memcpy(&kone->settings, buf, sizeof(struct kone_settings)); + memcpy(&kone->settings, settings, sizeof(struct kone_settings)); kone_profile_activated(kone, kone->settings.startup_profile); if (kone->settings.startup_profile != old_profile) kone_profile_report(kone, kone->settings.startup_profile); } +unlock: mutex_unlock(&kone->kone_lock); + if (retval) + return retval; + return sizeof(struct kone_settings); } static BIN_ATTR(settings, 0660, kone_sysfs_read_settings, From 5bf2f2f331ad812c9b7eea6e14a3ea328acbffc0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 1 Sep 2020 09:56:42 +0200 Subject: [PATCH 26/88] HID: ite: Add USB id match for Acer One S1003 keyboard dock The Acer One S1003 2-in-1 keyboard dock uses a Synaptics S910xx touchpad which is connected to an ITE 8910 USB keyboard controller chip. This keyboard has the same quirk for its rfkill / airplane mode hotkey as other keyboards with ITE keyboard chips, it only sends a single release event when pressed and released, it never sends a press event. This commit adds this keyboards USB id to the hid-ite id-table, fixing the rfkill key not working on this keyboard. Note that like for the Acer Aspire Switch 10 (SW5-012) the id-table entry matches on the HID_GROUP_GENERIC generic group so that hid-ite only binds to the keyboard interface and the mouse/touchpad interface is left untouched so that hid-multitouch can bind to it. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-ite.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 74fc1df6e3c2..ac89388d758f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1123,6 +1123,7 @@ #define USB_DEVICE_ID_SYNAPTICS_DELL_K12A 0x2819 #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968 #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 +#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003 0x73f5 #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 #define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047 diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c index 6c55682c5974..044a93f3c117 100644 --- a/drivers/hid/hid-ite.c +++ b/drivers/hid/hid-ite.c @@ -44,6 +44,10 @@ static const struct hid_device_id ite_devices[] = { { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, + /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_SYNAPTICS, + USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003) }, { } }; MODULE_DEVICE_TABLE(hid, ite_devices); From eafb2203626aedb599cc80aadcba533c917b53b0 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 2 Sep 2020 21:43:02 -0700 Subject: [PATCH 27/88] HID: i2c-hid: Prefer asynchronous probe Adding printouts to the i2c_hid_probe() function shows that it takes quite some time. It used to take about 70 ms, but after commit eef4016243e9 ("HID: i2c-hid: Always sleep 60ms after I2C_HID_PWR_ON commands") it takes about 190 ms. This is not tons of time but it's not trivial. Because we haven't yet specified that we'd prefer asynchronous probe for this driver then, if the driver is builtin to the kernel, we'll wait for this driver to finish before we start probes for more drivers. Let's set the flag to enable asynchronous for this driver so that other drivers aren't blocked from probing until we finish. Since this driver can be configured as a module and modules are always asynchronously probed this is quite a safe change and will benefit anyone who has a reason to build this driver into the kernel instead of using it as a module. [jkosina@suse.cz: drop spurious whitespace addition] Signed-off-by: Douglas Anderson Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index dbd04492825d..d053b86d0e2e 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -1268,6 +1268,7 @@ static struct i2c_driver i2c_hid_driver = { .driver = { .name = "i2c_hid", .pm = &i2c_hid_pm, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match), .of_match_table = of_match_ptr(i2c_hid_of_match), }, From c27e08820bc6cb7d483a8d87589bdbbbf10f2306 Mon Sep 17 00:00:00 2001 From: Laurent Gauthier Date: Wed, 9 Sep 2020 00:11:49 +0200 Subject: [PATCH 28/88] HID: hid-debug: fix nonblocking read semantics wrt EIO/ERESTARTSYS When the file has been open in non-blocking mode, EIO or ERESTARTSYS would never be returned even if they should (for example when device has been unplugged, you want EIO and not EAGAIN to be returned). Move the O_NONBLOCK check after other checks have been performed. Based on similar to patches hidraw and hiddev by Founder Fang and Jiri Kosina . Signed-off-by: Laurent Gauthier Signed-off-by: Jiri Kosina --- drivers/hid/hid-debug.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 9453147d020d..d7eaf9100370 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -1101,11 +1101,6 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer, set_current_state(TASK_INTERRUPTIBLE); while (kfifo_is_empty(&list->hid_debug_fifo)) { - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { ret = -ERESTARTSYS; break; @@ -1122,6 +1117,11 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer, goto out; } + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + break; + } + /* allow O_NONBLOCK from other threads */ mutex_unlock(&list->read_mutex); schedule(); From ad47ff330b26a9fefa882032be2122700e1625ab Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 9 Sep 2020 09:34:13 -0700 Subject: [PATCH 29/88] quota: widen timestamps for the fs_disk_quota structure Soon, XFS will support quota grace period expiration timestamps beyond the year 2038, widen the timestamp fields to handle the extra time bits. Internally, XFS now stores unsigned 34-bit quantities, so the extra 8 bits here should work fine. (Note that XFS is the only user of this structure.) Link: https://lore.kernel.org/r/20200909163413.GJ7955@magnolia Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/quota/quota.c | 42 +++++++++++++++++++++++++++++----- include/uapi/linux/dqblk_xfs.h | 11 ++++++++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 47f9e151988b..52362eeaea94 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -481,6 +481,14 @@ static inline u64 quota_btobb(u64 bytes) return (bytes + (1 << XFS_BB_SHIFT) - 1) >> XFS_BB_SHIFT; } +static inline s64 copy_from_xfs_dqblk_ts(const struct fs_disk_quota *d, + __s32 timer, __s8 timer_hi) +{ + if (d->d_fieldmask & FS_DQ_BIGTIME) + return (u32)timer | (s64)timer_hi << 32; + return timer; +} + static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) { dst->d_spc_hardlimit = quota_bbtob(src->d_blk_hardlimit); @@ -489,14 +497,17 @@ static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) dst->d_ino_softlimit = src->d_ino_softlimit; dst->d_space = quota_bbtob(src->d_bcount); dst->d_ino_count = src->d_icount; - dst->d_ino_timer = src->d_itimer; - dst->d_spc_timer = src->d_btimer; + dst->d_ino_timer = copy_from_xfs_dqblk_ts(src, src->d_itimer, + src->d_itimer_hi); + dst->d_spc_timer = copy_from_xfs_dqblk_ts(src, src->d_btimer, + src->d_btimer_hi); dst->d_ino_warns = src->d_iwarns; dst->d_spc_warns = src->d_bwarns; dst->d_rt_spc_hardlimit = quota_bbtob(src->d_rtb_hardlimit); dst->d_rt_spc_softlimit = quota_bbtob(src->d_rtb_softlimit); dst->d_rt_space = quota_bbtob(src->d_rtbcount); - dst->d_rt_spc_timer = src->d_rtbtimer; + dst->d_rt_spc_timer = copy_from_xfs_dqblk_ts(src, src->d_rtbtimer, + src->d_rtbtimer_hi); dst->d_rt_spc_warns = src->d_rtbwarns; dst->d_fieldmask = 0; if (src->d_fieldmask & FS_DQ_ISOFT) @@ -588,10 +599,26 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, return sb->s_qcop->set_dqblk(sb, qid, &qdq); } +static inline void copy_to_xfs_dqblk_ts(const struct fs_disk_quota *d, + __s32 *timer_lo, __s8 *timer_hi, s64 timer) +{ + *timer_lo = timer; + if (d->d_fieldmask & FS_DQ_BIGTIME) + *timer_hi = timer >> 32; +} + +static inline bool want_bigtime(s64 timer) +{ + return timer > S32_MAX || timer < S32_MIN; +} + static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src, int type, qid_t id) { memset(dst, 0, sizeof(*dst)); + if (want_bigtime(src->d_ino_timer) || want_bigtime(src->d_spc_timer) || + want_bigtime(src->d_rt_spc_timer)) + dst->d_fieldmask |= FS_DQ_BIGTIME; dst->d_version = FS_DQUOT_VERSION; dst->d_id = id; if (type == USRQUOTA) @@ -606,14 +633,17 @@ static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src, dst->d_ino_softlimit = src->d_ino_softlimit; dst->d_bcount = quota_btobb(src->d_space); dst->d_icount = src->d_ino_count; - dst->d_itimer = src->d_ino_timer; - dst->d_btimer = src->d_spc_timer; + copy_to_xfs_dqblk_ts(dst, &dst->d_itimer, &dst->d_itimer_hi, + src->d_ino_timer); + copy_to_xfs_dqblk_ts(dst, &dst->d_btimer, &dst->d_btimer_hi, + src->d_spc_timer); dst->d_iwarns = src->d_ino_warns; dst->d_bwarns = src->d_spc_warns; dst->d_rtb_hardlimit = quota_btobb(src->d_rt_spc_hardlimit); dst->d_rtb_softlimit = quota_btobb(src->d_rt_spc_softlimit); dst->d_rtbcount = quota_btobb(src->d_rt_space); - dst->d_rtbtimer = src->d_rt_spc_timer; + copy_to_xfs_dqblk_ts(dst, &dst->d_rtbtimer, &dst->d_rtbtimer_hi, + src->d_rt_spc_timer); dst->d_rtbwarns = src->d_rt_spc_warns; } diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h index 03d890b80ebc..16d73f54376d 100644 --- a/include/uapi/linux/dqblk_xfs.h +++ b/include/uapi/linux/dqblk_xfs.h @@ -66,7 +66,10 @@ typedef struct fs_disk_quota { __s32 d_btimer; /* similar to above; for disk blocks */ __u16 d_iwarns; /* # warnings issued wrt num inodes */ __u16 d_bwarns; /* # warnings issued wrt disk blocks */ - __s32 d_padding2; /* padding2 - for future use */ + __s8 d_itimer_hi; /* upper 8 bits of timer values */ + __s8 d_btimer_hi; + __s8 d_rtbtimer_hi; + __s8 d_padding2; /* padding2 - for future use */ __u64 d_rtb_hardlimit;/* absolute limit on realtime blks */ __u64 d_rtb_softlimit;/* preferred limit on RT disk blks */ __u64 d_rtbcount; /* # realtime blocks owned */ @@ -121,6 +124,12 @@ typedef struct fs_disk_quota { #define FS_DQ_RTBCOUNT (1<<14) #define FS_DQ_ACCT_MASK (FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT) +/* + * Quota expiration timestamps are 40-bit signed integers, with the upper 8 + * bits encoded in the _hi fields. + */ +#define FS_DQ_BIGTIME (1<<15) + /* * Various flags related to quotactl(2). */ From d1c10767837c4181f2e054865a58166fc117783b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 9 Sep 2020 15:54:46 +0200 Subject: [PATCH 30/88] quota: Expand comment describing d_itimer Expand comment describing d_itimer in struct fs_disk_quota. Reported-by: Matthew Wilcox Signed-off-by: Jan Kara --- include/uapi/linux/dqblk_xfs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h index 16d73f54376d..c71d909addda 100644 --- a/include/uapi/linux/dqblk_xfs.h +++ b/include/uapi/linux/dqblk_xfs.h @@ -61,8 +61,9 @@ typedef struct fs_disk_quota { __u64 d_ino_softlimit;/* preferred inode limit */ __u64 d_bcount; /* # disk blocks owned by the user */ __u64 d_icount; /* # inodes owned by the user */ - __s32 d_itimer; /* zero if within inode limits */ - /* if not, we refuse service */ + __s32 d_itimer; /* Zero if within inode limits. If + * not, we refuse service at this time + * (in seconds since Unix epoch) */ __s32 d_btimer; /* similar to above; for disk blocks */ __u16 d_iwarns; /* # warnings issued wrt num inodes */ __u16 d_bwarns; /* # warnings issued wrt disk blocks */ From c53ec7bcc780fde4916e7a563d68b90b20b0b6bc Mon Sep 17 00:00:00 2001 From: Wang Hai Date: Fri, 11 Sep 2020 19:40:36 +0800 Subject: [PATCH 31/88] ext2: Fix some kernel-doc warnings in balloc.c Fixes the following W=1 kernel build warning(s): fs/ext2/balloc.c:203: warning: Excess function parameter 'rb_root' description in '__rsv_window_dump' fs/ext2/balloc.c:294: warning: Excess function parameter 'rb_root' description in 'search_reserve_window' fs/ext2/balloc.c:878: warning: Excess function parameter 'rsv' description in 'alloc_new_reservation' Link: https://lore.kernel.org/r/20200911114036.60616-1-wanghai38@huawei.com Reported-by: Hulk Robot Signed-off-by: Wang Hai Signed-off-by: Jan Kara --- fs/ext2/balloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index fa9c951d3471..1f3f4326bf3c 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -189,7 +189,7 @@ static void group_adjust_blocks(struct super_block *sb, int group_no, /** * __rsv_window_dump() -- Dump the filesystem block allocation reservation map - * @rb_root: root of per-filesystem reservation rb tree + * @root: root of per-filesystem reservation rb tree * @verbose: verbose mode * @fn: function which wishes to dump the reservation map * @@ -282,7 +282,7 @@ goal_in_my_reservation(struct ext2_reserve_window *rsv, ext2_grpblk_t grp_goal, /** * search_reserve_window() - * @rb_root: root of reservation tree + * @root: root of reservation tree * @goal: target allocation block * * Find the reserved window which includes the goal, or the previous one @@ -859,7 +859,7 @@ static int find_next_reservable_window( * * failed: we failed to find a reservation window in this group * - * @rsv: the reservation + * @my_rsv: the reservation * * @grp_goal: The goal (group-relative). It is where the search for a * free reservable space should start from. From 8859bf2b1278d064a139e3031451524a49a56bd0 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 28 Jun 2020 00:00:57 -0700 Subject: [PATCH 32/88] reiserfs: only call unlock_new_inode() if I_NEW unlock_new_inode() is only meant to be called after a new inode has already been inserted into the hash table. But reiserfs_new_inode() can call it even before it has inserted the inode, triggering the WARNING in unlock_new_inode(). Fix this by only calling unlock_new_inode() if the inode has the I_NEW flag set, indicating that it's in the table. This addresses the syzbot report "WARNING in unlock_new_inode" (https://syzkaller.appspot.com/bug?extid=187510916eb6a14598f7). Link: https://lore.kernel.org/r/20200628070057.820213-1-ebiggers@kernel.org Reported-by: syzbot+187510916eb6a14598f7@syzkaller.appspotmail.com Signed-off-by: Eric Biggers Signed-off-by: Jan Kara --- fs/reiserfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 1509775da040..e3af44c61524 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -2163,7 +2163,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, out_inserted_sd: clear_nlink(inode); th->t_trans_id = 0; /* so the caller can't use this handle later */ - unlock_new_inode(inode); /* OK to do even if we hadn't locked it */ + if (inode->i_state & I_NEW) + unlock_new_inode(inode); iput(inode); return err; } From 36725cb091c51104e74d1008097e5d4d10ff372f Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:10:33 +0800 Subject: [PATCH 33/88] HID: intel-ish-hid: simplify the return expression of ishtp_bus_remove_device() Simplify the return expression. Signed-off-by: Qinglang Miao Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/bus.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index c47c3328a0f4..bba29cd36d29 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -502,8 +502,6 @@ static void ishtp_bus_remove_device(struct ishtp_cl_device *device) int ishtp_cl_driver_register(struct ishtp_cl_driver *driver, struct module *owner) { - int err; - if (!ishtp_device_ready) return -ENODEV; @@ -511,11 +509,7 @@ int ishtp_cl_driver_register(struct ishtp_cl_driver *driver, driver->driver.owner = owner; driver->driver.bus = &ishtp_cl_bus_type; - err = driver_register(&driver->driver); - if (err) - return err; - - return 0; + return driver_register(&driver->driver); } EXPORT_SYMBOL(ishtp_cl_driver_register); From 2c3468893779480f90b4a7a8e3df0ade0c4b7a75 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 20 Sep 2020 15:17:16 +0100 Subject: [PATCH 34/88] HID: alps: clean up indentation issue There is an if statement that is indented too deeply, fix this by removing the extraneous tab. Signed-off-by: Colin Ian King Signed-off-by: Jiri Kosina --- drivers/hid/hid-alps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c index a9c2de95c5e2..3feaece13ade 100644 --- a/drivers/hid/hid-alps.c +++ b/drivers/hid/hid-alps.c @@ -526,7 +526,7 @@ static int u1_init(struct hid_device *hdev, struct alps_dev *pri_data) ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y, &sen_line_num_y, 0, true); - if (ret < 0) { + if (ret < 0) { dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret); goto exit; } From aa9f6661eddd342e8d7a621a805beb7354d8d8f9 Mon Sep 17 00:00:00 2001 From: Jing Xiangfeng Date: Tue, 22 Sep 2020 16:13:22 +0800 Subject: [PATCH 35/88] udf: Remove redundant initialization of variable ret After commit 9293fcfbc181 ("udf: Remove struct ustr as non-needed intermediate storage"), the variable ret is being initialized with '-ENOMEM' that is meaningless. So remove it. Link: https://lore.kernel.org/r/20200922081322.70535-1-jingxiangfeng@huawei.com Signed-off-by: Jing Xiangfeng Signed-off-by: Jan Kara --- fs/udf/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index d9eabbe368ff..8b381456482d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -854,7 +854,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) uint8_t *outstr; struct buffer_head *bh; uint16_t ident; - int ret = -ENOMEM; + int ret; struct timestamp *ts; outstr = kmalloc(128, GFP_NOFS); From 140958da9ab53a7df9e9ccc7678ea64655279ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20Wikstr=C3=B6m?= Date: Tue, 22 Sep 2020 11:48:10 +0200 Subject: [PATCH 36/88] HID: multitouch: Lenovo X1 Tablet Gen3 trackpoint and buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One more device that needs 40d5bb87 to resolve regression for the trackpoint and three mouse buttons on the type cover of the Lenovo X1 Tablet Gen3. It is probably also needed for the Lenovo X1 Tablet Gen2 with PID 0x60a3 Signed-off-by: Mikael Wikström Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ac89388d758f..79495e218b7f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -727,6 +727,7 @@ #define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 +#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e3152155c4b8..99f041afd5c0 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1973,6 +1973,12 @@ static const struct hid_device_id mt_devices[] = { HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) }, + /* Lenovo X1 TAB Gen 3 */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_LENOVO, + USB_DEVICE_ID_LENOVO_X1_TAB3) }, + /* MosArt panels */ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, MT_USB_DEVICE(USB_VENDOR_ID_ASUS, From 4a6a4c966ccf38b2d74c05bb7c7dd3b94dbb3c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20Wikstr=C3=B6m?= Date: Tue, 22 Sep 2020 12:07:15 +0200 Subject: [PATCH 37/88] HID: multitouch: Lenovo X1 Tablet Gen2 trackpoint and buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One more device that needs 40d5bb87 to resolve regression for the trackpoint and three mouse buttons on the type cover of the Lenovo X1 Tablet Gen2. Signed-off-by: Mikael Wikström Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 79495e218b7f..d69842f79fc6 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -727,6 +727,7 @@ #define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 +#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 99f041afd5c0..d670bcd57bde 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1973,6 +1973,12 @@ static const struct hid_device_id mt_devices[] = { HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) }, + /* Lenovo X1 TAB Gen 2 */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_LENOVO, + USB_DEVICE_ID_LENOVO_X1_TAB) }, + /* Lenovo X1 TAB Gen 3 */ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, From a7be300de800e755714c71103ae4a0d205e41e99 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 22 Sep 2020 12:20:14 +0200 Subject: [PATCH 38/88] udf: Fix memory leak when mounting udf_process_sequence() allocates temporary array for processing partition descriptors on volume which it fails to free. Free the array when it is not needed anymore. Fixes: 7b78fd02fb19 ("udf: Fix handling of Partition Descriptors") CC: stable@vger.kernel.org Reported-by: syzbot+128f4dd6e796c98b3760@syzkaller.appspotmail.com Signed-off-by: Jan Kara --- fs/udf/super.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 8b381456482d..a76025de6710 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1690,7 +1690,8 @@ static noinline int udf_process_sequence( "Pointers (max %u supported)\n", UDF_MAX_TD_NESTING); brelse(bh); - return -EIO; + ret = -EIO; + goto out; } vdp = (struct volDescPtr *)bh->b_data; @@ -1710,7 +1711,8 @@ static noinline int udf_process_sequence( curr = get_volume_descriptor_record(ident, bh, &data); if (IS_ERR(curr)) { brelse(bh); - return PTR_ERR(curr); + ret = PTR_ERR(curr); + goto out; } /* Descriptor we don't care about? */ if (!curr) @@ -1732,28 +1734,31 @@ static noinline int udf_process_sequence( */ if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) { udf_err(sb, "Primary Volume Descriptor not found!\n"); - return -EAGAIN; + ret = -EAGAIN; + goto out; } ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block); if (ret < 0) - return ret; + goto out; if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) { ret = udf_load_logicalvol(sb, data.vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset); if (ret < 0) - return ret; + goto out; } /* Now handle prevailing Partition Descriptors */ for (i = 0; i < data.num_part_descs; i++) { ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block); if (ret < 0) - return ret; + goto out; } - - return 0; + ret = 0; +out: + kfree(data.part_descs_loc); + return ret; } /* From 4443390e08d34d5771ab444f601cf71b3c9634a4 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 21 Sep 2020 15:08:50 +0200 Subject: [PATCH 39/88] reiserfs: Initialize inode keys properly reiserfs_read_locked_inode() didn't initialize key length properly. Use _make_cpu_key() macro for key initialization so that all key member are properly initialized. CC: stable@vger.kernel.org Reported-by: syzbot+d94d02749498bb7bab4b@syzkaller.appspotmail.com Signed-off-by: Jan Kara --- fs/reiserfs/inode.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index e3af44c61524..c76d563dec0e 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1551,11 +1551,7 @@ void reiserfs_read_locked_inode(struct inode *inode, * set version 1, version 2 could be used too, because stat data * key is the same in both versions */ - key.version = KEY_FORMAT_3_5; - key.on_disk_key.k_dir_id = dirino; - key.on_disk_key.k_objectid = inode->i_ino; - key.on_disk_key.k_offset = 0; - key.on_disk_key.k_type = 0; + _make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3); /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path_to_sd); From 5f94e9c82a86ac1c624ac7ebf456515a07c10851 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Tue, 22 Sep 2020 20:00:12 +0800 Subject: [PATCH 40/88] HID: core: fix kerneldoc warnings in hid-core.c Fix following warnings caused by mismatch bewteen function parameters and comments. drivers/hid/hid-core.c:931: warning: Function parameter or member 'hid' not described in 'hid_parse_report' drivers/hid/hid-core.c:931: warning: Excess function parameter 'device' description in 'hid_parse_report' drivers/hid/hid-core.c:961: warning: Function parameter or member 'hid' not described in 'hid_validate_values' drivers/hid/hid-core.c:961: warning: Excess function parameter 'device' description in 'hid_validate_values' drivers/hid/hid-core.c:1452: warning: Function parameter or member 'report' not described in 'hid_match_report' drivers/hid/hid-core.c:1452: warning: Excess function parameter 'report_type' description in 'hid_match_report' drivers/hid/hid-core.c:2132: warning: Function parameter or member 'drv' not described in 'new_id_store' drivers/hid/hid-core.c:2132: warning: Excess function parameter 'driver' description in 'new_id_store' Signed-off-by: Xiaofei Tan Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d2ecc9c45255..727d042e8604 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -920,7 +920,7 @@ static int hid_scan_report(struct hid_device *hid) /** * hid_parse_report - parse device report * - * @device: hid device + * @hid: hid device * @start: report start * @size: report size * @@ -945,7 +945,7 @@ static const char * const hid_report_names[] = { /** * hid_validate_values - validate existing device report's value indexes * - * @device: hid device + * @hid: hid device * @type: which report type to examine * @id: which report ID to examine (0 for first) * @field_index: which report field to examine @@ -1444,7 +1444,7 @@ static int search(__s32 *array, __s32 value, unsigned n) * hid_match_report - check if driver's raw_event should be called * * @hid: hid device - * @report_type: type to match against + * @report: hid report to match against * * compare hid->driver->report_table->report_type to report->type */ @@ -2120,7 +2120,7 @@ struct hid_dynid { /** * store_new_id - add a new HID device ID to this driver and re-probe devices - * @driver: target device driver + * @drv: target device driver * @buf: buffer for scanning device ID data * @count: input size * From ca43ab1e54c0898a6e1b40d99ffd7f57c5c42257 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Tue, 22 Sep 2020 20:08:04 +0800 Subject: [PATCH 41/88] HID: i2c-hid: fix kerneldoc warnings in i2c-hid-core.c Fix following warnings caused by mismatch bewteen function parameters and comments. drivers/hid/i2c-hid/i2c-hid-core.c:331: warning: Function parameter or member 'data_len' not described in 'i2c_hid_set_or_send_report' drivers/hid/i2c-hid/i2c-hid-core.c:331: warning: Excess function parameter 'len' description in 'i2c_hid_set_or_send_report' Signed-off-by: Xiaofei Tan Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index dbd04492825d..01e9b367d7a5 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -323,7 +323,7 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, * @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT * @reportID: the report ID * @buf: the actual data to transfer, without the report ID - * @len: size of buf + * @data_len: size of buf * @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report */ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, From 997a91fd4448e2600e460af31e5fb934328374a9 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Sat, 5 Sep 2020 01:31:39 -0400 Subject: [PATCH 42/88] selftests: Add missing gitignore entries Prevent them from polluting git status after building selftests. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Shuah Khan --- tools/testing/selftests/firmware/.gitignore | 2 ++ tools/testing/selftests/netfilter/.gitignore | 2 ++ tools/testing/selftests/ptrace/.gitignore | 1 + 3 files changed, 5 insertions(+) create mode 100644 tools/testing/selftests/firmware/.gitignore create mode 100644 tools/testing/selftests/netfilter/.gitignore diff --git a/tools/testing/selftests/firmware/.gitignore b/tools/testing/selftests/firmware/.gitignore new file mode 100644 index 000000000000..62abc92a94c4 --- /dev/null +++ b/tools/testing/selftests/firmware/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +fw_namespace diff --git a/tools/testing/selftests/netfilter/.gitignore b/tools/testing/selftests/netfilter/.gitignore new file mode 100644 index 000000000000..8448f74adfec --- /dev/null +++ b/tools/testing/selftests/netfilter/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +nf-queue diff --git a/tools/testing/selftests/ptrace/.gitignore b/tools/testing/selftests/ptrace/.gitignore index 7bebf9534a86..792318aaa30c 100644 --- a/tools/testing/selftests/ptrace/.gitignore +++ b/tools/testing/selftests/ptrace/.gitignore @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only get_syscall_info peeksiginfo +vmaccess From 67e2fae3b767fd4444f3f161f6420d0d0338a10d Mon Sep 17 00:00:00 2001 From: Brendan Higgins Date: Wed, 23 Sep 2020 14:19:38 -0700 Subject: [PATCH 43/88] kunit: tool: fix --alltests flag Alltests flag evidently stopped working when run from outside of the root of the source tree, so fix that. Also add an additional broken config to the broken_on_uml config. Signed-off-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/configs/broken_on_uml.config | 1 + tools/testing/kunit/kunit_kernel.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tools/testing/kunit/configs/broken_on_uml.config b/tools/testing/kunit/configs/broken_on_uml.config index 239b9f03da2c..a7f0603d33f6 100644 --- a/tools/testing/kunit/configs/broken_on_uml.config +++ b/tools/testing/kunit/configs/broken_on_uml.config @@ -39,3 +39,4 @@ # CONFIG_QCOM_CPR is not set # CONFIG_RESET_BRCMSTB_RESCAL is not set # CONFIG_RESET_INTEL_GW is not set +# CONFIG_ADI_AXI_ADC is not set diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index e20e2056cb38..1b1826500f61 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -53,18 +53,23 @@ class LinuxSourceTreeOperations(object): except subprocess.CalledProcessError as e: raise ConfigError(e.output) - def make_allyesconfig(self): + def make_allyesconfig(self, build_dir, make_options): kunit_parser.print_with_timestamp( 'Enabling all CONFIGs for UML...') + command = ['make', 'ARCH=um', 'allyesconfig'] + if make_options: + command.extend(make_options) + if build_dir: + command += ['O=' + build_dir] process = subprocess.Popen( - ['make', 'ARCH=um', 'allyesconfig'], + command, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) process.wait() kunit_parser.print_with_timestamp( 'Disabling broken configs to run KUnit tests...') with ExitStack() as es: - config = open(KCONFIG_PATH, 'a') + config = open(get_kconfig_path(build_dir), 'a') disable = open(BROKEN_ALLCONFIG_PATH, 'r').read() config.write(disable) kunit_parser.print_with_timestamp( @@ -161,9 +166,9 @@ class LinuxSourceTree(object): return self.build_config(build_dir, make_options) def build_um_kernel(self, alltests, jobs, build_dir, make_options): - if alltests: - self._ops.make_allyesconfig() try: + if alltests: + self._ops.make_allyesconfig(build_dir, make_options) self._ops.make_olddefconfig(build_dir, make_options) self._ops.make(jobs, build_dir, make_options) except (ConfigError, BuildError) as e: From 3d3dc274ce736227e3197868ff749cff2f175f63 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 24 Sep 2020 11:36:19 -0700 Subject: [PATCH 44/88] quota: clear padding in v2r1_mem2diskdqb() Freshly allocated memory contains garbage, better make sure to init all struct v2r1_disk_dqblk fields to avoid KMSAN report: BUG: KMSAN: uninit-value in qtree_entry_unused+0x137/0x1b0 fs/quota/quota_tree.c:218 CPU: 0 PID: 23373 Comm: syz-executor.1 Not tainted 5.9.0-rc4-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x21c/0x280 lib/dump_stack.c:118 kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:122 __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:219 qtree_entry_unused+0x137/0x1b0 fs/quota/quota_tree.c:218 v2r1_mem2diskdqb+0x43d/0x710 fs/quota/quota_v2.c:285 qtree_write_dquot+0x226/0x870 fs/quota/quota_tree.c:394 v2_write_dquot+0x1ad/0x280 fs/quota/quota_v2.c:333 dquot_commit+0x4af/0x600 fs/quota/dquot.c:482 ext4_write_dquot fs/ext4/super.c:5934 [inline] ext4_mark_dquot_dirty+0x4d8/0x6a0 fs/ext4/super.c:5985 mark_dquot_dirty fs/quota/dquot.c:347 [inline] mark_all_dquot_dirty fs/quota/dquot.c:385 [inline] dquot_alloc_inode+0xc05/0x12b0 fs/quota/dquot.c:1755 __ext4_new_inode+0x8204/0x9d70 fs/ext4/ialloc.c:1155 ext4_tmpfile+0x41a/0x850 fs/ext4/namei.c:2686 vfs_tmpfile+0x2a2/0x570 fs/namei.c:3283 do_tmpfile fs/namei.c:3316 [inline] path_openat+0x4035/0x6a90 fs/namei.c:3359 do_filp_open+0x2b8/0x710 fs/namei.c:3395 do_sys_openat2+0xa88/0x1140 fs/open.c:1168 do_sys_open fs/open.c:1184 [inline] __do_compat_sys_openat fs/open.c:1242 [inline] __se_compat_sys_openat+0x2a4/0x310 fs/open.c:1240 __ia32_compat_sys_openat+0x56/0x70 fs/open.c:1240 do_syscall_32_irqs_on arch/x86/entry/common.c:80 [inline] __do_fast_syscall_32+0x129/0x180 arch/x86/entry/common.c:139 do_fast_syscall_32+0x6a/0xc0 arch/x86/entry/common.c:162 do_SYSENTER_32+0x73/0x90 arch/x86/entry/common.c:205 entry_SYSENTER_compat_after_hwframe+0x4d/0x5c RIP: 0023:0xf7ff4549 Code: b8 01 10 06 03 74 b4 01 10 07 03 74 b0 01 10 08 03 74 d8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 eb 0d 90 90 90 90 90 90 90 90 90 90 90 90 RSP: 002b:00000000f55cd0cc EFLAGS: 00000296 ORIG_RAX: 0000000000000127 RAX: ffffffffffffffda RBX: 00000000ffffff9c RCX: 0000000020000000 RDX: 0000000000410481 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 Uninit was created at: kmsan_save_stack_with_flags mm/kmsan/kmsan.c:143 [inline] kmsan_internal_poison_shadow+0x66/0xd0 mm/kmsan/kmsan.c:126 kmsan_slab_alloc+0x8a/0xe0 mm/kmsan/kmsan_hooks.c:80 slab_alloc_node mm/slub.c:2907 [inline] slab_alloc mm/slub.c:2916 [inline] __kmalloc+0x2bb/0x4b0 mm/slub.c:3982 kmalloc include/linux/slab.h:559 [inline] getdqbuf+0x56/0x150 fs/quota/quota_tree.c:52 qtree_write_dquot+0xf2/0x870 fs/quota/quota_tree.c:378 v2_write_dquot+0x1ad/0x280 fs/quota/quota_v2.c:333 dquot_commit+0x4af/0x600 fs/quota/dquot.c:482 ext4_write_dquot fs/ext4/super.c:5934 [inline] ext4_mark_dquot_dirty+0x4d8/0x6a0 fs/ext4/super.c:5985 mark_dquot_dirty fs/quota/dquot.c:347 [inline] mark_all_dquot_dirty fs/quota/dquot.c:385 [inline] dquot_alloc_inode+0xc05/0x12b0 fs/quota/dquot.c:1755 __ext4_new_inode+0x8204/0x9d70 fs/ext4/ialloc.c:1155 ext4_tmpfile+0x41a/0x850 fs/ext4/namei.c:2686 vfs_tmpfile+0x2a2/0x570 fs/namei.c:3283 do_tmpfile fs/namei.c:3316 [inline] path_openat+0x4035/0x6a90 fs/namei.c:3359 do_filp_open+0x2b8/0x710 fs/namei.c:3395 do_sys_openat2+0xa88/0x1140 fs/open.c:1168 do_sys_open fs/open.c:1184 [inline] __do_compat_sys_openat fs/open.c:1242 [inline] __se_compat_sys_openat+0x2a4/0x310 fs/open.c:1240 __ia32_compat_sys_openat+0x56/0x70 fs/open.c:1240 do_syscall_32_irqs_on arch/x86/entry/common.c:80 [inline] __do_fast_syscall_32+0x129/0x180 arch/x86/entry/common.c:139 do_fast_syscall_32+0x6a/0xc0 arch/x86/entry/common.c:162 do_SYSENTER_32+0x73/0x90 arch/x86/entry/common.c:205 entry_SYSENTER_compat_after_hwframe+0x4d/0x5c Fixes: 498c60153ebb ("quota: Implement quota format with 64-bit space and inode limits") Link: https://lore.kernel.org/r/20200924183619.4176790-1-edumazet@google.com Signed-off-by: Eric Dumazet Cc: Jan Kara Signed-off-by: Jan Kara --- fs/quota/quota_v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 58fc2a7c7fd1..e69a2bfdd81c 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -282,6 +282,7 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot) d->dqb_curspace = cpu_to_le64(m->dqb_curspace); d->dqb_btime = cpu_to_le64(m->dqb_btime); d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id)); + d->dqb_pad = 0; if (qtree_entry_unused(info, dp)) d->dqb_itime = cpu_to_le64(1); } From d9216d753b2b1406b801243b12aaf00a5ce5b861 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 23 Sep 2020 13:14:56 -0700 Subject: [PATCH 45/88] HID: wacom: Avoid entering wacom_wac_pen_report for pad / battery It has recently been reported that the "heartbeat" report from devices like the 2nd-gen Intuos Pro (PTH-460, PTH-660, PTH-860) or the 2nd-gen Bluetooth-enabled Intuos tablets (CTL-4100WL, CTL-6100WL) can cause the driver to send a spurious BTN_TOUCH=0 once per second in the middle of drawing. This can result in broken lines while drawing on Chrome OS. The source of the issue has been traced back to a change which modified the driver to only call `wacom_wac_pad_report()` once per report instead of once per collection. As part of this change, pad-handling code was removed from `wacom_wac_collection()` under the assumption that the `WACOM_PEN_FIELD` and `WACOM_TOUCH_FIELD` checks would not be satisfied when a pad or battery collection was being processed. To be clear, the macros `WACOM_PAD_FIELD` and `WACOM_PEN_FIELD` do not currently check exclusive conditions. In fact, most "pad" fields will also appear to be "pen" fields simply due to their presence inside of a Digitizer application collection. Because of this, the removal of the check from `wacom_wac_collection()` just causes pad / battery collections to instead trigger a call to `wacom_wac_pen_report()` instead. The pen report function in turn resets the tip switch state just prior to exiting, resulting in the observed BTN_TOUCH=0 symptom. To correct this, we restore a version of the `WACOM_PAD_FIELD` check in `wacom_wac_collection()` and return early. This effectively prevents pad / battery collections from being reported until the very end of the report as originally intended. Fixes: d4b8efeb46d9 ("HID: wacom: generic: Correct pad syncing") Cc: stable@vger.kernel.org # v4.17+ Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Tested-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1c96809b51c9..b74acbd5997b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2773,7 +2773,9 @@ static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *repo if (report->type != HID_INPUT_REPORT) return -1; - if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) + if (WACOM_PAD_FIELD(field)) + return 0; + else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_report(hdev, report); else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) wacom_wac_finger_report(hdev, report); From 505f394fa239cecb76d916aa858f87ed7ea7fde4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 25 Sep 2020 16:35:52 -0700 Subject: [PATCH 46/88] HID: hid-input: fix stylus battery reporting With commit 4f3882177240 hid-input started clearing of "ignored" usages to avoid using garbage that might have been left in them. However "battery strength" usages should not be ignored, as we do want to use them. Fixes: 4f3882177240 ("HID: hid-input: clear unmapped usages") Reported-by: Kenneth Albanowski Tested-by: Kenneth Albanowski Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 88e19996427e..9770db624bfa 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -797,7 +797,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x3b: /* Battery Strength */ hidinput_setup_battery(device, HID_INPUT_REPORT, field); usage->type = EV_PWR; - goto ignore; + return; case 0x3c: /* Invert */ map_key_clear(BTN_TOOL_RUBBER); @@ -1059,7 +1059,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_DC_BATTERYSTRENGTH: hidinput_setup_battery(device, HID_INPUT_REPORT, field); usage->type = EV_PWR; - goto ignore; + return; } goto unknown; From 044e2e26f214e5ab26af85faffd8d1e4ec066931 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 25 Sep 2020 12:14:03 +0200 Subject: [PATCH 47/88] udf: Avoid accessing uninitialized data on failed inode read When we fail to read inode, some data accessed in udf_evict_inode() may be uninitialized. Move the accesses to !is_bad_inode() branch. Reported-by: syzbot+91f02b28f9bb5f5f1341@syzkaller.appspotmail.com Signed-off-by: Jan Kara --- fs/udf/inode.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index adaba8e8b326..566118417e56 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -139,21 +139,24 @@ void udf_evict_inode(struct inode *inode) struct udf_inode_info *iinfo = UDF_I(inode); int want_delete = 0; - if (!inode->i_nlink && !is_bad_inode(inode)) { - want_delete = 1; - udf_setsize(inode, 0); - udf_update_inode(inode, IS_SYNC(inode)); + if (!is_bad_inode(inode)) { + if (!inode->i_nlink) { + want_delete = 1; + udf_setsize(inode, 0); + udf_update_inode(inode, IS_SYNC(inode)); + } + if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && + inode->i_size != iinfo->i_lenExtents) { + udf_warn(inode->i_sb, + "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n", + inode->i_ino, inode->i_mode, + (unsigned long long)inode->i_size, + (unsigned long long)iinfo->i_lenExtents); + } } truncate_inode_pages_final(&inode->i_data); invalidate_inode_buffers(inode); clear_inode(inode); - if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && - inode->i_size != iinfo->i_lenExtents) { - udf_warn(inode->i_sb, "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n", - inode->i_ino, inode->i_mode, - (unsigned long long)inode->i_size, - (unsigned long long)iinfo->i_lenExtents); - } kfree(iinfo->i_ext.i_data); iinfo->i_ext.i_data = NULL; udf_clear_extent_cache(inode); From 382a2287bf9cd283206764572f66ab12657218aa Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 25 Sep 2020 12:29:54 +0200 Subject: [PATCH 48/88] udf: Remove pointless union in udf_inode_info We use only a single member out of the i_ext union in udf_inode_info. Just remove the pointless union. Signed-off-by: Jan Kara --- fs/udf/directory.c | 2 +- fs/udf/file.c | 7 +++---- fs/udf/ialloc.c | 14 +++++++------- fs/udf/inode.c | 36 +++++++++++++++++------------------- fs/udf/misc.c | 6 +++--- fs/udf/namei.c | 7 +++---- fs/udf/partition.c | 2 +- fs/udf/super.c | 4 ++-- fs/udf/symlink.c | 2 +- fs/udf/udf_i.h | 6 +----- 10 files changed, 39 insertions(+), 47 deletions(-) diff --git a/fs/udf/directory.c b/fs/udf/directory.c index d9523013096f..73720320f0ab 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -34,7 +34,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, fibh->soffset = fibh->eoffset; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { - fi = udf_get_fileident(iinfo->i_ext.i_data - + fi = udf_get_fileident(iinfo->i_data - (iinfo->i_efe ? sizeof(struct extendedFileEntry) : sizeof(struct fileEntry)), diff --git a/fs/udf/file.c b/fs/udf/file.c index 628941a6b79a..ad8eefad27d7 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -50,7 +50,7 @@ static void __udf_adinicb_readpage(struct page *page) * So just sample it once and use the same value everywhere. */ kaddr = kmap_atomic(page); - memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, isize); + memcpy(kaddr, iinfo->i_data + iinfo->i_lenEAttr, isize); memset(kaddr + isize, 0, PAGE_SIZE - isize); flush_dcache_page(page); SetPageUptodate(page); @@ -76,8 +76,7 @@ static int udf_adinicb_writepage(struct page *page, BUG_ON(!PageLocked(page)); kaddr = kmap_atomic(page); - memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, - i_size_read(inode)); + memcpy(iinfo->i_data + iinfo->i_lenEAttr, kaddr, i_size_read(inode)); SetPageUptodate(page); kunmap_atomic(kaddr); mark_inode_dirty(inode); @@ -215,7 +214,7 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg); case UDF_GETEABLOCK: return copy_to_user((char __user *)arg, - UDF_I(inode)->i_ext.i_data, + UDF_I(inode)->i_data, UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0; default: return -ENOIOCTLCMD; diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 0adb40718a5d..84ed23edebfd 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -67,16 +67,16 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode) iinfo->i_efe = 1; if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev) sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE; - iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize - - sizeof(struct extendedFileEntry), - GFP_KERNEL); + iinfo->i_data = kzalloc(inode->i_sb->s_blocksize - + sizeof(struct extendedFileEntry), + GFP_KERNEL); } else { iinfo->i_efe = 0; - iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize - - sizeof(struct fileEntry), - GFP_KERNEL); + iinfo->i_data = kzalloc(inode->i_sb->s_blocksize - + sizeof(struct fileEntry), + GFP_KERNEL); } - if (!iinfo->i_ext.i_data) { + if (!iinfo->i_data) { iput(inode); return ERR_PTR(-ENOMEM); } diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 566118417e56..bb89c3e43212 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -157,8 +157,8 @@ void udf_evict_inode(struct inode *inode) truncate_inode_pages_final(&inode->i_data); invalidate_inode_buffers(inode); clear_inode(inode); - kfree(iinfo->i_ext.i_data); - iinfo->i_ext.i_data = NULL; + kfree(iinfo->i_data); + iinfo->i_data = NULL; udf_clear_extent_cache(inode); if (want_delete) { udf_free_inode(inode); @@ -288,14 +288,14 @@ int udf_expand_file_adinicb(struct inode *inode) kaddr = kmap_atomic(page); memset(kaddr + iinfo->i_lenAlloc, 0x00, PAGE_SIZE - iinfo->i_lenAlloc); - memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, + memcpy(kaddr, iinfo->i_data + iinfo->i_lenEAttr, iinfo->i_lenAlloc); flush_dcache_page(page); SetPageUptodate(page); kunmap_atomic(kaddr); } down_write(&iinfo->i_data_sem); - memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00, + memset(iinfo->i_data + iinfo->i_lenEAttr, 0x00, iinfo->i_lenAlloc); iinfo->i_lenAlloc = 0; if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) @@ -311,8 +311,7 @@ int udf_expand_file_adinicb(struct inode *inode) lock_page(page); down_write(&iinfo->i_data_sem); kaddr = kmap_atomic(page); - memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, - inode->i_size); + memcpy(iinfo->i_data + iinfo->i_lenEAttr, kaddr, inode->i_size); kunmap_atomic(kaddr); unlock_page(page); iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; @@ -399,8 +398,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, } mark_buffer_dirty_inode(dbh, inode); - memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0, - iinfo->i_lenAlloc); + memset(iinfo->i_data + iinfo->i_lenEAttr, 0, iinfo->i_lenAlloc); iinfo->i_lenAlloc = 0; eloc.logicalBlockNum = *block; eloc.partitionReferenceNum = @@ -1263,7 +1261,7 @@ int udf_setsize(struct inode *inode, loff_t newsize) if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { down_write(&iinfo->i_data_sem); udf_clear_extent_cache(inode); - memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, + memset(iinfo->i_data + iinfo->i_lenEAttr + newsize, 0x00, bsize - newsize - udf_file_entry_alloc_offset(inode)); iinfo->i_lenAlloc = newsize; @@ -1414,7 +1412,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) sizeof(struct extendedFileEntry)); if (ret) goto out; - memcpy(iinfo->i_ext.i_data, + memcpy(iinfo->i_data, bh->b_data + sizeof(struct extendedFileEntry), bs - sizeof(struct extendedFileEntry)); } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { @@ -1423,7 +1421,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry)); if (ret) goto out; - memcpy(iinfo->i_ext.i_data, + memcpy(iinfo->i_data, bh->b_data + sizeof(struct fileEntry), bs - sizeof(struct fileEntry)); } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { @@ -1436,7 +1434,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) sizeof(struct unallocSpaceEntry)); if (ret) goto out; - memcpy(iinfo->i_ext.i_data, + memcpy(iinfo->i_data, bh->b_data + sizeof(struct unallocSpaceEntry), bs - sizeof(struct unallocSpaceEntry)); return 0; @@ -1617,8 +1615,8 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) static int udf_alloc_i_data(struct inode *inode, size_t size) { struct udf_inode_info *iinfo = UDF_I(inode); - iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL); - if (!iinfo->i_ext.i_data) + iinfo->i_data = kmalloc(size, GFP_KERNEL); + if (!iinfo->i_data) return -ENOMEM; return 0; } @@ -1709,7 +1707,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), - iinfo->i_ext.i_data, inode->i_sb->s_blocksize - + iinfo->i_data, inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)); use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); crclen = sizeof(struct unallocSpaceEntry); @@ -1775,7 +1773,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) if (iinfo->i_efe == 0) { memcpy(bh->b_data + sizeof(struct fileEntry), - iinfo->i_ext.i_data, + iinfo->i_data, inode->i_sb->s_blocksize - sizeof(struct fileEntry)); fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); @@ -1794,7 +1792,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) crclen = sizeof(struct fileEntry); } else { memcpy(bh->b_data + sizeof(struct extendedFileEntry), - iinfo->i_ext.i_data, + iinfo->i_data, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)); efe->objectSize = @@ -2090,7 +2088,7 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos, struct udf_inode_info *iinfo = UDF_I(inode); if (!epos->bh) - ptr = iinfo->i_ext.i_data + epos->offset - + ptr = iinfo->i_data + epos->offset - udf_file_entry_alloc_offset(inode) + iinfo->i_lenEAttr; else @@ -2182,7 +2180,7 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, if (!epos->bh) { if (!epos->offset) epos->offset = udf_file_entry_alloc_offset(inode); - ptr = iinfo->i_ext.i_data + epos->offset - + ptr = iinfo->i_data + epos->offset - udf_file_entry_alloc_offset(inode) + iinfo->i_lenEAttr; alen = udf_file_entry_alloc_offset(inode) + diff --git a/fs/udf/misc.c b/fs/udf/misc.c index 401e64cde1be..eab94527340d 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c @@ -52,9 +52,9 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, uint16_t crclen; struct udf_inode_info *iinfo = UDF_I(inode); - ea = iinfo->i_ext.i_data; + ea = iinfo->i_data; if (iinfo->i_lenEAttr) { - ad = iinfo->i_ext.i_data + iinfo->i_lenEAttr; + ad = iinfo->i_data + iinfo->i_lenEAttr; } else { ad = ea; size += sizeof(struct extendedAttrHeaderDesc); @@ -153,7 +153,7 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type, uint32_t offset; struct udf_inode_info *iinfo = UDF_I(inode); - ea = iinfo->i_ext.i_data; + ea = iinfo->i_data; if (iinfo->i_lenEAttr) { struct extendedAttrHeaderDesc *eahd; diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 77b6d89b9bcd..e169d8fe35b5 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -460,8 +460,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { block = dinfo->i_location.logicalBlockNum; fi = (struct fileIdentDesc *) - (dinfo->i_ext.i_data + - fibh->soffset - + (dinfo->i_data + fibh->soffset - udf_ext0_offset(dir) + dinfo->i_lenEAttr); } else { @@ -940,7 +939,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, mark_buffer_dirty_inode(epos.bh, inode); ea = epos.bh->b_data + udf_ext0_offset(inode); } else - ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; + ea = iinfo->i_data + iinfo->i_lenEAttr; eoffset = sb->s_blocksize - udf_ext0_offset(inode); pc = (struct pathComponent *)ea; @@ -1120,7 +1119,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, retval = -EIO; if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { dir_fi = udf_get_fileident( - old_iinfo->i_ext.i_data - + old_iinfo->i_data - (old_iinfo->i_efe ? sizeof(struct extendedFileEntry) : sizeof(struct fileEntry)), diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 090baff83990..4cbf40575965 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -65,7 +65,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, } if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { - loc = le32_to_cpu(((__le32 *)(iinfo->i_ext.i_data + + loc = le32_to_cpu(((__le32 *)(iinfo->i_data + vdata->s_start_offset))[block]); goto translate; } diff --git a/fs/udf/super.c b/fs/udf/super.c index a76025de6710..413a50599d1c 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -168,7 +168,7 @@ static void init_once(void *foo) { struct udf_inode_info *ei = (struct udf_inode_info *)foo; - ei->i_ext.i_data = NULL; + ei->i_data = NULL; inode_init_once(&ei->vfs_inode); } @@ -1202,7 +1202,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) vat20 = (struct virtualAllocationTable20 *)bh->b_data; } else { vat20 = (struct virtualAllocationTable20 *) - vati->i_ext.i_data; + vati->i_data; } map->s_type_specific.s_virtual.s_start_offset = diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 25ff91c7e94a..c973db239604 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -122,7 +122,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) down_read(&iinfo->i_data_sem); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { - symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; + symlink = iinfo->i_data + iinfo->i_lenEAttr; } else { bh = sb_bread(inode->i_sb, pos); diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index 4245d1f63258..06ff7006b822 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h @@ -45,11 +45,7 @@ struct udf_inode_info { unsigned i_strat4096 : 1; unsigned i_streamdir : 1; unsigned reserved : 25; - union { - struct short_ad *i_sad; - struct long_ad *i_lad; - __u8 *i_data; - } i_ext; + __u8 *i_data; struct kernel_lb_addr i_locStreamdir; __u64 i_lenStreams; struct rw_semaphore i_data_sem; From 44ac6b829c4e173fdf6df18e6dd86aecf9a3dc99 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 25 Sep 2020 14:53:08 +0200 Subject: [PATCH 49/88] udf: Limit sparing table size Although UDF standard allows it, we don't support sparing table larger than a single block. Check it during mount so that we don't try to access memory beyond end of buffer. Reported-by: syzbot+9991561e714f597095da@syzkaller.appspotmail.com Signed-off-by: Jan Kara --- fs/udf/super.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/udf/super.c b/fs/udf/super.c index 413a50599d1c..faf2017ada11 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1345,6 +1345,12 @@ static int udf_load_sparable_map(struct super_block *sb, (int)spm->numSparingTables); return -EIO; } + if (le32_to_cpu(spm->sizeSparingTable) > sb->s_blocksize) { + udf_err(sb, "error loading logical volume descriptor: " + "Too big sparing table size (%u)\n", + le32_to_cpu(spm->sizeSparingTable)); + return -EIO; + } for (i = 0; i < spm->numSparingTables; i++) { loc = le32_to_cpu(spm->locSparingTable[i]); From 14c9c014babedc6098bf4cd83c622997867bc0df Mon Sep 17 00:00:00 2001 From: Sean O'Brien Date: Wed, 9 Sep 2020 15:03:04 -0700 Subject: [PATCH 50/88] HID: add vivaldi HID driver Add vivaldi HID driver. This driver allows us to read and report the top row layout of keyboards which provide a vendor-defined (Google) HID usage. Signed-off-by: Sean O'Brien Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 9 +++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 7 ++ drivers/hid/hid-vivaldi.c | 144 ++++++++++++++++++++++++++++++++++++++ include/linux/hid.h | 2 + 5 files changed, 163 insertions(+) create mode 100644 drivers/hid/hid-vivaldi.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 05315b434276..612629678c84 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -397,6 +397,15 @@ config HID_GOOGLE_HAMMER help Say Y here if you have a Google Hammer device. +config HID_VIVALDI + tristate "Vivaldi Keyboard" + depends on HID + help + Say Y here if you want to enable support for Vivaldi keyboards. + + Vivaldi keyboards use a vendor-specific (Google) HID usage to report + how the keys in the top row are physically ordered. + config HID_GT683R tristate "MSI GT68xR LED support" depends on LEDS_CLASS && USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index d8ea4b8c95af..4acb583c92a6 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o obj-$(CONFIG_HID_GFRM) += hid-gfrm.o obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o obj-$(CONFIG_HID_GOOGLE_HAMMER) += hid-google-hammer.o +obj-$(CONFIG_HID_VIVALDI) += hid-vivaldi.o obj-$(CONFIG_HID_GT683R) += hid-gt683r.o obj-$(CONFIG_HID_GYRATION) += hid-gyration.o obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d2ecc9c45255..6dbd09254c44 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -814,6 +814,13 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR) parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC; + + if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR) + for (i = 0; i < parser->local.usage_index; i++) + if (parser->local.usage[i] == + (HID_UP_GOOGLEVENDOR | 0x0001)) + parser->device->group = + HID_GROUP_VIVALDI; } static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) diff --git a/drivers/hid/hid-vivaldi.c b/drivers/hid/hid-vivaldi.c new file mode 100644 index 000000000000..cd7ada48b1d9 --- /dev/null +++ b/drivers/hid/hid-vivaldi.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * HID support for Vivaldi Keyboard + * + * Copyright 2020 Google LLC. + * Author: Sean O'Brien + */ + +#include +#include + +#define MIN_FN_ROW_KEY 1 +#define MAX_FN_ROW_KEY 24 +#define HID_VD_FN_ROW_PHYSMAP 0x00000001 +#define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP) + +static struct hid_driver hid_vivaldi; + +struct vivaldi_data { + u32 function_row_physmap[MAX_FN_ROW_KEY - MIN_FN_ROW_KEY + 1]; + int max_function_row_key; +}; + +static ssize_t function_row_physmap_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hid_device *hdev = to_hid_device(dev); + struct vivaldi_data *drvdata = hid_get_drvdata(hdev); + ssize_t size = 0; + int i; + + if (!drvdata->max_function_row_key) + return 0; + + for (i = 0; i < drvdata->max_function_row_key; i++) + size += sprintf(buf + size, "%02X ", + drvdata->function_row_physmap[i]); + size += sprintf(buf + size, "\n"); + return size; +} + +DEVICE_ATTR_RO(function_row_physmap); +static struct attribute *sysfs_attrs[] = { + &dev_attr_function_row_physmap.attr, + NULL +}; + +static const struct attribute_group input_attribute_group = { + .attrs = sysfs_attrs +}; + +static int vivaldi_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + struct vivaldi_data *drvdata; + int ret; + + drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); + hid_set_drvdata(hdev, drvdata); + + ret = hid_parse(hdev); + if (ret) + return ret; + + return hid_hw_start(hdev, HID_CONNECT_DEFAULT); +} + +static void vivaldi_feature_mapping(struct hid_device *hdev, + struct hid_field *field, + struct hid_usage *usage) +{ + struct vivaldi_data *drvdata = hid_get_drvdata(hdev); + int fn_key; + int ret; + u32 report_len; + u8 *buf; + + if (field->logical != HID_USAGE_FN_ROW_PHYSMAP || + (usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL) + return; + + fn_key = (usage->hid & HID_USAGE); + if (fn_key < MIN_FN_ROW_KEY || fn_key > MAX_FN_ROW_KEY) + return; + if (fn_key > drvdata->max_function_row_key) + drvdata->max_function_row_key = fn_key; + + buf = hid_alloc_report_buf(field->report, GFP_KERNEL); + if (!buf) + return; + + report_len = hid_report_len(field->report); + ret = hid_hw_raw_request(hdev, field->report->id, buf, + report_len, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + if (ret < 0) { + dev_warn(&hdev->dev, "failed to fetch feature %d\n", + field->report->id); + goto out; + } + + ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, + report_len, 0); + if (ret) { + dev_warn(&hdev->dev, "failed to report feature %d\n", + field->report->id); + goto out; + } + + drvdata->function_row_physmap[fn_key - MIN_FN_ROW_KEY] = + field->value[usage->usage_index]; + +out: + kfree(buf); +} + +static int vivaldi_input_configured(struct hid_device *hdev, + struct hid_input *hidinput) +{ + return sysfs_create_group(&hdev->dev.kobj, &input_attribute_group); +} + +static const struct hid_device_id vivaldi_table[] = { + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_VIVALDI, HID_ANY_ID, + HID_ANY_ID) }, + { } +}; + +MODULE_DEVICE_TABLE(hid, vivaldi_table); + +static struct hid_driver hid_vivaldi = { + .name = "hid-vivaldi", + .id_table = vivaldi_table, + .probe = vivaldi_probe, + .feature_mapping = vivaldi_feature_mapping, + .input_configured = vivaldi_input_configured, +}; + +module_hid_driver(hid_vivaldi); + +MODULE_AUTHOR("Sean O'Brien"); +MODULE_DESCRIPTION("HID vivaldi driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/hid.h b/include/linux/hid.h index c7044a14200e..58684657960b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -163,6 +163,7 @@ struct hid_item { #define HID_UP_LNVENDOR 0xffa00000 #define HID_UP_SENSOR 0x00200000 #define HID_UP_ASUSVENDOR 0xff310000 +#define HID_UP_GOOGLEVENDOR 0xffd10000 #define HID_USAGE 0x0000ffff @@ -371,6 +372,7 @@ struct hid_item { #define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102 #define HID_GROUP_STEAM 0x0103 #define HID_GROUP_LOGITECH_27MHZ_DEVICE 0x0104 +#define HID_GROUP_VIVALDI 0x0105 /* * HID protocol status From c2bb80b8bdd04dfe32364b78b61b6a47f717af52 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 30 Sep 2020 17:08:20 +0200 Subject: [PATCH 51/88] reiserfs: Fix oops during mount With suitably crafted reiserfs image and mount command reiserfs will crash when trying to verify that XATTR_ROOT directory can be looked up in / as that recurses back to xattr code like: xattr_lookup+0x24/0x280 fs/reiserfs/xattr.c:395 reiserfs_xattr_get+0x89/0x540 fs/reiserfs/xattr.c:677 reiserfs_get_acl+0x63/0x690 fs/reiserfs/xattr_acl.c:209 get_acl+0x152/0x2e0 fs/posix_acl.c:141 check_acl fs/namei.c:277 [inline] acl_permission_check fs/namei.c:309 [inline] generic_permission+0x2ba/0x550 fs/namei.c:353 do_inode_permission fs/namei.c:398 [inline] inode_permission+0x234/0x4a0 fs/namei.c:463 lookup_one_len+0xa6/0x200 fs/namei.c:2557 reiserfs_lookup_privroot+0x85/0x1e0 fs/reiserfs/xattr.c:972 reiserfs_fill_super+0x2b51/0x3240 fs/reiserfs/super.c:2176 mount_bdev+0x24f/0x360 fs/super.c:1417 Fix the problem by bailing from reiserfs_xattr_get() when xattrs are not yet initialized. CC: stable@vger.kernel.org Reported-by: syzbot+9b33c9b118d77ff59b6f@syzkaller.appspotmail.com Signed-off-by: Jan Kara --- fs/reiserfs/xattr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 28b241cd6987..fe63a7c3e0da 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -674,6 +674,13 @@ reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer, if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; + /* + * priv_root needn't be initialized during mount so allow initial + * lookups to succeed. + */ + if (!REISERFS_SB(inode->i_sb)->priv_root) + return 0; + dentry = xattr_lookup(inode, name, XATTR_REPLACE); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); From 82206a0c06ccbd4a80cd623b9d52fcda130d6c7d Mon Sep 17 00:00:00 2001 From: Brendan Higgins Date: Mon, 28 Sep 2020 13:02:27 -0700 Subject: [PATCH 52/88] kunit: tool: handle when .kunit exists but .kunitconfig does not Right now .kunitconfig and the build dir are automatically created if the build dir does not exists; however, if the build dir is present and .kunitconfig is not, kunit_tool will crash. Fix this by checking for both the build dir as well as the .kunitconfig. NOTE: This depends on commit 5578d008d9e0 ("kunit: tool: fix running kunit_tool from outside kernel tree") Link: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git/commit/?id=5578d008d9e06bb531fb3e62dd17096d9fd9c853 Signed-off-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 3c95a0eb0d04..ebf5f5763dee 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -261,6 +261,8 @@ def main(argv, linux=None): if cli_args.subcommand == 'run': if not os.path.exists(cli_args.build_dir): os.mkdir(cli_args.build_dir) + + if not os.path.exists(kunit_kernel.kunitconfig_path): create_default_kunitconfig() if not linux: @@ -277,10 +279,12 @@ def main(argv, linux=None): if result.status != KunitStatus.SUCCESS: sys.exit(1) elif cli_args.subcommand == 'config': - if cli_args.build_dir: - if not os.path.exists(cli_args.build_dir): - os.mkdir(cli_args.build_dir) - create_default_kunitconfig() + if cli_args.build_dir and ( + not os.path.exists(cli_args.build_dir)): + os.mkdir(cli_args.build_dir) + + if not os.path.exists(kunit_kernel.kunitconfig_path): + create_default_kunitconfig() if not linux: linux = kunit_kernel.LinuxSourceTree() From 8964bd4ff6f01462c7bdbe3d1280cf59e6157980 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:15 +0200 Subject: [PATCH 53/88] MAINTAINERS: add the sample directory to the configfs entry Code samples for configfs don't have an explicit maintainer. Add the samples directory to the existing configfs entry in MAINTAINERS. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index d746519253c3..6bbe4cb67331 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4407,6 +4407,7 @@ S: Supported T: git git://git.infradead.org/users/hch/configfs.git F: fs/configfs/ F: include/linux/configfs.h +F: samples/configfs/ CONNECTOR M: Evgeniy Polyakov From 447243737c9d52d9c77fe0da0ed993903b64f28c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 7 Oct 2020 15:43:56 +0200 Subject: [PATCH 54/88] samples: configfs: remove redundant newlines There's no need for suplemental newlines in the source file - especially since the examples are well divided with comments already. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index e2398d94e8da..cabe77ef05d5 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -15,11 +15,8 @@ #include #include #include - #include - - /* * 01-childless * @@ -117,7 +114,6 @@ static struct childless childless_subsys = { }, }; - /* ----------------------------------------------------------------- */ /* @@ -185,7 +181,6 @@ static const struct config_item_type simple_child_type = { .ct_owner = THIS_MODULE, }; - struct simple_children { struct config_group group; }; @@ -263,7 +258,6 @@ static struct configfs_subsystem simple_children_subsys = { }, }; - /* ----------------------------------------------------------------- */ /* From e0ee1fdb3fc49102e03c34527c5185b4761c7c8f Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:18 +0200 Subject: [PATCH 55/88] samples: configfs: drop unnecessary ternary operators Checking pointers for NULL value before passing them to container_of() is pointless because even if we return NULL from the ternary operator, none of the users checks the returned value but they instead dereference it unconditionally. AFAICT this cannot really happen either. Simplify the code by removing the ternary operators from to_childless() et al. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index cabe77ef05d5..ad3f8e1071fa 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -37,8 +37,8 @@ struct childless { static inline struct childless *to_childless(struct config_item *item) { - return item ? container_of(to_configfs_subsystem(to_config_group(item)), - struct childless, subsys) : NULL; + return container_of(to_configfs_subsystem(to_config_group(item)), + struct childless, subsys); } static ssize_t childless_showme_show(struct config_item *item, char *page) @@ -132,7 +132,7 @@ struct simple_child { static inline struct simple_child *to_simple_child(struct config_item *item) { - return item ? container_of(item, struct simple_child, item) : NULL; + return container_of(item, struct simple_child, item); } static ssize_t simple_child_storeme_show(struct config_item *item, char *page) @@ -187,8 +187,8 @@ struct simple_children { static inline struct simple_children *to_simple_children(struct config_item *item) { - return item ? container_of(to_config_group(item), - struct simple_children, group) : NULL; + return container_of(to_config_group(item), + struct simple_children, group); } static struct config_item *simple_children_make_item(struct config_group *group, From 1b0d36e81bdc52684af19f0cad9c9dca13ce4dbc Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:20 +0200 Subject: [PATCH 56/88] samples: configfs: fix alignment in item struct Aling the assignment of a static structure's field to be consistent with all other instances. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index ad3f8e1071fa..1af7cc965098 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -172,7 +172,7 @@ static void simple_child_release(struct config_item *item) } static struct configfs_item_operations simple_child_item_ops = { - .release = simple_child_release, + .release = simple_child_release, }; static const struct config_item_type simple_child_type = { From b86ff67d5a28f3ac1479d99b8a687e7107c58ae6 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:21 +0200 Subject: [PATCH 57/88] samples: configfs: replace simple_strtoul() with kstrtoint() simple_strtoul() is deprecated. Use kstrtoint(). Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 1af7cc965098..7cf1d44c1e37 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -61,17 +62,11 @@ static ssize_t childless_storeme_store(struct config_item *item, const char *page, size_t count) { struct childless *childless = to_childless(item); - unsigned long tmp; - char *p = (char *) page; + int ret; - tmp = simple_strtoul(p, &p, 10); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp > INT_MAX) - return -ERANGE; - - childless->storeme = tmp; + ret = kstrtoint(page, 10, &childless->storeme); + if (ret) + return ret; return count; } @@ -144,17 +139,11 @@ static ssize_t simple_child_storeme_store(struct config_item *item, const char *page, size_t count) { struct simple_child *simple_child = to_simple_child(item); - unsigned long tmp; - char *p = (char *) page; + int ret; - tmp = simple_strtoul(p, &p, 10); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp > INT_MAX) - return -ERANGE; - - simple_child->storeme = tmp; + ret = kstrtoint(page, 10, &simple_child->storeme); + if (ret) + return ret; return count; } From 91aad62560fc8cc11a1f04e627da0c0f0d33ef08 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:22 +0200 Subject: [PATCH 58/88] samples: configfs: don't reinitialize variables which are already zeroed The structure containing the storeme field is allocated using kzalloc(). There's no need to set it to 0 again. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 7cf1d44c1e37..66bb9bc5c8d0 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -192,8 +192,6 @@ static struct config_item *simple_children_make_item(struct config_group *group, config_item_init_type_name(&simple_child->item, name, &simple_child_type); - simple_child->storeme = 0; - return &simple_child->item; } From 4e415a844ddd705cc7de87e01f0e6189a3def8ef Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:24 +0200 Subject: [PATCH 59/88] samples: configfs: consolidate local variables of the same type Move local variables of the same type into a single line for better readability. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 66bb9bc5c8d0..2e56d6920642 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -331,9 +331,8 @@ static struct configfs_subsystem *example_subsys[] = { static int __init configfs_example_init(void) { - int ret; - int i; struct configfs_subsystem *subsys; + int ret, i; for (i = 0; example_subsys[i]; i++) { subsys = example_subsys[i]; From 288f295e0a49481c4ff64715b6b3eb8ebfe3432b Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:25 +0200 Subject: [PATCH 60/88] samples: configfs: don't use spaces before tabs The copyright notice alarms checkpatch.pl of usin spaces before tabs. Fix this. Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 2e56d6920642..83e2ad7a1b08 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -7,7 +7,7 @@ * macros defined by configfs.h * * Based on sysfs: - * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel + * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel * * configfs Copyright (C) 2005 Oracle. All rights reserved. */ From 76ecfcb0852eb0390881a695a2f349b804d80147 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 24 Sep 2020 14:45:26 +0200 Subject: [PATCH 61/88] samples: configfs: prefer pr_err() over bare printk(KERN_ERR pr_*() printing helpers are preferred over using bare printk(). Signed-off-by: Bartosz Golaszewski Signed-off-by: Christoph Hellwig --- samples/configfs/configfs_sample.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c index 83e2ad7a1b08..f9008be7a8a1 100644 --- a/samples/configfs/configfs_sample.c +++ b/samples/configfs/configfs_sample.c @@ -341,9 +341,8 @@ static int __init configfs_example_init(void) mutex_init(&subsys->su_mutex); ret = configfs_register_subsystem(subsys); if (ret) { - printk(KERN_ERR "Error %d while registering subsystem %s\n", - ret, - subsys->su_group.cg_item.ci_namebuf); + pr_err("Error %d while registering subsystem %s\n", + ret, subsys->su_group.cg_item.ci_namebuf); goto out_unregister; } } From f0f0a5df4e081e7a659929303fe83450edce9a3e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 28 Sep 2020 13:26:48 -0700 Subject: [PATCH 62/88] selftests: Extract run_kselftest.sh and generate stand-alone test list Instead of building a script on the fly (which just repeats the same thing for each test collection), move the script out of the Makefile and into run_kselftest.sh, which reads kselftest-list.txt. Adjust the emit_tests target to report each test on a separate line so that test running tools (e.g. LAVA) can easily remove individual tests (for example, as seen in [1]). [1] https://github.com/Linaro/test-definitions/pull/208/commits/2e7b62155e4998e54ac0587704932484d4ff84c8 Signed-off-by: Kees Cook Tested-by: Naresh Kamboju Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 26 ++++++---------------- tools/testing/selftests/lib.mk | 5 ++--- tools/testing/selftests/run_kselftest.sh | 28 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 22 deletions(-) create mode 100755 tools/testing/selftests/run_kselftest.sh diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 15c1c1359c50..d9c283503159 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -206,6 +206,7 @@ KSFT_INSTALL_PATH := $(abspath $(KSFT_INSTALL_PATH)) # Avoid changing the rest of the logic here and lib.mk. INSTALL_PATH := $(KSFT_INSTALL_PATH) ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh +TEST_LIST := $(INSTALL_PATH)/kselftest-list.txt install: all ifdef INSTALL_PATH @@ -214,6 +215,8 @@ ifdef INSTALL_PATH install -m 744 kselftest/module.sh $(INSTALL_PATH)/kselftest/ install -m 744 kselftest/runner.sh $(INSTALL_PATH)/kselftest/ install -m 744 kselftest/prefix.pl $(INSTALL_PATH)/kselftest/ + install -m 744 run_kselftest.sh $(INSTALL_PATH)/ + rm -f $(TEST_LIST) @ret=1; \ for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ @@ -222,33 +225,18 @@ ifdef INSTALL_PATH ret=$$((ret * $$?)); \ done; exit $$ret; - @# Ask all targets to emit their test scripts - echo "#!/bin/sh" > $(ALL_SCRIPT) - echo "BASE_DIR=\$$(realpath \$$(dirname \$$0))" >> $(ALL_SCRIPT) - echo "cd \$$BASE_DIR" >> $(ALL_SCRIPT) - echo ". ./kselftest/runner.sh" >> $(ALL_SCRIPT) - echo "ROOT=\$$PWD" >> $(ALL_SCRIPT) - echo "if [ \"\$$1\" = \"--summary\" ]; then" >> $(ALL_SCRIPT) - echo " logfile=\$$BASE_DIR/output.log" >> $(ALL_SCRIPT) - echo " cat /dev/null > \$$logfile" >> $(ALL_SCRIPT) - echo "fi" >> $(ALL_SCRIPT) - @# While building run_kselftest.sh skip also non-existent TARGET dirs: + @# Ask all targets to emit their test scripts + @# While building kselftest-list.text skip also non-existent TARGET dirs: @# they could be the result of a build failure and should NOT be @# included in the generated runlist. for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ [ ! -d $(INSTALL_PATH)/$$TARGET ] && echo "Skipping non-existent dir: $$TARGET" && continue; \ - echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \ - echo "cd $$TARGET" >> $(ALL_SCRIPT); \ - echo -n "run_many" >> $(ALL_SCRIPT); \ echo -n "Emit Tests for $$TARGET\n"; \ - $(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ - echo "" >> $(ALL_SCRIPT); \ - echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ + $(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET COLLECTION=$$TARGET \ + -C $$TARGET emit_tests >> $(TEST_LIST); \ done; - - chmod u+x $(ALL_SCRIPT) else $(error Error: set INSTALL_PATH to use install) endif diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 51124b962d56..30848ca36555 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -107,9 +107,8 @@ endif emit_tests: for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \ BASENAME_TEST=`basename $$TEST`; \ - echo " \\"; \ - echo -n " \"$$BASENAME_TEST\""; \ - done; \ + echo "$(COLLECTION):$$BASENAME_TEST"; \ + done # define if isn't already. It is undefined in make O= case. ifeq ($(RM),) diff --git a/tools/testing/selftests/run_kselftest.sh b/tools/testing/selftests/run_kselftest.sh new file mode 100755 index 000000000000..8b0ad4766d78 --- /dev/null +++ b/tools/testing/selftests/run_kselftest.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Run installed kselftest tests. +# +BASE_DIR=$(realpath $(dirname $0)) +cd $BASE_DIR +TESTS="$BASE_DIR"/kselftest-list.txt +if [ ! -r "$TESTS" ] ; then + echo "$0: Could not find list of tests to run ($TESTS)" >&2 + exit 1 +fi +available="$(cat "$TESTS")" + +. ./kselftest/runner.sh +ROOT=$PWD + +if [ "$1" = "--summary" ] ; then + logfile="$BASE_DIR"/output.log + cat /dev/null > $logfile +fi + +collections=$(echo "$available" | cut -d: -f1 | uniq) +for collection in $collections ; do + [ -w /dev/kmsg ] && echo "kselftest: Running tests in $collection" >> /dev/kmsg + tests=$(echo "$available" | grep "^$collection:" | cut -d: -f2) + (cd "$collection" && run_many $tests) +done From 5da1918446a1d50d57f2f6062f7fdede0b052473 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 28 Sep 2020 13:26:49 -0700 Subject: [PATCH 63/88] selftests/run_kselftest.sh: Make each test individually selectable Currently with run_kselftest.sh there is no way to choose which test we could run. All the tests listed in kselftest-list.txt are all run every time. This patch enhanced the run_kselftest.sh to make the test collections (or tests) individually selectable. e.g.: $ ./run_kselftest.sh -c seccomp -t timers:posix_timers -t timers:nanosleep Additionally adds a way to list all known tests with "-l", usage with "-h", and perform a dry run without running tests with "-n". Co-developed-by: Hangbin Liu Signed-off-by: Hangbin Liu Signed-off-by: Kees Cook Tested-by: Naresh Kamboju Signed-off-by: Shuah Khan --- tools/testing/selftests/run_kselftest.sh | 77 ++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/run_kselftest.sh b/tools/testing/selftests/run_kselftest.sh index 8b0ad4766d78..609a4ef9300e 100755 --- a/tools/testing/selftests/run_kselftest.sh +++ b/tools/testing/selftests/run_kselftest.sh @@ -8,21 +8,86 @@ cd $BASE_DIR TESTS="$BASE_DIR"/kselftest-list.txt if [ ! -r "$TESTS" ] ; then echo "$0: Could not find list of tests to run ($TESTS)" >&2 - exit 1 + available="" +else + available="$(cat "$TESTS")" fi -available="$(cat "$TESTS")" . ./kselftest/runner.sh ROOT=$PWD -if [ "$1" = "--summary" ] ; then - logfile="$BASE_DIR"/output.log - cat /dev/null > $logfile +usage() +{ + cat < $logfile + shift ;; + -t | --test) + TESTS="$TESTS $2" + shift 2 ;; + -c | --collection) + COLLECTIONS="$COLLECTIONS $2" + shift 2 ;; + -l | --list) + echo "$available" + exit 0 ;; + -n | --dry-run) + dryrun="echo" + shift ;; + -h | --help) + usage 0 ;; + "") + break ;; + *) + usage 1 ;; + esac +done + +# Add all selected collections to the explicit test list. +if [ -n "$COLLECTIONS" ]; then + for collection in $COLLECTIONS ; do + found="$(echo "$available" | grep "^$collection:")" + if [ -z "$found" ] ; then + echo "No such collection '$collection'" >&2 + exit 1 + fi + TESTS="$TESTS $found" + done +fi +# Replace available test list with explicitly selected tests. +if [ -n "$TESTS" ]; then + valid="" + for test in $TESTS ; do + found="$(echo "$available" | grep "^${test}$")" + if [ -z "$found" ] ; then + echo "No such test '$test'" >&2 + exit 1 + fi + valid="$valid $found" + done + available="$(echo "$valid" | sed -e 's/ /\n/g')" fi collections=$(echo "$available" | cut -d: -f1 | uniq) for collection in $collections ; do [ -w /dev/kmsg ] && echo "kselftest: Running tests in $collection" >> /dev/kmsg tests=$(echo "$available" | grep "^$collection:" | cut -d: -f2) - (cd "$collection" && run_many $tests) + ($dryrun cd "$collection" && $dryrun run_many $tests) done From 4c8511317b4ec75cc3868f80a7b9fddb8322e512 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 28 Sep 2020 13:26:50 -0700 Subject: [PATCH 64/88] doc: dev-tools: kselftest.rst: Update examples and paths Update the installation commands and path details, detail the new options available in the run_kselftests.sh script. Signed-off-by: Kees Cook Reviewed-by: Naresh Kamboju Signed-off-by: Shuah Khan --- Documentation/dev-tools/kselftest.rst | 35 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst index 469d115a95f1..a901def730d9 100644 --- a/Documentation/dev-tools/kselftest.rst +++ b/Documentation/dev-tools/kselftest.rst @@ -125,32 +125,41 @@ Note that some tests will require root privileges. Install selftests ================= -You can use the kselftest_install.sh tool to install selftests in the -default location, which is tools/testing/selftests/kselftest, or in a -user specified location. +You can use the "install" target of "make" (which calls the `kselftest_install.sh` +tool) to install selftests in the default location (`tools/testing/selftests/kselftest_install`), +or in a user specified location via the `INSTALL_PATH` "make" variable. To install selftests in default location:: - $ cd tools/testing/selftests - $ ./kselftest_install.sh + $ make -C tools/testing/selftests install To install selftests in a user specified location:: - $ cd tools/testing/selftests - $ ./kselftest_install.sh install_dir + $ make -C tools/testing/selftests install INSTALL_PATH=/some/other/path Running installed selftests =========================== -Kselftest install as well as the Kselftest tarball provide a script -named "run_kselftest.sh" to run the tests. +Found in the install directory, as well as in the Kselftest tarball, +is a script named `run_kselftest.sh` to run the tests. You can simply do the following to run the installed Kselftests. Please note some tests will require root privileges:: - $ cd kselftest + $ cd kselftest_install $ ./run_kselftest.sh +To see the list of available tests, the `-l` option can be used:: + + $ ./run_kselftest.sh -l + +The `-c` option can be used to run all the tests from a test collection, or +the `-t` option for specific single tests. Either can be used multiple times:: + + $ ./run_kselftest.sh -c bpf -c seccomp -t timers:posix_timers -t timer:nanosleep + +For other features see the script usage output, seen with the `-h` option. + Packaging selftests =================== @@ -160,9 +169,9 @@ different system. To package selftests, run:: $ make -C tools/testing/selftests gen_tar This generates a tarball in the `INSTALL_PATH/kselftest-packages` directory. By -default, `.gz` format is used. The tar format can be overridden by specifying -a `FORMAT` make variable. Any value recognized by `tar's auto-compress`_ option -is supported, such as:: +default, `.gz` format is used. The tar compression format can be overridden by +specifying a `FORMAT` make variable. Any value recognized by `tar's auto-compress`_ +option is supported, such as:: $ make -C tools/testing/selftests gen_tar FORMAT=.xz From 46d716025a228de835a8fd51c8420e3ce3c88795 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Thu, 8 Oct 2020 02:26:18 -0400 Subject: [PATCH 65/88] direct-io: clean up error paths of do_blockdev_direct_IO In preparation to resort DIO checks, reduce code duplication of error handling in do_blockdev_direct_IO. Link: https://lore.kernel.org/r/20201008062620.2928326-2-krisman@collabora.com Reviewed-by: Jan Kara Reviewed-by: Jens Axboe Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Jan Kara --- fs/direct-io.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 183299892465..6c11db1cec27 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1170,7 +1170,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, blkbits = blksize_bits(bdev_logical_block_size(bdev)); blocksize_mask = (1 << blkbits) - 1; if (align & blocksize_mask) - goto out; + return -EINVAL; } /* watch out for a 0 len io from a tricksy fs */ @@ -1178,9 +1178,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, return 0; dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); - retval = -ENOMEM; if (!dio) - goto out; + return -ENOMEM; /* * Believe it or not, zeroing out the page array caused a .5% * performance regression in a database benchmark. So, we take @@ -1199,22 +1198,16 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, retval = filemap_write_and_wait_range(mapping, offset, end - 1); - if (retval) { - inode_unlock(inode); - kmem_cache_free(dio_cache, dio); - goto out; - } + if (retval) + goto fail_dio; } } /* Once we sampled i_size check for reads beyond EOF */ dio->i_size = i_size_read(inode); if (iov_iter_rw(iter) == READ && offset >= dio->i_size) { - if (dio->flags & DIO_LOCKING) - inode_unlock(inode); - kmem_cache_free(dio_cache, dio); retval = 0; - goto out; + goto fail_dio; } /* @@ -1258,14 +1251,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, */ retval = sb_init_dio_done_wq(dio->inode->i_sb); } - if (retval) { - /* - * We grab i_mutex only for reads so we don't have - * to release it here - */ - kmem_cache_free(dio_cache, dio); - goto out; - } + if (retval) + goto fail_dio; } /* @@ -1368,7 +1355,13 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, } else BUG_ON(retval != -EIOCBQUEUED); -out: + return retval; + +fail_dio: + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) + inode_unlock(inode); + + kmem_cache_free(dio_cache, dio); return retval; } From 0a9164cb7ff32d6936f14657aebc3c4c2a0d5f9d Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Thu, 8 Oct 2020 02:26:19 -0400 Subject: [PATCH 66/88] direct-io: don't force writeback for reads beyond EOF If a DIO read starts past EOF, the kernel won't attempt it, so we don't need to flush dirty pages before failing the syscall. Link: https://lore.kernel.org/r/20201008062620.2928326-3-krisman@collabora.com Suggested-by: Jan Kara Reviewed-by: Jan Kara Reviewed-by: Jens Axboe Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Jan Kara --- fs/direct-io.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 6c11db1cec27..c17efe58f1c9 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1188,19 +1188,9 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, memset(dio, 0, offsetof(struct dio, pages)); dio->flags = flags; - if (dio->flags & DIO_LOCKING) { - if (iov_iter_rw(iter) == READ) { - struct address_space *mapping = - iocb->ki_filp->f_mapping; - - /* will be released by direct_io_worker */ - inode_lock(inode); - - retval = filemap_write_and_wait_range(mapping, offset, - end - 1); - if (retval) - goto fail_dio; - } + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) { + /* will be released by direct_io_worker */ + inode_lock(inode); } /* Once we sampled i_size check for reads beyond EOF */ @@ -1210,6 +1200,14 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, goto fail_dio; } + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) { + struct address_space *mapping = iocb->ki_filp->f_mapping; + + retval = filemap_write_and_wait_range(mapping, offset, end - 1); + if (retval) + goto fail_dio; + } + /* * For file extending writes updating i_size before data writeouts * complete can expose uninitialized blocks in dumb filesystems. From 41b21af388f94baf7433d4e7845703c7275251de Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Thu, 8 Oct 2020 02:26:20 -0400 Subject: [PATCH 67/88] direct-io: defer alignment check until after the EOF check Prior to commit 9fe55eea7e4b ("Fix race when checking i_size on direct i/o read"), an unaligned direct read past end of file would trigger EOF, since generic_file_aio_read detected this read-at-EOF condition and skipped the direct IO read entirely, returning 0. After that change, the read now reaches dio_generic, which detects the misalignment and returns EINVAL. This consolidates the generic direct-io to follow the same behavior of filesystems. Apparently, this fix will only affect ocfs2 since other filesystems do this verification before calling do_blockdev_direct_IO, with the exception of f2fs, which has the same bug, but is fixed in the next patch. it can be verified by a read loop on a file that does a partial read before EOF (On file that doesn't end at an aligned address). The following code fails on an unaligned file on filesystems without prior validation without this patch, but not on btrfs, ext4, and xfs. while (done < total) { ssize_t delta = pread(fd, buf + done, total - done, off + done); if (!delta) break; ... } Fix this regression by moving the misalignment check to after the EOF check added by commit 74cedf9b6c60 ("direct-io: Fix negative return from dio read beyond eof"). Based on a patch by Jamie Liu. Link: https://lore.kernel.org/r/20201008062620.2928326-4-krisman@collabora.com Reported-by: Jamie Liu Reviewed-by: Jan Kara Reviewed-by: Jens Axboe Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Jan Kara --- fs/direct-io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index c17efe58f1c9..82838cca934b 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1165,14 +1165,6 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, * the early prefetch in the caller enough time. */ - if (align & blocksize_mask) { - if (bdev) - blkbits = blksize_bits(bdev_logical_block_size(bdev)); - blocksize_mask = (1 << blkbits) - 1; - if (align & blocksize_mask) - return -EINVAL; - } - /* watch out for a 0 len io from a tricksy fs */ if (iov_iter_rw(iter) == READ && !count) return 0; @@ -1200,6 +1192,14 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, goto fail_dio; } + if (align & blocksize_mask) { + if (bdev) + blkbits = blksize_bits(bdev_logical_block_size(bdev)); + blocksize_mask = (1 << blkbits) - 1; + if (align & blocksize_mask) + goto fail_dio; + } + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) { struct address_space *mapping = iocb->ki_filp->f_mapping; From 1abdd39f14b25dd2d69096b624a4f86f158a9feb Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Wed, 30 Sep 2020 11:31:51 -0700 Subject: [PATCH 68/88] kunit: tool: fix display of make errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CalledProcessError stores the output of the failed process as `bytes`, not a `str`. So when we log it on build error, the make output is all crammed into one line with "\n" instead of actually printing new lines. After this change, we get readable output with new lines, e.g. > CC lib/kunit/kunit-example-test.o > In file included from ../lib/kunit/test.c:9: > ../include/kunit/test.h:22:1: error: unknown type name ‘invalid_type_that_causes_compile’ > 22 | invalid_type_that_causes_compile errors; > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > make[3]: *** [../scripts/Makefile.build:283: lib/kunit/test.o] Error 1 Secondly, trying to concat exceptions to strings will fail with > TypeError: can only concatenate str (not "OSError") to str so fix this with an explicit cast to str. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Tested-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit_kernel.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index 1b1826500f61..b557b1e93f98 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -36,9 +36,9 @@ class LinuxSourceTreeOperations(object): try: subprocess.check_output(['make', 'mrproper'], stderr=subprocess.STDOUT) except OSError as e: - raise ConfigError('Could not call make command: ' + e) + raise ConfigError('Could not call make command: ' + str(e)) except subprocess.CalledProcessError as e: - raise ConfigError(e.output) + raise ConfigError(e.output.decode()) def make_olddefconfig(self, build_dir, make_options): command = ['make', 'ARCH=um', 'olddefconfig'] @@ -49,9 +49,9 @@ class LinuxSourceTreeOperations(object): try: subprocess.check_output(command, stderr=subprocess.STDOUT) except OSError as e: - raise ConfigError('Could not call make command: ' + e) + raise ConfigError('Could not call make command: ' + str(e)) except subprocess.CalledProcessError as e: - raise ConfigError(e.output) + raise ConfigError(e.output.decode()) def make_allyesconfig(self, build_dir, make_options): kunit_parser.print_with_timestamp( @@ -84,9 +84,9 @@ class LinuxSourceTreeOperations(object): try: subprocess.check_output(command, stderr=subprocess.STDOUT) except OSError as e: - raise BuildError('Could not call execute make: ' + e) + raise BuildError('Could not call execute make: ' + str(e)) except subprocess.CalledProcessError as e: - raise BuildError(e.output) + raise BuildError(e.output.decode()) def linux_bin(self, params, timeout, build_dir, outfile): """Runs the Linux UML binary. Must be named 'linux'.""" From 626b901f60446355e35e8c76c6b391a7d7491203 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Fri, 14 Aug 2020 12:45:04 -0700 Subject: [PATCH 69/88] Drivers: hv: vmbus: Add parsing of VMbus interrupt in ACPI DSDT On ARM64, Hyper-V now specifies the interrupt to be used by VMbus in the ACPI DSDT. This information is not used on x86 because the interrupt vector must be hardcoded. But update the generic VMbus driver to do the parsing and pass the information to the architecture specific code that sets up the Linux IRQ. Update consumers of the interrupt to get it from an architecture specific function. Signed-off-by: Michael Kelley Link: https://lore.kernel.org/r/1597434304-40631-1-git-send-email-mikelley@microsoft.com Signed-off-by: Wei Liu --- arch/x86/include/asm/mshyperv.h | 1 + arch/x86/kernel/cpu/mshyperv.c | 7 ++++++- drivers/hv/hv.c | 2 +- drivers/hv/vmbus_drv.c | 30 +++++++++++++++++++++++++++--- include/asm-generic/mshyperv.h | 4 +++- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 4f77b8f22e54..ffc289992d1b 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -54,6 +54,7 @@ typedef int (*hyperv_fill_flush_list_func)( #define hv_enable_vdso_clocksource() \ vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK); #define hv_get_raw_timer() rdtsc_ordered() +#define hv_get_vector() HYPERVISOR_CALLBACK_VECTOR /* * Reference to pv_ops must be inline so objtool diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 9834a43cd0fa..05ef1f4550cb 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -55,9 +55,14 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback) set_irq_regs(old_regs); } -void hv_setup_vmbus_irq(void (*handler)(void)) +int hv_setup_vmbus_irq(int irq, void (*handler)(void)) { + /* + * The 'irq' argument is ignored on x86/x64 because a hard-coded + * interrupt vector is used for Hyper-V interrupts. + */ vmbus_handler = handler; + return 0; } void hv_remove_vmbus_irq(void) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 410f1fab519c..0cde10fe0e71 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -180,7 +180,7 @@ void hv_synic_enable_regs(unsigned int cpu) /* Setup the shared SINT. */ hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); - shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; + shared_sint.vector = hv_get_vector(); shared_sint.masked = false; shared_sint.auto_eoi = hv_recommend_using_aeoi(); hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 187809977360..4217646decf1 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -48,6 +48,10 @@ static int hyperv_cpuhp_online; static void *hv_panic_page; +/* Values parsed from ACPI DSDT */ +static int vmbus_irq; +int vmbus_interrupt; + /* * Boolean to control whether to report panic messages over Hyper-V. * @@ -1347,7 +1351,7 @@ static void vmbus_isr(void) tasklet_schedule(&hv_cpu->msg_dpc); } - add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0); + add_interrupt_randomness(hv_get_vector(), 0); } /* @@ -1430,7 +1434,9 @@ static int vmbus_bus_init(void) if (ret) return ret; - hv_setup_vmbus_irq(vmbus_isr); + ret = hv_setup_vmbus_irq(vmbus_irq, vmbus_isr); + if (ret) + goto err_setup; ret = hv_synic_alloc(); if (ret) @@ -1505,7 +1511,7 @@ static int vmbus_bus_init(void) hv_synic_free(); err_alloc: hv_remove_vmbus_irq(); - +err_setup: bus_unregister(&hv_bus); unregister_sysctl_table(hv_ctl_table_hdr); hv_ctl_table_hdr = NULL; @@ -2070,6 +2076,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) struct resource *new_res; struct resource **old_res = &hyperv_mmio; struct resource **prev_res = NULL; + struct resource r; switch (res->type) { @@ -2088,6 +2095,23 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) end = res->data.address64.address.maximum; break; + /* + * The IRQ information is needed only on ARM64, which Hyper-V + * sets up in the extended format. IRQ information is present + * on x86/x64 in the non-extended format but it is not used by + * Linux. So don't bother checking for the non-extended format. + */ + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + if (!acpi_dev_resource_interrupt(res, 0, &r)) { + pr_err("Unable to parse Hyper-V ACPI interrupt\n"); + return AE_ERROR; + } + /* ARM64 INTID for VMbus */ + vmbus_interrupt = res->data.extended_irq.interrupts[0]; + /* Linux IRQ number */ + vmbus_irq = r.start; + return AE_OK; + default: /* Unused resource type */ return AE_OK; diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index c5edc5e08b94..c57799684170 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -89,7 +89,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) } } -void hv_setup_vmbus_irq(void (*handler)(void)); +int hv_setup_vmbus_irq(int irq, void (*handler)(void)); void hv_remove_vmbus_irq(void); void hv_enable_vmbus_irq(void); void hv_disable_vmbus_irq(void); @@ -99,6 +99,8 @@ void hv_remove_kexec_handler(void); void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)); void hv_remove_crash_handler(void); +extern int vmbus_interrupt; + #if IS_ENABLED(CONFIG_HYPERV) /* * Hypervisor's notion of virtual processor ID is different from From 6b698713d4e99e5a64e2d07f0df90545809227b9 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 10:00:40 +0200 Subject: [PATCH 70/88] fw_cfg: Add support for parisc architecture Signed-off-by: Helge Deller --- drivers/firmware/Kconfig | 2 +- drivers/firmware/qemu_fw_cfg.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index fbd785dd0513..25f51b60194b 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -187,7 +187,7 @@ config RASPBERRYPI_FIRMWARE config FW_CFG_SYSFS tristate "QEMU fw_cfg device support in sysfs" - depends on SYSFS && (ARM || ARM64 || PPC_PMAC || SPARC || X86) + depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || SPARC || X86) depends on HAS_IOPORT_MAP default n help diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 6945c3c96637..0078260fbabe 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -215,6 +215,9 @@ static void fw_cfg_io_cleanup(void) # define FW_CFG_CTRL_OFF 0x08 # define FW_CFG_DATA_OFF 0x00 # define FW_CFG_DMA_OFF 0x10 +# elif defined(CONFIG_PARISC) /* parisc */ +# define FW_CFG_CTRL_OFF 0x00 +# define FW_CFG_DATA_OFF 0x04 # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */ # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x02 From 024f5b597564acced9e69305f7a9ef1202186a61 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 10:02:38 +0200 Subject: [PATCH 71/88] parisc: Add qemu fw_cfg interface When running on qemu, SeaBIOS-hppa stores the iomem address for the emulated fw_cfg port in PAGE0_>pad0[2/3]. Let the Linux driver auto-configure the fw_cfg interface with it, so that the fw_cfg info shows up in /sys/firmware/qemu_fw_cfg. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 1 + arch/parisc/kernel/inventory.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index cd4afe1e7a6c..087cbef348e6 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -376,5 +376,6 @@ config KEXEC_FILE endmenu +source "drivers/firmware/Kconfig" source "drivers/parisc/Kconfig" diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 9298f2285510..7ab2f2a54400 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -641,4 +642,33 @@ void __init do_device_inventory(void) if (pa_serialize_tlb_flushes) pr_info("Merced bus found: Enable PxTLB serialization.\n"); #endif + +#if defined(CONFIG_FW_CFG_SYSFS) + if (running_on_qemu) { + struct resource res[3] = {0,}; + unsigned int base; + + base = ((unsigned long long) PAGE0->pad0[2] << 32) + | PAGE0->pad0[3]; /* SeaBIOS stored it here */ + + res[0].name = "fw_cfg"; + res[0].start = base; + res[0].end = base + 8 - 1; + res[0].flags = IORESOURCE_MEM; + + res[1].name = "ctrl"; + res[1].start = 0; + res[1].flags = IORESOURCE_REG; + + res[2].name = "data"; + res[2].start = 4; + res[2].flags = IORESOURCE_REG; + + if (base) { + pr_info("Found qemu fw_cfg interface at %#08x\n", base); + platform_device_register_simple("fw_cfg", + PLATFORM_DEVID_NONE, res, 3); + } + } +#endif } From f4d0d40cd1f19104e4f60537973ff5ac2f90123e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 14 Aug 2020 15:14:12 +0200 Subject: [PATCH 72/88] parisc: Avoid external interrupts when IPI finishes No need to allow external interrupts when the IPI loop is going to finish now. Signed-off-by: Helge Deller --- arch/parisc/kernel/smp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 6271139d2213..10227f667c8a 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -173,9 +173,12 @@ ipi_interrupt(int irq, void *dev_id) this_cpu, which); return IRQ_NONE; } /* Switch */ - /* let in any pending interrupts */ - local_irq_enable(); - local_irq_disable(); + + /* before doing more, let in any pending interrupts */ + if (ops) { + local_irq_enable(); + local_irq_disable(); + } } /* while (ops) */ } return IRQ_HANDLED; From 41f5a81c07cd410917c9ae3c165b9b761d48ba75 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 13:57:07 +0200 Subject: [PATCH 73/88] parisc: Drop HP-UX specific fcntl and signal flags Those flags are nowhere used in the Linux kernel and were added when we still wanted to support HP-UX in a compat mode. Since we never will support HP-UX, drop those flags. Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/fcntl.h | 5 +---- arch/parisc/include/uapi/asm/signal.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 03ce20e5ad7d..e19adc65b1d0 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -3,7 +3,6 @@ #define _PARISC_FCNTL_H #define O_APPEND 000000010 -#define O_BLKSEEK 000000100 /* HPUX only */ #define O_CREAT 000000400 /* not fcntl */ #define O_EXCL 000002000 /* not fcntl */ #define O_LARGEFILE 000004000 @@ -11,14 +10,12 @@ #define O_SYNC (__O_SYNC|O_DSYNC) #define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ #define O_NOCTTY 000400000 /* not fcntl */ -#define O_DSYNC 001000000 /* HPUX only */ -#define O_RSYNC 002000000 /* HPUX only */ +#define O_DSYNC 001000000 #define O_NOATIME 004000000 #define O_CLOEXEC 010000000 /* set close_on_exec */ #define O_DIRECTORY 000010000 /* must be a directory */ #define O_NOFOLLOW 000000200 /* don't follow links */ -#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ #define O_PATH 020000000 #define __O_TMPFILE 040000000 diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index d38563a394f2..045fde6d2fac 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -61,7 +61,6 @@ #define SA_NODEFER 0x00000020 #define SA_RESTART 0x00000040 #define SA_NOCLDWAIT 0x00000080 -#define _SA_SIGGFAULT 0x00000100 /* HPUX */ #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND From 75ae04206a4d0e4f541c1d692b7febd1c0fdb814 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 14:11:35 +0200 Subject: [PATCH 74/88] parisc: Define O_NONBLOCK to become 000200000 HPUX has separate NDELAY & NONBLOCK values. In the past we wanted to be able to run HP-UX binaries natively on parisc Linux which is why we defined O_NONBLOCK to 000200004 to distinguish NDELAY & NONBLOCK bits. But with 2 bits set in this bitmask we often ran into compatibility issues with other Linux applications which often only test one bit (or even compare the values). To avoid such issues in the future, this patch changes O_NONBLOCK to become 000200000. That way old programs will still be functional, and for new programs we now have only one bit set. Update the comment about SOCK_NONBLOCK too. Signed-off-by: Helge Deller --- arch/parisc/include/asm/socket.h | 4 ++-- arch/parisc/include/uapi/asm/fcntl.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h index 79feff1b0721..33500c9f6e5e 100644 --- a/arch/parisc/include/asm/socket.h +++ b/arch/parisc/include/asm/socket.h @@ -4,8 +4,8 @@ #include -/* O_NONBLOCK clashes with the bits used for socket types. Therefore we - * have to define SOCK_NONBLOCK to a different value here. +/* O_NONBLOCK clashed with the bits used for socket types. Therefore we + * had to define SOCK_NONBLOCK to a different value here. */ #define SOCK_NONBLOCK 0x40000000 diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index e19adc65b1d0..03dee816cb13 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -8,7 +8,7 @@ #define O_LARGEFILE 000004000 #define __O_SYNC 000100000 #define O_SYNC (__O_SYNC|O_DSYNC) -#define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ +#define O_NONBLOCK 000200000 #define O_NOCTTY 000400000 /* not fcntl */ #define O_DSYNC 001000000 #define O_NOATIME 004000000 From cd760704ee32a762029c08ca0702228c34846ffb Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 18:07:49 +0200 Subject: [PATCH 75/88] parisc: Drop useless comments in uapi/asm/signal.h Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/signal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index 045fde6d2fac..e605197b462c 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -35,11 +35,11 @@ #define SIGURG 29 #define SIGXFSZ 30 #define SIGUNUSED 31 -#define SIGSYS 31 /* Linux doesn't use this */ +#define SIGSYS 31 /* These should not be considered constants from userland. */ #define SIGRTMIN 32 -#define SIGRTMAX _NSIG /* it's 44 under HP/UX */ +#define SIGRTMAX _NSIG /* * SA_FLAGS values: From 0b5d9a063f67e9f77edb7d372eab82f33bf6b407 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 11 Sep 2020 12:27:46 +0200 Subject: [PATCH 76/88] parisc: disable CONFIG_IDE in defconfigs Enable libata support for the Nat Semi NS87415 controller, and disable the soon to be removed legacy ide driver entirely. Signed-off-by: Christoph Hellwig Acked-by: Helge Deller Signed-off-by: Helge Deller --- arch/parisc/configs/generic-32bit_defconfig | 6 ++---- arch/parisc/configs/generic-64bit_defconfig | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 61bac8ff8f22..3cbcfad5f724 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -52,10 +52,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=6144 -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y @@ -65,6 +61,8 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_ZALON=y CONFIG_SCSI_DH=y CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_NS87415=y CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 59561e04e659..7e2d7026285e 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -58,11 +58,6 @@ CONFIG_PCI_IOV=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_LOOP=y -CONFIG_IDE=y -CONFIG_IDE_GD=m -CONFIG_IDE_GD_ATAPI=y -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_NS87415=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y @@ -76,6 +71,7 @@ CONFIG_SCSI_ZALON=y CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_DH=y CONFIG_ATA=y +CONFIG_PATA_NS87415=y CONFIG_PATA_SIL680=y CONFIG_ATA_GENERIC=y CONFIG_MD=y From f15309d7ad5d12603941ef213ead0e7ebe6e8943 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 30 Sep 2020 17:24:47 +0200 Subject: [PATCH 77/88] parisc: Add ioread64_hi_lo() and iowrite64_hi_lo() The kernel test robot reports missing functions. Add them. hppa-linux-ld: drivers/firmware/arm_scmi/perf.o: in function `scmi_perf_fc_ring_db': (.text+0x610): undefined reference to `ioread64_hi_lo' (.text+0x63c): undefined reference to `iowrite64_hi_lo' Reported-by: kernel test robot Signed-off-by: Helge Deller --- arch/parisc/lib/iomap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c index ce400417d54e..f03adb1999e7 100644 --- a/arch/parisc/lib/iomap.c +++ b/arch/parisc/lib/iomap.c @@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr) return *((u64 *)addr); } +u64 ioread64_hi_lo(const void __iomem *addr) +{ + u32 low, high; + + high = ioread32(addr + sizeof(u32)); + low = ioread32(addr); + + return low + ((u64)high << 32); +} + void iowrite8(u8 datum, void __iomem *addr) { if (unlikely(INDIRECT_ADDR(addr))) { @@ -409,6 +419,12 @@ void iowrite64be(u64 datum, void __iomem *addr) } } +void iowrite64_hi_lo(u64 val, void __iomem *addr) +{ + iowrite32(val >> 32, addr + sizeof(u32)); + iowrite32(val, addr); +} + /* Repeating interfaces */ void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) @@ -511,6 +527,7 @@ EXPORT_SYMBOL(ioread32); EXPORT_SYMBOL(ioread32be); EXPORT_SYMBOL(ioread64); EXPORT_SYMBOL(ioread64be); +EXPORT_SYMBOL(ioread64_hi_lo); EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite16); EXPORT_SYMBOL(iowrite16be); @@ -518,6 +535,7 @@ EXPORT_SYMBOL(iowrite32); EXPORT_SYMBOL(iowrite32be); EXPORT_SYMBOL(iowrite64); EXPORT_SYMBOL(iowrite64be); +EXPORT_SYMBOL(iowrite64_hi_lo); EXPORT_SYMBOL(ioread8_rep); EXPORT_SYMBOL(ioread16_rep); EXPORT_SYMBOL(ioread32_rep); From 6caf55e570efe53f161bf9af64f22b310e86032e Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 19:55:04 +0200 Subject: [PATCH 78/88] parisc: Add alternative patching to synchronize_caches define This change allows the sync barrier instruction to be patched to a nop. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/barrier.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h index 640d46edf32e..c705decf2bed 100644 --- a/arch/parisc/include/asm/barrier.h +++ b/arch/parisc/include/asm/barrier.h @@ -2,11 +2,15 @@ #ifndef __ASM_BARRIER_H #define __ASM_BARRIER_H +#include + #ifndef __ASSEMBLY__ /* The synchronize caches instruction executes as a nop on systems in which all memory references are performed in order. */ -#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory") +#define synchronize_caches() asm volatile("sync" \ + ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \ + : : : "memory") #if defined(CONFIG_SMP) #define mb() do { synchronize_caches(); } while (0) From 4df82ce78a34b8f94f3a512ef93972f978713cbc Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 20:03:27 +0200 Subject: [PATCH 79/88] parisc: Fix comments and enable interrupts later Correct the comments: The jump is forwards, not backwards. Enable the interrupts after %r29 (reference param area) was loaded. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/entry.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 519f9056fd00..f6f28e41bb5e 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -899,20 +899,20 @@ intr_check_sig: * Only do signals if we are returning to user space */ LDREG PT_IASQ0(%r16), %r20 - cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ + cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */ LDREG PT_IASQ1(%r16), %r20 - cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ - - /* NOTE: We need to enable interrupts if we have to deliver - * signals. We used to do this earlier but it caused kernel - * stack overflows. */ - ssm PSW_SM_I, %r0 + cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */ copy %r0, %r25 /* long in_syscall = 0 */ #ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif + /* NOTE: We need to enable interrupts if we have to deliver + * signals. We used to do this earlier but it caused kernel + * stack overflows. */ + ssm PSW_SM_I, %r0 + BL do_notify_resume,%r2 copy %r16, %r26 /* struct pt_regs *regs */ From 2a7d4eed5720d163f50b26892abe45b8cf40e849 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:16:49 +0200 Subject: [PATCH 80/88] parisc: Mark pointers volatile in __xchg8(), __xchg32() and __xchg64() Let the complier treat the pointers volatile to ensure that they get accessed atomicly. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/cmpxchg.h | 14 +++++++------- arch/parisc/lib/bitops.c | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h index 068958575871..cf5ee9b0b393 100644 --- a/arch/parisc/include/asm/cmpxchg.h +++ b/arch/parisc/include/asm/cmpxchg.h @@ -14,22 +14,22 @@ extern void __xchg_called_with_bad_pointer(void); /* __xchg32/64 defined in arch/parisc/lib/bitops.c */ -extern unsigned long __xchg8(char, char *); -extern unsigned long __xchg32(int, int *); +extern unsigned long __xchg8(char, volatile char *); +extern unsigned long __xchg32(int, volatile int *); #ifdef CONFIG_64BIT -extern unsigned long __xchg64(unsigned long, unsigned long *); +extern unsigned long __xchg64(unsigned long, volatile unsigned long *); #endif /* optimizer better get rid of switch since size is a constant */ static inline unsigned long -__xchg(unsigned long x, __volatile__ void *ptr, int size) +__xchg(unsigned long x, volatile void *ptr, int size) { switch (size) { #ifdef CONFIG_64BIT - case 8: return __xchg64(x, (unsigned long *) ptr); + case 8: return __xchg64(x, (volatile unsigned long *) ptr); #endif - case 4: return __xchg32((int) x, (int *) ptr); - case 1: return __xchg8((char) x, (char *) ptr); + case 4: return __xchg32((int) x, (volatile int *) ptr); + case 1: return __xchg8((char) x, (volatile char *) ptr); } __xchg_called_with_bad_pointer(); return x; diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index 2e4d1f05a926..9ac683bf6ae7 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { #endif #ifdef CONFIG_64BIT -unsigned long __xchg64(unsigned long x, unsigned long *ptr) +unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr) { unsigned long temp, flags; @@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, unsigned long *ptr) } #endif -unsigned long __xchg32(int x, int *ptr) +unsigned long __xchg32(int x, volatile int *ptr) { unsigned long flags; long temp; @@ -43,7 +43,7 @@ unsigned long __xchg32(int x, int *ptr) } -unsigned long __xchg8(char x, char *ptr) +unsigned long __xchg8(char x, volatile char *ptr) { unsigned long flags; long temp; From 53a42b6324b8ddce1e9d2f34da2ca68ef21c2084 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:21:41 +0200 Subject: [PATCH 81/88] parisc: Switch to more fine grained lws locks Increase the number of lws locks to 256 entries (instead of 16) and choose lock entry based on bits 3-11 (instead of 4-7) of the relevant address. With this change we archieve more fine-grained locking in futex syscalls and thus reduce the number of possible stalls. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/futex.h | 4 ++-- arch/parisc/kernel/syscall.S | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index c459f656c8c3..fceb9cf02fb3 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -16,7 +16,7 @@ static inline void _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) { extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; + long index = ((long)uaddr & 0x3f8) >> 1; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; local_irq_save(*flags); arch_spin_lock(s); @@ -26,7 +26,7 @@ static inline void _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) { extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; + long index = ((long)uaddr & 0x3f8) >> 1; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spin_unlock(s); local_irq_restore(*flags); diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 3ad61a177f5b..322503780db6 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -571,8 +571,8 @@ lws_compare_and_swap: ldil L%lws_lock_start, %r20 ldo R%lws_lock_start(%r20), %r28 - /* Extract four bits from r26 and hash lock (Bits 4-7) */ - extru %r26, 27, 4, %r20 + /* Extract eight bits from r26 and hash lock (Bits 3-11) */ + extru %r26, 28, 8, %r20 /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) @@ -761,8 +761,8 @@ cas2_lock_start: ldil L%lws_lock_start, %r20 ldo R%lws_lock_start(%r20), %r28 - /* Extract four bits from r26 and hash lock (Bits 4-7) */ - extru %r26, 27, 4, %r20 + /* Extract eight bits from r26 and hash lock (Bits 3-11) */ + extru %r26, 28, 8, %r20 /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) @@ -950,7 +950,7 @@ END(sys_call_table64) .align L1_CACHE_BYTES ENTRY(lws_lock_start) /* lws locks */ - .rept 16 + .rept 256 /* Keep locks aligned at 16-bytes */ .word 1 .word 0 From a50d3d3ce0235fdc06cdb5cc2fb082964ecb56da Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:28:31 +0200 Subject: [PATCH 82/88] parisc: Rewrite tlb flush threshold calculation Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/cache.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index b5e1d9f1b440..86a1a63563fd 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -383,12 +383,12 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm); static unsigned long parisc_cache_flush_threshold __ro_after_init = FLUSH_THRESHOLD; #define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */ -static unsigned long parisc_tlb_flush_threshold __ro_after_init = FLUSH_TLB_THRESHOLD; +static unsigned long parisc_tlb_flush_threshold __ro_after_init = ~0UL; void __init parisc_setup_cache_timing(void) { unsigned long rangetime, alltime; - unsigned long size, start; + unsigned long size; unsigned long threshold; alltime = mfctl(16); @@ -422,14 +422,9 @@ void __init parisc_setup_cache_timing(void) goto set_tlb_threshold; } - size = 0; - start = (unsigned long) _text; + size = (unsigned long)_end - (unsigned long)_text; rangetime = mfctl(16); - while (start < (unsigned long) _end) { - flush_tlb_kernel_range(start, start + PAGE_SIZE); - start += PAGE_SIZE; - size += PAGE_SIZE; - } + flush_tlb_kernel_range((unsigned long)_text, (unsigned long)_end); rangetime = mfctl(16) - rangetime; alltime = mfctl(16); @@ -444,8 +439,11 @@ void __init parisc_setup_cache_timing(void) threshold/1024); set_tlb_threshold: - if (threshold > parisc_tlb_flush_threshold) + if (threshold > FLUSH_TLB_THRESHOLD) parisc_tlb_flush_threshold = threshold; + else + parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD; + printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", parisc_tlb_flush_threshold/1024); } From b47cf497469fae14fcbf63526150c8c71e636c20 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 2 Oct 2020 21:32:39 +0200 Subject: [PATCH 83/88] parisc: Install vmlinuz instead of zImage file Tested-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh index 6f68784fea25..056d588befdd 100644 --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh @@ -43,7 +43,7 @@ fi # Default install -if [ "$(basename $2)" = "zImage" ]; then +if [ "$(basename $2)" = "vmlinuz" ]; then # Compressed install echo "Installing compressed kernel" base=vmlinuz From f173e3a751708b7f5e0b77dcdd4ac3c2287b735e Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:41:52 +0200 Subject: [PATCH 84/88] parisc: Improve spinlock handling Use READ_ONCE() to check if spinlock is locked. The other changes are cleanups. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/spinlock.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 51b6c47f802f..fa5ee8a45dbd 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -10,13 +10,21 @@ static inline int arch_spin_is_locked(arch_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); - return *a == 0; + return READ_ONCE(*a) == 0; } -#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) +static inline void arch_spin_lock(arch_spinlock_t *x) +{ + volatile unsigned int *a; + + a = __ldcw_align(x); + while (__ldcw(a) == 0) + while (*a == 0) + continue; +} static inline void arch_spin_lock_flags(arch_spinlock_t *x, - unsigned long flags) + unsigned long flags) { volatile unsigned int *a; @@ -25,10 +33,8 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x, while (*a == 0) if (flags & PSW_SM_I) { local_irq_enable(); - cpu_relax(); local_irq_disable(); - } else - cpu_relax(); + } } #define arch_spin_lock_flags arch_spin_lock_flags @@ -44,12 +50,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *x) static inline int arch_spin_trylock(arch_spinlock_t *x) { volatile unsigned int *a; - int ret; a = __ldcw_align(x); - ret = __ldcw(a) != 0; - - return ret; + return __ldcw(a) != 0; } /* From 4a770b413fe91d5d271e29a50a1f23cf189b4d2e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Oct 2020 08:50:51 +0200 Subject: [PATCH 85/88] parisc: Add MAP_UNINITIALIZED define We will not allow unitialized anon mmaps, but we need this define to prevent build errors, e.g. the debian foot package. Suggested-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/mman.h | 1 + tools/arch/parisc/include/uapi/asm/mman.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h index 6fd8871e4081..ab78cba446ed 100644 --- a/arch/parisc/include/uapi/asm/mman.h +++ b/arch/parisc/include/uapi/asm/mman.h @@ -25,6 +25,7 @@ #define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */ #define MAP_HUGETLB 0x80000 /* create a huge page mapping */ #define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */ +#define MAP_UNINITIALIZED 0 /* uninitialized anonymous mmap */ #define MS_SYNC 1 /* synchronous memory sync */ #define MS_ASYNC 2 /* sync memory asynchronously */ diff --git a/tools/arch/parisc/include/uapi/asm/mman.h b/tools/arch/parisc/include/uapi/asm/mman.h index f9fd1325f5bd..506c06a6536f 100644 --- a/tools/arch/parisc/include/uapi/asm/mman.h +++ b/tools/arch/parisc/include/uapi/asm/mman.h @@ -39,6 +39,5 @@ #define MADV_SOFT_OFFLINE 101 /* MAP_32BIT is undefined on parisc, fix it for perf */ #define MAP_32BIT 0 -/* MAP_UNINITIALIZED is undefined on parisc, fix it for perf */ #define MAP_UNINITIALIZED 0 #endif From 58a5c67aadde68d0d31c36adbabdec28c25bb6ab Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Oct 2020 09:05:09 +0200 Subject: [PATCH 86/88] parisc/sticon: Always register sticon console driver If the ROM provides functional STI routines, always register the sticon driver, even if the serial console was choosen as boot device. Additionally, in that case, do not make the sticon driver the default output console device. Signed-off-by: Helge Deller --- drivers/video/console/sticon.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index e7fd995d3aea..7c1dcd526600 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -348,14 +348,13 @@ static int __init sticonsole_init(void) if (!sticon_sti) return -ENODEV; - if (conswitchp == &dummy_con) { - printk(KERN_INFO "sticon: Initializing STI text console.\n"); - console_lock(); - err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1); - console_unlock(); - return err; - } - return 0; + pr_info("sticon: Initializing STI text console.\n"); + console_lock(); + err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, + PAGE0->mem_cons.cl_class != CL_DUPLEX); + console_unlock(); + + return err; } module_init(sticonsole_init); From 7ff3f14ddc355bfbc94c766f43b90606b1f79e83 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Oct 2020 10:44:52 +0200 Subject: [PATCH 87/88] parisc/sticon: Add user font support This is a major rework of the sticon (parisc text console) driver in order to support user font support. Usually one want to use the stifb (parisc framebuffer driver) which is based on fbcon and does support fonts and colors, but some old machines (e.g. HP 730 workstations) don't provide a supported stifb graphic card, and for those user fonts are preferred. This patch drops unused code for software cursor and scrollback, enhances the debug output and adds better documentation. The code was tested on various machines with byte-mode and word-mode graphic cards on GSC- and PCI-busses. Signed-off-by: Helge Deller --- drivers/video/console/Kconfig | 1 + drivers/video/console/sticon.c | 282 ++++++++++++++++++------------- drivers/video/console/sticore.c | 284 +++++++++++++++++--------------- drivers/video/fbdev/sticore.h | 27 ++- 4 files changed, 326 insertions(+), 268 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 39deb22a4180..ee33b8ec62bb 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -119,6 +119,7 @@ config STI_CONSOLE bool "STI text console" depends on PARISC && HAS_IOMEM select FONT_SUPPORT + select CRC32 default y help The STI console is the builtin display/keyboard on HP-PARISC diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 7c1dcd526600..1b451165311c 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -2,7 +2,7 @@ * linux/drivers/video/console/sticon.c - console driver using HP's STI firmware * * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002 Helge Deller + * Copyright (C) 2002-2020 Helge Deller * * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c, * which were @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include #include @@ -52,28 +55,16 @@ #define BLANK 0 static int vga_is_gfx; +#define STI_DEF_FONT sticon_sti->font + +/* borrowed from fbcon.c */ +#define FNTREFCOUNT(fd) (fd->refcount) +#define FNTCRC(fd) (fd->crc) +static struct sti_cooked_font *font_data[MAX_NR_CONSOLES]; + /* this is the sti_struct used for this console */ static struct sti_struct *sticon_sti; -/* Software scrollback */ -static unsigned long softback_buf, softback_curr; -static unsigned long softback_in; -static unsigned long /* softback_top, */ softback_end; -static int softback_lines; - -/* software cursor */ -static int cursor_drawn; -#define CURSOR_DRAW_DELAY (1) -#define DEFAULT_CURSOR_BLINK_RATE (20) - -static int vbl_cursor_cnt; - -static inline void cursor_undrawn(void) -{ - vbl_cursor_cnt = 0; - cursor_drawn = 0; -} - static const char *sticon_startup(void) { return "STI console"; @@ -81,61 +72,43 @@ static const char *sticon_startup(void) static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) { - int redraw_cursor = 0; - if (vga_is_gfx || console_blanked) return; if (conp->vc_mode != KD_TEXT) return; -#if 0 - if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) { - cursor_undrawn(); - redraw_cursor = 1; - } -#endif - sti_putc(sticon_sti, c, ypos, xpos); - - if (redraw_cursor) - vbl_cursor_cnt = CURSOR_DRAW_DELAY; + sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]); } static void sticon_putcs(struct vc_data *conp, const unsigned short *s, int count, int ypos, int xpos) { - int redraw_cursor = 0; - if (vga_is_gfx || console_blanked) return; if (conp->vc_mode != KD_TEXT) return; -#if 0 - if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) && - (p->cursor_x < (xpos + count))) { - cursor_undrawn(); - redraw_cursor = 1; - } -#endif - while (count--) { - sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++); + sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++, + font_data[conp->vc_num]); } - - if (redraw_cursor) - vbl_cursor_cnt = CURSOR_DRAW_DELAY; } static void sticon_cursor(struct vc_data *conp, int mode) { unsigned short car1; + /* no cursor update if screen is blanked */ + if (vga_is_gfx || console_blanked) + return; + car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols]; switch (mode) { case CM_ERASE: - sti_putc(sticon_sti, car1, conp->state.y, conp->state.x); + sti_putc(sticon_sti, car1, conp->state.y, conp->state.x, + font_data[conp->vc_num]); break; case CM_MOVE: case CM_DRAW: @@ -146,7 +119,7 @@ static void sticon_cursor(struct vc_data *conp, int mode) case CUR_TWO_THIRDS: case CUR_BLOCK: sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), - conp->state.y, conp->state.x); + conp->state.y, conp->state.x, font_data[conp->vc_num]); break; } break; @@ -165,42 +138,164 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t, switch (dir) { case SM_UP: - sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); - sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); + sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols, + font_data[conp->vc_num]); + sti_clear(sti, b - count, 0, count, conp->vc_cols, + conp->vc_video_erase_char, font_data[conp->vc_num]); break; case SM_DOWN: - sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); - sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); + sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols, + font_data[conp->vc_num]); + sti_clear(sti, t, 0, count, conp->vc_cols, + conp->vc_video_erase_char, font_data[conp->vc_num]); break; } return false; } +static int sticon_set_def_font(int unit, struct console_font *op) +{ + if (font_data[unit] != STI_DEF_FONT) { + if (--FNTREFCOUNT(font_data[unit]) == 0) { + kfree(font_data[unit]->raw_ptr); + kfree(font_data[unit]); + } + font_data[unit] = STI_DEF_FONT; + } + + return 0; +} + +static int sticon_set_font(struct vc_data *vc, struct console_font *op) +{ + struct sti_struct *sti = sticon_sti; + int vc_cols, vc_rows, vc_old_cols, vc_old_rows; + int unit = vc->vc_num; + int w = op->width; + int h = op->height; + int size, i, bpc, pitch; + struct sti_rom_font *new_font; + struct sti_cooked_font *cooked_font; + unsigned char *data = op->data, *p; + + if ((w < 6) || (h < 6) || (w > 32) || (h > 32) + || (op->charcount != 256 && op->charcount != 512)) + return -EINVAL; + pitch = ALIGN(w, 8) / 8; + bpc = pitch * h; + size = bpc * op->charcount; + + new_font = kmalloc(sizeof(*new_font) + size, STI_LOWMEM); + if (!new_font) + return -ENOMEM; + + new_font->first_char = 0; + new_font->last_char = op->charcount - 1; + new_font->width = w; + new_font->height = h; + new_font->font_type = STI_FONT_HPROMAN8; + new_font->bytes_per_char = bpc; + new_font->underline_height = 0; + new_font->underline_pos = 0; + + cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); + if (!cooked_font) { + kfree(new_font); + return -ENOMEM; + } + cooked_font->raw = new_font; + cooked_font->raw_ptr = new_font; + cooked_font->width = w; + cooked_font->height = h; + FNTREFCOUNT(cooked_font) = 0; /* usage counter */ + + p = (unsigned char *) new_font; + p += sizeof(*new_font); + for (i = 0; i < op->charcount; i++) { + memcpy(p, data, bpc); + data += pitch*32; + p += bpc; + } + FNTCRC(cooked_font) = crc32(0, new_font, size + sizeof(*new_font)); + sti_font_convert_bytemode(sti, cooked_font); + new_font = cooked_font->raw_ptr; + + /* check if font is already used by other console */ + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (font_data[i] != STI_DEF_FONT + && (FNTCRC(font_data[i]) == FNTCRC(cooked_font))) { + kfree(new_font); + kfree(cooked_font); + /* current font is the same as the new one */ + if (i == unit) + return 0; + cooked_font = font_data[i]; + new_font = cooked_font->raw_ptr; + break; + } + } + + /* clear screen with old font: we now may have less rows */ + vc_old_rows = vc->vc_rows; + vc_old_cols = vc->vc_cols; + sti_clear(sticon_sti, 0, 0, vc_old_rows, vc_old_cols, + vc->vc_video_erase_char, font_data[vc->vc_num]); + + /* delete old font in case it is a user font */ + sticon_set_def_font(unit, NULL); + + FNTREFCOUNT(cooked_font)++; + font_data[unit] = cooked_font; + + vc_cols = sti_onscreen_x(sti) / cooked_font->width; + vc_rows = sti_onscreen_y(sti) / cooked_font->height; + vc_resize(vc, vc_cols, vc_rows); + + /* need to repaint screen if cols & rows are same as old font */ + if (vc_cols == vc_old_cols && vc_rows == vc_old_rows) + update_screen(vc); + + return 0; +} + +static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name) +{ + return sticon_set_def_font(vc->vc_num, op); +} + +static int sticon_font_set(struct vc_data *vc, struct console_font *font, + unsigned int flags) +{ + return sticon_set_font(vc, font); +} + static void sticon_init(struct vc_data *c, int init) { struct sti_struct *sti = sticon_sti; int vc_cols, vc_rows; sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0); - vc_cols = sti_onscreen_x(sti) / sti->font_width; - vc_rows = sti_onscreen_y(sti) / sti->font_height; + vc_cols = sti_onscreen_x(sti) / sti->font->width; + vc_rows = sti_onscreen_y(sti) / sti->font->height; c->vc_can_do_color = 1; if (init) { c->vc_cols = vc_cols; c->vc_rows = vc_rows; } else { - /* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */ - /* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */ vc_resize(c, vc_cols, vc_rows); -/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */ } } static void sticon_deinit(struct vc_data *c) { + int i; + + /* free memory used by user font */ + for (i = 0; i < MAX_NR_CONSOLES; i++) + sticon_set_def_font(i, NULL); } static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, @@ -209,7 +304,8 @@ static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, if (!height || !width) return; - sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char); + sti_clear(sticon_sti, sy, sx, height, width, + conp->vc_video_erase_char, font_data[conp->vc_num]); } static int sticon_switch(struct vc_data *conp) @@ -224,64 +320,13 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch) vga_is_gfx = 0; return 1; } - sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK); + sti_clear(sticon_sti, 0, 0, c->vc_rows, c->vc_cols, BLANK, + font_data[c->vc_num]); if (mode_switch) vga_is_gfx = 1; return 1; } -static u16 *sticon_screen_pos(const struct vc_data *conp, int offset) -{ - int line; - unsigned long p; - - if (conp->vc_num != fg_console || !softback_lines) - return (u16 *)(conp->vc_origin + offset); - line = offset / conp->vc_size_row; - if (line >= softback_lines) - return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row); - p = softback_curr + offset; - if (p >= softback_end) - p += softback_buf - softback_end; - return (u16 *)p; -} - -static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, - int *px, int *py) -{ - int x, y; - unsigned long ret; - if (pos >= conp->vc_origin && pos < conp->vc_scr_end) { - unsigned long offset = (pos - conp->vc_origin) / 2; - - x = offset % conp->vc_cols; - y = offset / conp->vc_cols; - if (conp->vc_num == fg_console) - y += softback_lines; - ret = pos + (conp->vc_cols - x) * 2; - } else if (conp->vc_num == fg_console && softback_lines) { - unsigned long offset = pos - softback_curr; - - if (pos < softback_curr) - offset += softback_end - softback_buf; - offset /= 2; - x = offset % conp->vc_cols; - y = offset / conp->vc_cols; - ret = pos + (conp->vc_cols - x) * 2; - if (ret == softback_end) - ret = softback_buf; - if (ret == softback_in) - ret = conp->vc_origin; - } else { - /* Should not happen */ - x = y = 0; - ret = conp->vc_origin; - } - if (px) *px = x; - if (py) *py = y; - return ret; -} - static u8 sticon_build_attr(struct vc_data *conp, u8 color, enum vc_intensity intens, bool blink, bool underline, bool reverse, @@ -312,10 +357,6 @@ static void sticon_invert_region(struct vc_data *conp, u16 *p, int count) } } -static void sticon_save_screen(struct vc_data *conp) -{ -} - static const struct consw sti_con = { .owner = THIS_MODULE, .con_startup = sticon_startup, @@ -328,18 +369,18 @@ static const struct consw sti_con = { .con_scroll = sticon_scroll, .con_switch = sticon_switch, .con_blank = sticon_blank, - .con_save_screen = sticon_save_screen, + .con_font_set = sticon_font_set, + .con_font_default = sticon_font_default, .con_build_attr = sticon_build_attr, .con_invert_region = sticon_invert_region, - .con_screen_pos = sticon_screen_pos, - .con_getxy = sticon_getxy, }; static int __init sticonsole_init(void) { - int err; + int err, i; + /* already initialized ? */ if (sticon_sti) return 0; @@ -348,6 +389,9 @@ static int __init sticonsole_init(void) if (!sticon_sti) return -ENODEV; + for (i = 0; i < MAX_NR_CONSOLES; i++) + font_data[i] = STI_DEF_FONT; + pr_info("sticon: Initializing STI text console.\n"); console_lock(); err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 84c3ca37040a..6a26a364f9bd 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -4,7 +4,7 @@ * core code for console driver using HP's STI firmware * * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2001-2013 Helge Deller + * Copyright (C) 2001-2020 Helge Deller * Copyright (C) 2001-2002 Thomas Bogendoerfer * * TODO: @@ -14,6 +14,8 @@ * */ +#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME + #include #include #include @@ -133,16 +135,17 @@ static const struct sti_font_flags default_font_flags = { }; void -sti_putc(struct sti_struct *sti, int c, int y, int x) +sti_putc(struct sti_struct *sti, int c, int y, int x, + struct sti_cooked_font *font) { struct sti_font_inptr *inptr = &sti->sti_data->font_inptr; struct sti_font_inptr inptr_default = { - .font_start_addr= STI_PTR(sti->font->raw), + .font_start_addr = STI_PTR(font->raw), .index = c_index(sti, c), .fg_color = c_fg(sti, c), .bg_color = c_bg(sti, c), - .dest_x = x * sti->font_width, - .dest_y = y * sti->font_height, + .dest_x = x * font->width, + .dest_y = y * font->height, }; struct sti_font_outptr *outptr = &sti->sti_data->font_outptr; s32 ret; @@ -193,18 +196,18 @@ sti_set(struct sti_struct *sti, int src_y, int src_x, void sti_clear(struct sti_struct *sti, int src_y, int src_x, - int height, int width, int c) + int height, int width, int c, struct sti_cooked_font *font) { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; struct sti_blkmv_inptr inptr_default = { .fg_color = c_fg(sti, c), .bg_color = c_bg(sti, c), - .src_x = src_x * sti->font_width, - .src_y = src_y * sti->font_height, - .dest_x = src_x * sti->font_width, - .dest_y = src_y * sti->font_height, - .width = width * sti->font_width, - .height = height* sti->font_height, + .src_x = src_x * font->width, + .src_y = src_y * font->height, + .dest_x = src_x * font->width, + .dest_y = src_y * font->height, + .width = width * font->width, + .height = height * font->height, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; @@ -225,16 +228,17 @@ static const struct sti_blkmv_flags default_blkmv_flags = { void sti_bmove(struct sti_struct *sti, int src_y, int src_x, - int dst_y, int dst_x, int height, int width) + int dst_y, int dst_x, int height, int width, + struct sti_cooked_font *font) { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; struct sti_blkmv_inptr inptr_default = { - .src_x = src_x * sti->font_width, - .src_y = src_y * sti->font_height, - .dest_x = dst_x * sti->font_width, - .dest_y = dst_y * sti->font_height, - .width = width * sti->font_width, - .height = height* sti->font_height, + .src_x = src_x * font->width, + .src_y = src_y * font->height, + .dest_x = dst_x * font->width, + .dest_y = dst_y * font->height, + .width = width * font->width, + .height = height * font->height, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; @@ -301,36 +305,32 @@ __setup("sti=", sti_setup); -static char *font_name[MAX_STI_ROMS]; -static int font_index[MAX_STI_ROMS], - font_height[MAX_STI_ROMS], - font_width[MAX_STI_ROMS]; +static char *font_name; +static int font_index, + font_height, + font_width; #ifndef MODULE static int sti_font_setup(char *str) { - char *x; - int i = 0; + /* + * The default font can be selected in various ways. + * a) sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 selects + * an built-in Linux framebuffer font. + * b) sti_font=, where index is (1..x) with 1 selecting + * the first HP STI ROM built-in font.. + */ - /* we accept sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 - * or sti_font=7 style command lines. */ + if (*str >= '0' && *str <= '9') { + char *x; - while (i='0' && *str<='9') { - if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) { - font_height[i] = simple_strtoul(str, NULL, 0); - font_width[i] = simple_strtoul(x+1, NULL, 0); - } else { - font_index[i] = simple_strtoul(str, NULL, 0); - } + if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) { + font_height = simple_strtoul(str, NULL, 0); + font_width = simple_strtoul(x+1, NULL, 0); } else { - font_name[i] = str; /* fb font name */ + font_index = simple_strtoul(str, NULL, 0); } - - if ((x = strchr(str, ','))) - *x++ = 0; - str = x; - - i++; + } else { + font_name = str; /* fb font name */ } return 1; @@ -344,7 +344,7 @@ static int sti_font_setup(char *str) * framebuffer font names (e.g. VGA8x16, SUN22x18). * This is only available if the fonts have been statically compiled * in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options. - * - sti_font= + * - sti_font= ( = 1,2,3,...) * most STI ROMs have built-in HP specific fonts, which can be selected * by giving the desired number to the sticon driver. * NOTE: This number is machine and STI ROM dependend. @@ -364,8 +364,7 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, { struct sti_glob_cfg_ext *cfg; - DPRINTK((KERN_INFO - "%d text planes\n" + pr_debug("%d text planes\n" "%4d x %4d screen resolution\n" "%4d x %4d offscreen\n" "%4d x %4d layout\n" @@ -382,12 +381,11 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5], glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7], glob_cfg->reent_lvl, - glob_cfg->save_addr)); + glob_cfg->save_addr); /* dump extended cfg */ cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr); - DPRINTK(( KERN_INFO - "monitor %d\n" + pr_debug("monitor %d\n" "in friendly mode: %d\n" "power consumption %d watts\n" "freq ref %d\n" @@ -396,20 +394,19 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, cfg->friendly_boot, cfg->power, cfg->freq_ref, - cfg->sti_mem_addr, sti_mem_request)); + cfg->sti_mem_addr, sti_mem_request); } static void sti_dump_outptr(struct sti_struct *sti) { - DPRINTK((KERN_INFO - "%d bits per pixel\n" + pr_debug("%d bits per pixel\n" "%d used bits\n" "%d planes\n" "attributes %08x\n", sti->sti_data->inq_outptr.bits_per_pixel, sti->sti_data->inq_outptr.bits_used, sti->sti_data->inq_outptr.planes, - sti->sti_data->inq_outptr.attributes)); + sti->sti_data->inq_outptr.attributes); } static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, @@ -448,8 +445,7 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, if (offs != PCI_ROM_ADDRESS && (offs < PCI_BASE_ADDRESS_0 || offs > PCI_BASE_ADDRESS_5)) { - printk (KERN_WARNING - "STI pci region mapping for region %d (%02x) can't be mapped\n", + pr_warn("STI pci region mapping for region %d (%02x) can't be mapped\n", i,sti->rm_entry[i]); continue; } @@ -464,14 +460,14 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, if (len) glob_cfg->region_ptrs[i] = sti->regions_phys[i]; - DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " + pr_debug("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " "btlb=%d, sysonly=%d, cache=%d, last=%d\n", i, sti->regions_phys[i], glob_cfg->region_ptrs[i], len/1024, sti->regions[i].region_desc.btlb, sti->regions[i].region_desc.sys_only, sti->regions[i].region_desc.cache, - sti->regions[i].region_desc.last)); + sti->regions[i].region_desc.last); /* last entry reached ? */ if (sti->regions[i].region_desc.last) @@ -479,8 +475,8 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, } if (++i<8 && sti->regions[i].region) - printk(KERN_WARNING "%s: *future ptr (0x%8x) not yet supported !\n", - __FILE__, sti->regions[i].region); + pr_warn("future ptr (0x%8x) not yet supported !\n", + sti->regions[i].region); glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr); @@ -538,6 +534,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) } cooked_font->raw = nf; + cooked_font->raw_ptr = nf; cooked_font->next_font = NULL; cooked_rom->font_start = cooked_font; @@ -552,24 +549,38 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) } #endif -static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom, - int (*search_font_fnc)(struct sti_cooked_rom *, int, int)) +static int sti_search_font(struct sti_cooked_rom *rom, int height, int width) +{ + struct sti_cooked_font *font; + int i = 0; + + for (font = rom->font_start; font; font = font->next_font, i++) { + if ((font->raw->width == width) && + (font->raw->height == height)) + return i; + } + return 0; +} + +static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom) { struct sti_cooked_font *font; int i; - int index = num_sti_roms; /* check for framebuffer-font first */ - if ((font = sti_select_fbfont(rom, font_name[index]))) - return font; + if (!font_index) { + font = sti_select_fbfont(rom, font_name); + if (font) + return font; + } - if (font_width[index] && font_height[index]) - font_index[index] = search_font_fnc(rom, - font_height[index], font_width[index]); + if (font_width && font_height) + font_index = sti_search_font(rom, + font_height, font_width); - for (font = rom->font_start, i = font_index[index]; - font && (i > 0); - font = font->next_font, i--); + for (font = rom->font_start, i = font_index - 1; + font && (i > 0); + font = font->next_font, i--); if (font) return font; @@ -578,20 +589,35 @@ static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom, } -static void sti_dump_rom(struct sti_rom *rom) +static void sti_dump_rom(struct sti_struct *sti) { - printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n", + struct sti_rom *rom = sti->rom->raw; + struct sti_cooked_font *font_start; + int nr; + + pr_info(" id %04x-%04x, conforms to spec rev. %d.%02x\n", rom->graphics_id[0], rom->graphics_id[1], rom->revno[0] >> 4, rom->revno[0] & 0x0f); - DPRINTK((" supports %d monitors\n", rom->num_mons)); - DPRINTK((" font start %08x\n", rom->font_start)); - DPRINTK((" region list %08x\n", rom->region_list)); - DPRINTK((" init_graph %08x\n", rom->init_graph)); - DPRINTK((" bus support %02x\n", rom->bus_support)); - DPRINTK((" ext bus support %02x\n", rom->ext_bus_support)); - DPRINTK((" alternate code type %d\n", rom->alt_code_type)); + pr_debug(" supports %d monitors\n", rom->num_mons); + pr_debug(" font start %08x\n", rom->font_start); + pr_debug(" region list %08x\n", rom->region_list); + pr_debug(" init_graph %08x\n", rom->init_graph); + pr_debug(" bus support %02x\n", rom->bus_support); + pr_debug(" ext bus support %02x\n", rom->ext_bus_support); + pr_debug(" alternate code type %d\n", rom->alt_code_type); + + font_start = sti->rom->font_start; + nr = 0; + while (font_start) { + struct sti_rom_font *f = font_start->raw; + + pr_info(" built-in font #%d: size %dx%d, chars %d-%d, bpc %d\n", ++nr, + f->width, f->height, + f->first_char, f->last_char, f->bytes_per_char); + font_start = font_start->next_font; + } } @@ -628,39 +654,34 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom, return 1; } - -static int sti_search_font(struct sti_cooked_rom *rom, int height, int width) -{ - struct sti_cooked_font *font; - int i = 0; - - for (font = rom->font_start; font; font = font->next_font, i++) { - if ((font->raw->width == width) && - (font->raw->height == height)) - return i; - } - return 0; -} - #define BMODE_RELOCATE(offset) offset = (offset) / 4; #define BMODE_LAST_ADDR_OFFS 0x50 -static void *sti_bmode_font_raw(struct sti_cooked_font *f) +void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f) { unsigned char *n, *p, *q; - int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); - + int size = f->raw->bytes_per_char * 256 + sizeof(struct sti_rom_font); + struct sti_rom_font *old_font; + + if (sti->wordmode) + return; + + old_font = f->raw_ptr; n = kcalloc(4, size, STI_LOWMEM); + f->raw_ptr = n; if (!n) - return NULL; + return; p = n + 3; - q = (unsigned char *)f->raw; + q = (unsigned char *) f->raw; while (size--) { *p = *q++; - p+=4; + p += 4; } - return n + 3; + /* store new ptr to byte-mode font and delete old font */ + f->raw = (struct sti_rom_font *) (n + 3); + kfree(old_font); } +EXPORT_SYMBOL(sti_font_convert_bytemode); static void sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) @@ -747,7 +768,7 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, goto out_err; if (!sti_cook_fonts(cooked, raw)) { - printk(KERN_ERR "No font found for STI at %08lx\n", address); + pr_warn("No font found for STI at %08lx\n", address); goto out_err; } @@ -756,7 +777,8 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, address = (unsigned long) STI_PTR(raw); - pr_info("STI ROM supports 32 %sbit firmware functions.\n", + pr_info("STI %s ROM supports 32 %sbit firmware functions.\n", + wordmode ? "word mode" : "byte mode", raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64 ? "and 64 " : ""); @@ -767,18 +789,17 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, sti->rom = cooked; sti->rom->raw = raw; - - sti->font = sti_select_font(sti->rom, sti_search_font); - sti->font_width = sti->font->raw->width; - sti->font_height = sti->font->raw->height; - if (!wordmode) - sti->font->raw = sti_bmode_font_raw(sti->font); + sti_dump_rom(sti); + + sti->wordmode = wordmode; + sti->font = sti_select_font(sti->rom); + sti->font->width = sti->font->raw->width; + sti->font->height = sti->font->raw->height; + sti_font_convert_bytemode(sti, sti->font); sti->sti_mem_request = raw->sti_mem_req; sti->graphics_id[0] = raw->graphics_id[0]; sti->graphics_id[1] = raw->graphics_id[1]; - - sti_dump_rom(raw); /* check if the ROM routines in this card are compatible */ if (wordmode || sti->graphics_id[1] != 0x09A02587) @@ -804,9 +825,9 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, return 1; msg_not_supported: - printk(KERN_ERR "Sorry, this GSC/STI card is not yet supported.\n"); - printk(KERN_ERR "Please see http://parisc-linux.org/faq/" - "graphics-howto.html for more info.\n"); + pr_warn("Sorry, this GSC/STI card is not yet supported.\n"); + pr_warn("Please see https://parisc.wiki.kernel.org/" + "index.php/Graphics_howto for more info.\n"); /* fall through */ out_err: kfree(raw); @@ -823,7 +844,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, u32 sig; if (num_sti_roms >= MAX_STI_ROMS) { - printk(KERN_WARNING "maximum number of STI ROMS reached !\n"); + pr_warn("maximum number of STI ROMS reached !\n"); return NULL; } @@ -849,16 +870,15 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, if (i != 1) { /* The ROM could have multiple architecture * dependent images (e.g. i386, parisc,...) */ - printk(KERN_WARNING - "PCI ROM is not a STI ROM type image (0x%8x)\n", i); + pr_warn("PCI ROM is not a STI ROM type image (0x%8x)\n", i); goto out_err; } sti->pd = pd; i = gsc_readl(address+0x0c); - DPRINTK(("PCI ROM size (from header) = %d kB\n", - le16_to_cpu(i>>16)*512/1024)); + pr_debug("PCI ROM size (from header) = %d kB\n", + le16_to_cpu(i>>16)*512/1024); rm_offset = le16_to_cpu(i & 0xffff); if (rm_offset) { /* read 16 bytes from the pci region mapper array */ @@ -867,29 +887,24 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, *rm++ = gsc_readl(address+rm_offset+0x04); *rm++ = gsc_readl(address+rm_offset+0x08); *rm++ = gsc_readl(address+rm_offset+0x0c); - DPRINTK(("PCI region Mapper offset = %08x: ", - rm_offset)); - for (i=0; i<16; i++) - DPRINTK(("%02x ", sti->rm_entry[i])); - DPRINTK(("\n")); } address += le32_to_cpu(gsc_readl(address+8)); - DPRINTK(("sig %04x, PCI STI ROM at %08lx\n", sig, address)); + pr_debug("sig %04x, PCI STI ROM at %08lx\n", sig, address); goto test_rom; } ok = 0; if ((sig & 0xff) == 0x01) { - DPRINTK((" byte mode ROM at %08lx, hpa at %08lx\n", - address, hpa)); + pr_debug(" byte mode ROM at %08lx, hpa at %08lx\n", + address, hpa); ok = sti_read_rom(0, sti, address); } if ((sig & 0xffff) == 0x0303) { - DPRINTK((" word mode ROM at %08lx, hpa at %08lx\n", - address, hpa)); + pr_debug(" word mode ROM at %08lx, hpa at %08lx\n", + address, hpa); ok = sti_read_rom(1, sti, address); } @@ -906,7 +921,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, unsigned long rom_base; rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE); pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE); - DPRINTK((KERN_DEBUG "STI PCI ROM disabled\n")); + pr_debug("STI PCI ROM disabled\n"); } if (sti_init_graph(sti)) @@ -981,14 +996,14 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE); if (rom_base) { pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE); - DPRINTK((KERN_DEBUG "STI PCI ROM enabled at 0x%08lx\n", rom_base)); + pr_debug("STI PCI ROM enabled at 0x%08lx\n", rom_base); } - printk(KERN_INFO "STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n", + pr_info("STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n", rom_base, rom_len/1024, fb_base, fb_len/1024/1024); - DPRINTK((KERN_DEBUG "Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n", - rom_base, fb_base)); + pr_debug("Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n", + rom_base, fb_base); sti = sti_try_rom_generic(rom_base, fb_base, pd); if (sti) { @@ -998,8 +1013,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) } if (!sti) { - printk(KERN_WARNING "Unable to handle STI device '%s'\n", - pci_name(pd)); + pr_warn("Unable to handle STI device '%s'\n", pci_name(pd)); return -ENODEV; } #endif /* CONFIG_PCI */ @@ -1058,7 +1072,7 @@ static void sti_init_roms(void) sticore_initialized = 1; - printk(KERN_INFO "STI GSC/PCI core graphics driver " + pr_info("STI GSC/PCI core graphics driver " STI_DRIVERVERSION "\n"); /* Register drivers for native & PCI cards */ diff --git a/drivers/video/fbdev/sticore.h b/drivers/video/fbdev/sticore.h index fb8f58f9867a..c338f7848ae2 100644 --- a/drivers/video/fbdev/sticore.h +++ b/drivers/video/fbdev/sticore.h @@ -4,12 +4,6 @@ /* generic STI structures & functions */ -#if 0 -#define DPRINTK(x) printk x -#else -#define DPRINTK(x) -#endif - #define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */ #define STI_REGION_MAX 8 /* hardcoded STI constants */ @@ -246,8 +240,12 @@ struct sti_rom_font { /* sticore internal font handling */ struct sti_cooked_font { - struct sti_rom_font *raw; + struct sti_rom_font *raw; /* native ptr for STI functions */ + void *raw_ptr; /* kmalloc'ed font data */ struct sti_cooked_font *next_font; + int height, width; + int refcount; + u32 crc; }; struct sti_cooked_rom { @@ -341,9 +339,6 @@ struct sti_all_data { struct sti_struct { spinlock_t lock; - /* the following fields needs to be filled in by the word/byte routines */ - int font_width; - int font_height; /* char **mon_strings; */ int sti_mem_request; u32 graphics_id[2]; @@ -362,6 +357,7 @@ struct sti_struct { struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */ + int wordmode; struct sti_cooked_font *font; /* ptr to selected font (cooked) */ struct pci_dev *pd; @@ -380,6 +376,7 @@ struct sti_struct { /* sticore interface functions */ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ +void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f); /* sticore main function to call STI firmware */ @@ -391,12 +388,14 @@ int sti_call(const struct sti_struct *sti, unsigned long func, /* functions to call the STI ROM directly */ -void sti_putc(struct sti_struct *sti, int c, int y, int x); +void sti_putc(struct sti_struct *sti, int c, int y, int x, + struct sti_cooked_font *font); void sti_set(struct sti_struct *sti, int src_y, int src_x, - int height, int width, u8 color); + int height, int width, u8 color); void sti_clear(struct sti_struct *sti, int src_y, int src_x, - int height, int width, int c); + int height, int width, int c, struct sti_cooked_font *font); void sti_bmove(struct sti_struct *sti, int src_y, int src_x, - int dst_y, int dst_x, int height, int width); + int dst_y, int dst_x, int height, int width, + struct sti_cooked_font *font); #endif /* STICORE_H */ From 203c38fbe833abb47212db77004c05793b7220a3 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 9 Jul 2020 15:57:29 +0800 Subject: [PATCH 88/88] HID: i2c-hid: Enable wakeup capability from Suspend-to-Idle Many laptops can be woken up from Suspend-to-Idle by touchpad. This is also the default behavior on other OSes. However, if touchpad and touchscreen contact to each other when lid is closed, wakeup events can be triggered inadventertly. So let's disable the wakeup by default, but enable the wakeup capability so users can enable it at their own discretion. Signed-off-by: Kai-Heng Feng Reviewed-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid-core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index d053b86d0e2e..f2c6660ba3d7 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -935,6 +935,14 @@ static void i2c_hid_acpi_fix_up_power(struct device *dev) acpi_device_fix_up_power(adev); } +static void i2c_hid_acpi_enable_wakeup(struct device *dev) +{ + if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { + device_set_wakeup_capable(dev, true); + device_set_wakeup_enable(dev, false); + } +} + static const struct acpi_device_id i2c_hid_acpi_match[] = { {"ACPI0C50", 0 }, {"PNP0C50", 0 }, @@ -949,6 +957,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client, } static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} + +static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {} #endif #ifdef CONFIG_OF @@ -1076,6 +1086,8 @@ static int i2c_hid_probe(struct i2c_client *client, i2c_hid_acpi_fix_up_power(&client->dev); + i2c_hid_acpi_enable_wakeup(&client->dev); + device_enable_async_suspend(&client->dev); /* Make sure there is something at this address */