# git rev-parse -q --verify c228d294f2040c3a5f5965ff04d4947d0bf6e7da^{commit} c228d294f2040c3a5f5965ff04d4947d0bf6e7da already have revision, skipping fetch # git checkout -q -f -B kisskb c228d294f2040c3a5f5965ff04d4947d0bf6e7da # git clean -qxdf # < git log -1 # commit c228d294f2040c3a5f5965ff04d4947d0bf6e7da # Author: Linus Torvalds # Date: Thu Jan 31 11:10:20 2019 -0800 # # x86: explicitly align IO accesses in memcpy_{to,from}io # # In commit 170d13ca3a2f ("x86: re-introduce non-generic memcpy_{to,from}io") # I made our copy from IO space use a separate copy routine rather than # rely on the generic memcpy. I did that because our generic memory copy # isn't actually well-defined when it comes to internal access ordering or # alignment, and will in fact depend on various CPUID flags. # # In particular, the default memcpy() for a modern Intel CPU will # generally be just a "rep movsb", which works reasonably well for # medium-sized memory copies of regular RAM, since the CPU will turn it # into fairly optimized microcode. # # However, for non-cached memory and IO, "rep movs" ends up being # horrendously slow and will just do the architectural "one byte at a # time" accesses implied by the movsb. # # At the other end of the spectrum, if you _don't_ end up using the "rep # movsb" code, you'd likely fall back to the software copy, which does # overlapping accesses for the tail, and may copy things backwards. # Again, for regular memory that's fine, for IO memory not so much. # # The thinking was that clearly nobody really cared (because things # worked), but some people had seen horrible performance due to the byte # accesses, so let's just revert back to our long ago version that dod # "rep movsl" for the bulk of the copy, and then fixed up the potentially # last few bytes of the tail with "movsw/b". # # Interestingly (and perhaps not entirely surprisingly), while that was # our original memory copy implementation, and had been used before for # IO, in the meantime many new users of memcpy_*io() had come about. And # while the access patterns for the memory copy weren't well-defined (so # arguably _any_ access pattern should work), in practice the "rep movsb" # case had been very common for the last several years. # # In particular Jarkko Sakkinen reported that the memcpy_*io() change # resuled in weird errors from his Geminilake NUC TPM module. # # And it turns out that the TPM TCG accesses according to spec require # that the accesses be # # (a) done strictly sequentially # # (b) be naturally aligned # # otherwise the TPM chip will abort the PCI transaction. # # And, in fact, the tpm_crb.c driver did this: # # memcpy_fromio(buf, priv->rsp, 6); # ... # memcpy_fromio(&buf[6], &priv->rsp[6], expected - 6); # # which really should never have worked in the first place, but back # before commit 170d13ca3a2f it *happened* to work, because the # memcpy_fromio() would be expanded to a regular memcpy, and # # (a) gcc would expand the first memcpy in-line, and turn it into a # 4-byte and a 2-byte read, and they happened to be in the right # order, and the alignment was right. # # (b) gcc would call "memcpy()" for the second one, and the machines that # had this TPM chip also apparently ended up always having ERMS # ("Enhanced REP MOVSB/STOSB instructions"), so we'd use the "rep # movbs" for that copy. # # In other words, basically by pure luck, the code happened to use the # right access sizes in the (two different!) memcpy() implementations to # make it all work. # # But after commit 170d13ca3a2f, both of the memcpy_fromio() calls # resulted in a call to the routine with the consistent memory accesses, # and in both cases it started out transferring with 4-byte accesses. # Which worked for the first copy, but resulted in the second copy doing a # 32-bit read at an address that was only 2-byte aligned. # # Jarkko is actually fixing the fragile code in the TPM driver, but since # this is an excellent example of why we absolutely must not use a generic # memcpy for IO accesses, _and_ an IO-specific one really should strive to # align the IO accesses, let's do exactly that. # # Side note: Jarkko also noted that the driver had been used on ARM # platforms, and had worked. That was because on 32-bit ARM, memcpy_*io() # ends up always doing byte accesses, and on 64-bit ARM it first does byte # accesses to align to 8-byte boundaries, and then does 8-byte accesses # for the bulk. # # So ARM actually worked by design, and the x86 case worked by pure luck. # # We *might* want to make x86-64 do the 8-byte case too. That should be a # pretty straightforward extension, but let's do one thing at a time. And # generally MMIO accesses aren't really all that performance-critical, as # shown by the fact that for a long time we just did them a byte at a # time, and very few people ever noticed. # # Reported-and-tested-by: Jarkko Sakkinen # Tested-by: Jerry Snitselaar # Cc: David Laight # Fixes: 170d13ca3a2f ("x86: re-introduce non-generic memcpy_{to,from}io") # Signed-off-by: Linus Torvalds # < /opt/cross/kisskb/korg/gcc-8.1.0-nolibc/x86_64-linux/bin/x86_64-linux-gcc --version # < /opt/cross/kisskb/korg/gcc-8.1.0-nolibc/x86_64-linux/bin/x86_64-linux-ld --version # < git log --format=%s --max-count=1 c228d294f2040c3a5f5965ff04d4947d0bf6e7da # < make -s -j 48 ARCH=x86_64 O=/kisskb/build/linus-rand_x86_64-randconfig_x86_64-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/x86_64-linux/bin/x86_64-linux- randconfig KCONFIG_SEED=0x99DFBE32 WARNING: unmet direct dependencies detected for PINCTRL_MTK_MOORE Depends on [n]: PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] Selected by [y]: - PINCTRL_MT7623 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7623 || COMPILE_TEST [=y]) - PINCTRL_MT7629 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7629 || COMPILE_TEST [=y]) - PINCTRL_MT7622 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (ARM64 || COMPILE_TEST [=y]) WARNING: unmet direct dependencies detected for PINCTRL_MTK_MOORE Depends on [n]: PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] Selected by [y]: - PINCTRL_MT7623 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7623 || COMPILE_TEST [=y]) - PINCTRL_MT7629 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7629 || COMPILE_TEST [=y]) - PINCTRL_MT7622 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (ARM64 || COMPILE_TEST [=y]) WARNING: unmet direct dependencies detected for PINCTRL_MTK_MOORE Depends on [n]: PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] Selected by [y]: - PINCTRL_MT7623 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7623 || COMPILE_TEST [=y]) - PINCTRL_MT7629 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7629 || COMPILE_TEST [=y]) - PINCTRL_MT7622 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (ARM64 || COMPILE_TEST [=y]) # Added to kconfig CONFIG_STANDALONE=y # Added to kconfig CONFIG_PREVENT_FIRMWARE_BUILD=y # Added to kconfig CONFIG_CC_STACKPROTECTOR_STRONG=n # Added to kconfig CONFIG_GCC_PLUGINS=n # Added to kconfig CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=n # Added to kconfig CONFIG_GCC_PLUGIN_SANCOV=n # Added to kconfig CONFIG_GCC_PLUGIN_LATENT_ENTROPY=n # yes \n | make -s -j 48 ARCH=x86_64 O=/kisskb/build/linus-rand_x86_64-randconfig_x86_64-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/x86_64-linux/bin/x86_64-linux- oldconfig yes: standard output: Broken pipe # make -s -j 48 ARCH=x86_64 O=/kisskb/build/linus-rand_x86_64-randconfig_x86_64-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/x86_64-linux/bin/x86_64-linux- WARNING: unmet direct dependencies detected for PINCTRL_MTK_MOORE Depends on [n]: PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] Selected by [y]: - PINCTRL_MT7623 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7623 || COMPILE_TEST [=y]) - PINCTRL_MT7629 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7629 || COMPILE_TEST [=y]) - PINCTRL_MT7622 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (ARM64 || COMPILE_TEST [=y]) WARNING: unmet direct dependencies detected for PINCTRL_MTK_MOORE Depends on [n]: PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] Selected by [y]: - PINCTRL_MT7623 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7623 || COMPILE_TEST [=y]) - PINCTRL_MT7629 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7629 || COMPILE_TEST [=y]) - PINCTRL_MT7622 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (ARM64 || COMPILE_TEST [=y]) WARNING: unmet direct dependencies detected for PINCTRL_MTK_MOORE Depends on [n]: PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] Selected by [y]: - PINCTRL_MT7623 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7623 || COMPILE_TEST [=y]) - PINCTRL_MT7629 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (MACH_MT7629 || COMPILE_TEST [=y]) - PINCTRL_MT7622 [=y] && PINCTRL [=y] && (ARCH_MEDIATEK || COMPILE_TEST [=y]) && (ARM64 || COMPILE_TEST [=y]) /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:22:44: error: array type has incomplete element type 'struct pinconf_generic_params' static const struct pinconf_generic_params mtk_custom_bindings[] = { ^~~~~~~~~~~~~~~~~~~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: In function 'mtk_pinmux_set_mux': /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:46:9: error: implicit declaration of function 'pinmux_generic_get_function'; did you mean 'pinmux_generic_free_functions'? [-Werror=implicit-function-declaration] func = pinmux_generic_get_function(pctldev, selector); ^~~~~~~~~~~~~~~~~~~~~~~~~~~ pinmux_generic_free_functions /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:46:7: warning: assignment to 'struct function_desc *' from 'int' makes pointer from integer without a cast [-Wint-conversion] func = pinmux_generic_get_function(pctldev, selector); ^ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:50:8: error: implicit declaration of function 'pinctrl_generic_get_group'; did you mean 'pinctrl_dev_get_name'? [-Werror=implicit-function-declaration] grp = pinctrl_generic_get_group(pctldev, group); ^~~~~~~~~~~~~~~~~~~~~~~~~ pinctrl_dev_get_name /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:50:6: warning: assignment to 'struct group_desc *' from 'int' makes pointer from integer without a cast [-Wint-conversion] grp = pinctrl_generic_get_group(pctldev, group); ^ In file included from /kisskb/src/include/linux/gpio/driver.h:5, from /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:11: /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:55:7: error: dereferencing pointer to incomplete type 'struct function_desc' func->name, grp->name); ^~ /kisskb/src/include/linux/device.h:1476:46: note: in definition of macro 'dev_dbg' dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~~~~~~~~~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:55:18: error: dereferencing pointer to incomplete type 'struct group_desc' func->name, grp->name); ^~ /kisskb/src/include/linux/device.h:1476:46: note: in definition of macro 'dev_dbg' dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~~~~~~~~~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: In function 'mtk_pinconf_group_get': /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:357:8: error: implicit declaration of function 'pinctrl_generic_get_group_pins'; did you mean 'pinctrl_get_group_pins'? [-Werror=implicit-function-declaration] ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinctrl_get_group_pins /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: At top level: /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:397:22: error: 'pinctrl_generic_get_group_count' undeclared here (not in a function); did you mean 'pinctrl_get_group_pins'? .get_groups_count = pinctrl_generic_get_group_count, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinctrl_get_group_pins /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:398:20: error: 'pinctrl_generic_get_group_name' undeclared here (not in a function); did you mean 'pinctrl_dev_get_devname'? .get_group_name = pinctrl_generic_get_group_name, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinctrl_dev_get_devname /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:399:20: error: 'pinctrl_generic_get_group_pins' undeclared here (not in a function); did you mean 'pinctrl_get_group_pins'? .get_group_pins = pinctrl_generic_get_group_pins, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinctrl_get_group_pins /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:400:20: error: 'pinconf_generic_dt_node_to_map_all' undeclared here (not in a function); did you mean 'pinconf_generic_dump_config'? .dt_node_to_map = pinconf_generic_dt_node_to_map_all, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinconf_generic_dump_config /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:401:17: error: 'pinconf_generic_dt_free_map' undeclared here (not in a function); did you mean 'pinconf_generic_params'? .dt_free_map = pinconf_generic_dt_free_map, ^~~~~~~~~~~~~~~~~~~~~~~~~~~ pinconf_generic_params /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:405:25: error: 'pinmux_generic_get_function_count' undeclared here (not in a function); did you mean 'pinmux_generic_free_functions'? .get_functions_count = pinmux_generic_get_function_count, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinmux_generic_free_functions /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:406:23: error: 'pinmux_generic_get_function_name' undeclared here (not in a function); did you mean 'pinmux_generic_free_functions'? .get_function_name = pinmux_generic_get_function_name, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinmux_generic_free_functions /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:407:25: error: 'pinmux_generic_get_function_groups' undeclared here (not in a function); did you mean 'pinmux_generic_free_functions'? .get_function_groups = pinmux_generic_get_function_groups, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pinmux_generic_free_functions /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: In function 'mtk_build_gpiochip': /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:521:6: error: 'struct gpio_chip' has no member named 'of_node' chip->of_node = np; ^~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:522:6: error: 'struct gpio_chip' has no member named 'of_gpio_n_cells' chip->of_gpio_n_cells = 2; ^~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: In function 'mtk_build_groups': /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:552:50: error: invalid use of undefined type 'struct group_desc' const struct group_desc *group = hw->soc->grps + i; ^ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:554:9: error: implicit declaration of function 'pinctrl_generic_add_group'; did you mean 'pinconf_generic_dump_pins'? [-Werror=implicit-function-declaration] err = pinctrl_generic_add_group(hw->pctrl, group->name, ^~~~~~~~~~~~~~~~~~~~~~~~~ pinconf_generic_dump_pins /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:554:51: error: dereferencing pointer to incomplete type 'const struct group_desc' err = pinctrl_generic_add_group(hw->pctrl, group->name, ^~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: In function 'mtk_build_functions': /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:572:53: error: invalid use of undefined type 'struct function_desc' const struct function_desc *func = hw->soc->funcs + i; ^ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:574:9: error: implicit declaration of function 'pinmux_generic_add_function'; did you mean 'pinmux_generic_free_functions'? [-Werror=implicit-function-declaration] err = pinmux_generic_add_function(hw->pctrl, func->name, ^~~~~~~~~~~~~~~~~~~~~~~~~~~ pinmux_generic_free_functions /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:574:52: error: dereferencing pointer to incomplete type 'const struct function_desc' err = pinmux_generic_add_function(hw->pctrl, func->name, ^~ In file included from /kisskb/src/include/linux/kernel.h:15, from /kisskb/src/include/linux/list.h:9, from /kisskb/src/include/linux/kobject.h:19, from /kisskb/src/include/linux/device.h:16, from /kisskb/src/include/linux/gpio/driver.h:5, from /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:11: /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c: In function 'mtk_moore_pinctrl_probe': /kisskb/src/include/linux/build_bug.h:16:45: error: bit-field '' width not an integer constant #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); })) ^ /kisskb/src/include/linux/compiler.h:351:28: note: in expansion of macro 'BUILD_BUG_ON_ZERO' #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) ^~~~~~~~~~~~~~~~~ /kisskb/src/include/linux/kernel.h:72:59: note: in expansion of macro '__must_be_array' #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) ^~~~~~~~~~~~~~~ /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:643:31: note: in expansion of macro 'ARRAY_SIZE' mtk_desc.num_custom_params = ARRAY_SIZE(mtk_custom_bindings); ^~~~~~~~~~ At top level: /kisskb/src/drivers/pinctrl/mediatek/pinctrl-moore.c:22:44: warning: 'mtk_custom_bindings' defined but not used [-Wunused-variable] static const struct pinconf_generic_params mtk_custom_bindings[] = { ^~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors make[4]: *** [/kisskb/src/scripts/Makefile.build:276: drivers/pinctrl/mediatek/pinctrl-moore.o] Error 1 make[4]: *** Waiting for unfinished jobs.... make[3]: *** [/kisskb/src/scripts/Makefile.build:492: drivers/pinctrl/mediatek] Error 2 make[3]: *** Waiting for unfinished jobs.... make[2]: *** [/kisskb/src/scripts/Makefile.build:492: drivers/pinctrl] Error 2 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [/kisskb/src/Makefile:1043: drivers] Error 2 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:152: sub-make] Error 2 Command 'make -s -j 48 ARCH=x86_64 O=/kisskb/build/linus-rand_x86_64-randconfig_x86_64-gcc8 CROSS_COMPILE=/opt/cross/kisskb/korg/gcc-8.1.0-nolibc/x86_64-linux/bin/x86_64-linux- ' returned non-zero exit status 2 # rm -rf /kisskb/build/linus-rand_x86_64-randconfig_x86_64-gcc8 # Build took: 0:01:52.822527