Overlapping header include additions in macsec.c A bug fix in 'net' overlapping with the removal of 'version' string in ena_netdev.c Overlapping test additions in selftests Makefile Overlapping PCI ID table adjustments in iwlwifi driver.
Unified · Split
| @@ -225,6 +225,7 @@ Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com> · 224 unmodified lines | |||
| 225 | Praveen BP <praveenbp@ti.com> | 225 | Praveen BP <praveenbp@ti.com> |
| 226 | Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com> | 226 | Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com> |
| 227 | Qais Yousef <qsyousef@gmail.com> <qais.yousef@imgtec.com> | 227 | Qais Yousef <qsyousef@gmail.com> <qais.yousef@imgtec.com> |
| 228 | Quentin Monnet <quentin@isovalent.com> <quentin.monnet@netronome.com> | ||
| 228 | Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com> | 229 | Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com> |
| 229 | Rafael J. Wysocki <rjw@rjwysocki.net> <rjw@sisk.pl> | 230 | Rafael J. Wysocki <rjw@rjwysocki.net> <rjw@sisk.pl> |
| 230 | Rajesh Shah <rajesh.shah@intel.com> | 231 | Rajesh Shah <rajesh.shah@intel.com> |
| @@ -110,6 +110,8 @@ stable kernels. · 109 unmodified lines | |||
| 110 | +----------------+-----------------+-----------------+-----------------------------+ | 110 | +----------------+-----------------+-----------------+-----------------------------+ |
| 111 | | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | 111 | | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | |
| 112 | +----------------+-----------------+-----------------+-----------------------------+ | 112 | +----------------+-----------------+-----------------+-----------------------------+ |
| 113 | | Cavium | ThunderX GICv3 | #38539 | N/A | | ||
| 114 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 113 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | 115 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | |
| 114 | +----------------+-----------------+-----------------+-----------------------------+ | 116 | +----------------+-----------------+-----------------+-----------------------------+ |
| 115 | | Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 | | 117 | | Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 | |
| @@ -266,11 +266,15 @@ to use. · 265 unmodified lines | |||
| 266 | attached (via the dmaengine_desc_attach_metadata() helper to the descriptor. | 266 | attached (via the dmaengine_desc_attach_metadata() helper to the descriptor. |
| 267 | 267 | ||
| 268 | From the DMA driver the following is expected for this mode: | 268 | From the DMA driver the following is expected for this mode: |
| 269 | |||
| 269 | - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM | 270 | - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM |
| 271 | |||
| 270 | The data from the provided metadata buffer should be prepared for the DMA | 272 | The data from the provided metadata buffer should be prepared for the DMA |
| 271 | controller to be sent alongside of the payload data. Either by copying to a | 273 | controller to be sent alongside of the payload data. Either by copying to a |
| 272 | hardware descriptor, or highly coupled packet. | 274 | hardware descriptor, or highly coupled packet. |
| 275 | |||
| 273 | - DMA_DEV_TO_MEM | 276 | - DMA_DEV_TO_MEM |
| 277 | |||
| 274 | On transfer completion the DMA driver must copy the metadata to the client | 278 | On transfer completion the DMA driver must copy the metadata to the client |
| 275 | provided metadata buffer before notifying the client about the completion. | 279 | provided metadata buffer before notifying the client about the completion. |
| 276 | After the transfer completion, DMA drivers must not touch the metadata | 280 | After the transfer completion, DMA drivers must not touch the metadata |
| @@ -284,10 +288,14 @@ to use. · 7 unmodified lines | |||
| 284 | and dmaengine_desc_set_metadata_len() is provided as helper functions. | 288 | and dmaengine_desc_set_metadata_len() is provided as helper functions. |
| 285 | 289 | ||
| 286 | From the DMA driver the following is expected for this mode: | 290 | From the DMA driver the following is expected for this mode: |
| 287 | - get_metadata_ptr | 291 | |
| 292 | - get_metadata_ptr() | ||
| 293 | |||
| 288 | Should return a pointer for the metadata buffer, the maximum size of the | 294 | Should return a pointer for the metadata buffer, the maximum size of the |
| 289 | metadata buffer and the currently used / valid (if any) bytes in the buffer. | 295 | metadata buffer and the currently used / valid (if any) bytes in the buffer. |
| 290 | - set_metadata_len | 296 | |
| 297 | - set_metadata_len() | ||
| 298 | |||
| 291 | It is called by the clients after it have placed the metadata to the buffer | 299 | It is called by the clients after it have placed the metadata to the buffer |
| 292 | to let the DMA driver know the number of valid bytes provided. | 300 | to let the DMA driver know the number of valid bytes provided. |
| 293 | 301 | ||
| @@ -258,11 +258,11 @@ conditions. · 257 unmodified lines | |||
| 258 | | option | condition | size read write read write | | 258 | | option | condition | size read write read write | |
| 259 | +--------------+-----------+-----------------------------------------+ | 259 | +--------------+-----------+-----------------------------------------+ |
| 260 | | | good | fixed yes no yes yes | | 260 | | | good | fixed yes no yes yes | |
| 261 | | remount-ro | read-only | fixed yes no yes no | | 261 | | remount-ro | read-only | as is yes no yes no | |
| 262 | | (default) | offline | 0 no no no no | | 262 | | (default) | offline | 0 no no no no | |
| 263 | +--------------+-----------+-----------------------------------------+ | 263 | +--------------+-----------+-----------------------------------------+ |
| 264 | | | good | fixed yes no yes yes | | 264 | | | good | fixed yes no yes yes | |
| 265 | | zone-ro | read-only | fixed yes no yes no | | 265 | | zone-ro | read-only | as is yes no yes no | |
| 266 | | | offline | 0 no no no no | | 266 | | | offline | 0 no no no no | |
| 267 | +--------------+-----------+-----------------------------------------+ | 267 | +--------------+-----------+-----------------------------------------+ |
| 268 | | | good | 0 no no yes yes | | 268 | | | good | 0 no no yes yes | |
| @@ -270,7 +270,7 @@ conditions. · 1 unmodified line | |||
| 270 | | | offline | 0 no no no no | | 270 | | | offline | 0 no no no no | |
| 271 | +--------------+-----------+-----------------------------------------+ | 271 | +--------------+-----------+-----------------------------------------+ |
| 272 | | | good | fixed yes yes yes yes | | 272 | | | good | fixed yes yes yes yes | |
| 273 | | repair | read-only | fixed yes no yes no | | 273 | | repair | read-only | as is yes no yes no | |
| 274 | | | offline | 0 no no no no | | 274 | | | offline | 0 no no no no | |
| 275 | +--------------+-----------+-----------------------------------------+ | 275 | +--------------+-----------+-----------------------------------------+ |
| 276 | 276 | ||
| @@ -307,8 +307,16 @@ condition changes. The defined behaviors are as follow: · 30 unmodified lines | |||
| 307 | * zone-offline | 307 | * zone-offline |
| 308 | * repair | 308 | * repair |
| 309 | 309 | ||
| 310 | The I/O error actions defined for each behavior are detailed in the previous | 310 | The run-time I/O error actions defined for each behavior are detailed in the |
| 311 | section. | 311 | previous section. Mount time I/O errors will cause the mount operation to fail. |
| 312 | The handling of read-only zones also differs between mount-time and run-time. | ||
| 313 | If a read-only zone is found at mount time, the zone is always treated in the | ||
| 314 | same manner as offline zones, that is, all accesses are disabled and the zone | ||
| 315 | file size set to 0. This is necessary as the write pointer of read-only zones | ||
| 316 | is defined as invalib by the ZBC and ZAC standards, making it impossible to | ||
| 317 | discover the amount of data that has been written to the zone. In the case of a | ||
| 318 | read-only zone discovered at run-time, as indicated in the previous section. | ||
| 319 | the size of the zone file is left unchanged from its last updated value. | ||
| 312 | 320 | ||
| 313 | Zonefs User Space Tools | 321 | Zonefs User Space Tools |
| 314 | ======================= | 322 | ======================= |
| @@ -237,7 +237,7 @@ This is solely useful to speed up test compiles. · 236 unmodified lines | |||
| 237 | KBUILD_EXTRA_SYMBOLS | 237 | KBUILD_EXTRA_SYMBOLS |
| 238 | -------------------- | 238 | -------------------- |
| 239 | For modules that use symbols from other modules. | 239 | For modules that use symbols from other modules. |
| 240 | See more details in modules.txt. | 240 | See more details in modules.rst. |
| 241 | 241 | ||
| 242 | ALLSOURCE_ARCHS | 242 | ALLSOURCE_ARCHS |
| 243 | --------------- | 243 | --------------- |
| @@ -44,7 +44,7 @@ intermediate:: · 43 unmodified lines | |||
| 44 | def_bool y | 44 | def_bool y |
| 45 | 45 | ||
| 46 | Then, Kconfig moves onto the evaluation stage to resolve inter-symbol | 46 | Then, Kconfig moves onto the evaluation stage to resolve inter-symbol |
| 47 | dependency as explained in kconfig-language.txt. | 47 | dependency as explained in kconfig-language.rst. |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | Variables | 50 | Variables |
| @@ -924,7 +924,7 @@ When kbuild executes, the following steps are followed (roughly): · 923 unmodified lines | |||
| 924 | $(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that | 924 | $(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that |
| 925 | are used for assembler. | 925 | are used for assembler. |
| 926 | 926 | ||
| 927 | From commandline AFLAGS_MODULE shall be used (see kbuild.txt). | 927 | From commandline AFLAGS_MODULE shall be used (see kbuild.rst). |
| 928 | 928 | ||
| 929 | KBUILD_CFLAGS_KERNEL | 929 | KBUILD_CFLAGS_KERNEL |
| 930 | $(CC) options specific for built-in | 930 | $(CC) options specific for built-in |
| @@ -937,7 +937,7 @@ When kbuild executes, the following steps are followed (roughly): · 6 unmodified lines | |||
| 937 | 937 | ||
| 938 | $(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that | 938 | $(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that |
| 939 | are used for $(CC). | 939 | are used for $(CC). |
| 940 | From commandline CFLAGS_MODULE shall be used (see kbuild.txt). | 940 | From commandline CFLAGS_MODULE shall be used (see kbuild.rst). |
| 941 | 941 | ||
| 942 | KBUILD_LDFLAGS_MODULE | 942 | KBUILD_LDFLAGS_MODULE |
| 943 | Options for $(LD) when linking modules | 943 | Options for $(LD) when linking modules |
| @@ -945,7 +945,7 @@ When kbuild executes, the following steps are followed (roughly): · 1 unmodified line | |||
| 945 | $(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options | 945 | $(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options |
| 946 | used when linking modules. This is often a linker script. | 946 | used when linking modules. This is often a linker script. |
| 947 | 947 | ||
| 948 | From commandline LDFLAGS_MODULE shall be used (see kbuild.txt). | 948 | From commandline LDFLAGS_MODULE shall be used (see kbuild.rst). |
| 949 | 949 | ||
| 950 | KBUILD_LDS | 950 | KBUILD_LDS |
| 951 | 951 | ||
| @@ -470,9 +470,9 @@ build. · 469 unmodified lines | |||
| 470 | 470 | ||
| 471 | The syntax of the Module.symvers file is:: | 471 | The syntax of the Module.symvers file is:: |
| 472 | 472 | ||
| 473 | <CRC> <Symbol> <Namespace> <Module> <Export Type> | 473 | <CRC> <Symbol> <Module> <Export Type> <Namespace> |
| 474 | 474 | ||
| 475 | 0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL | 475 | 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE |
| 476 | 476 | ||
| 477 | The fields are separated by tabs and values may be empty (e.g. | 477 | The fields are separated by tabs and values may be empty (e.g. |
| 478 | if no namespace is defined for an exported symbol). | 478 | if no namespace is defined for an exported symbol). |
| @@ -7527,6 +7527,12 @@ F: include/uapi/linux/if_hippi.h · 7526 unmodified lines | |||
| 7527 | F: net/802/hippi.c | 7527 | F: net/802/hippi.c |
| 7528 | F: drivers/net/hippi/ | 7528 | F: drivers/net/hippi/ |
| 7529 | 7529 | ||
| 7530 | HISILICON DMA DRIVER | ||
| 7531 | M: Zhou Wang <wangzhou1@hisilicon.com> | ||
| 7532 | L: dmaengine@vger.kernel.org | ||
| 7533 | S: Maintained | ||
| 7534 | F: drivers/dma/hisi_dma.c | ||
| 7535 | |||
| 7530 | HISILICON SECURITY ENGINE V2 DRIVER (SEC2) | 7536 | HISILICON SECURITY ENGINE V2 DRIVER (SEC2) |
| 7531 | M: Zaibo Xu <xuzaibo@huawei.com> | 7537 | M: Zaibo Xu <xuzaibo@huawei.com> |
| 7532 | L: linux-crypto@vger.kernel.org | 7538 | L: linux-crypto@vger.kernel.org |
| @@ -8487,7 +8493,6 @@ L: dmaengine@vger.kernel.org · 954 unmodified lines | |||
| 8487 | S: Supported | 8493 | S: Supported |
| 8488 | F: drivers/dma/idxd/* | 8494 | F: drivers/dma/idxd/* |
| 8489 | F: include/uapi/linux/idxd.h | 8495 | F: include/uapi/linux/idxd.h |
| 8490 | F: include/linux/idxd.h | ||
| 8491 | 8496 | ||
| 8492 | INTEL IDLE DRIVER | 8497 | INTEL IDLE DRIVER |
| 8493 | M: Jacob Pan <jacob.jun.pan@linux.intel.com> | 8498 | M: Jacob Pan <jacob.jun.pan@linux.intel.com> |
| @@ -8694,7 +8699,7 @@ M: Emmanuel Grumbach <emmanuel.grumbach@intel.com> · 200 unmodified lines | |||
| 8694 | M: Luca Coelho <luciano.coelho@intel.com> | 8699 | M: Luca Coelho <luciano.coelho@intel.com> |
| 8695 | M: Intel Linux Wireless <linuxwifi@intel.com> | 8700 | M: Intel Linux Wireless <linuxwifi@intel.com> |
| 8696 | L: linux-wireless@vger.kernel.org | 8701 | L: linux-wireless@vger.kernel.org |
| 8697 | W: http://intellinuxwireless.org | 8702 | W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi |
| 8698 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git | 8703 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git |
| 8699 | S: Supported | 8704 | S: Supported |
| 8700 | F: drivers/net/wireless/intel/iwlwifi/ | 8705 | F: drivers/net/wireless/intel/iwlwifi/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 6 | 3 | PATCHLEVEL = 6 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc5 | 5 | EXTRAVERSION = -rc7 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -1804,7 +1804,7 @@ existing-targets := $(wildcard $(sort $(targets))) · 1795 unmodified lines | |||
| 1804 | 1804 | ||
| 1805 | -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) | 1805 | -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) |
| 1806 | 1806 | ||
| 1807 | endif # config-targets | 1807 | endif # config-build |
| 1808 | endif # mixed-build | 1808 | endif # mixed-build |
| 1809 | endif # need-sub-make | 1809 | endif # need-sub-make |
| 1810 | 1810 | ||
| @@ -154,7 +154,7 @@ config ARC_CPU_HS · 153 unmodified lines | |||
| 154 | help | 154 | help |
| 155 | Support for ARC HS38x Cores based on ARCv2 ISA | 155 | Support for ARC HS38x Cores based on ARCv2 ISA |
| 156 | The notable features are: | 156 | The notable features are: |
| 157 | - SMP configurations of upto 4 core with coherency | 157 | - SMP configurations of up to 4 cores with coherency |
| 158 | - Optional L2 Cache and IO-Coherency | 158 | - Optional L2 Cache and IO-Coherency |
| 159 | - Revised Interrupt Architecture (multiple priorites, reg banks, | 159 | - Revised Interrupt Architecture (multiple priorites, reg banks, |
| 160 | auto stack switch, auto regfile save/restore) | 160 | auto stack switch, auto regfile save/restore) |
| @@ -192,7 +192,7 @@ config ARC_SMP_HALT_ON_RESET · 31 unmodified lines | |||
| 192 | help | 192 | help |
| 193 | In SMP configuration cores can be configured as Halt-on-reset | 193 | In SMP configuration cores can be configured as Halt-on-reset |
| 194 | or they could all start at same time. For Halt-on-reset, non | 194 | or they could all start at same time. For Halt-on-reset, non |
| 195 | masters are parked until Master kicks them so they can start of | 195 | masters are parked until Master kicks them so they can start off |
| 196 | at designated entry point. For other case, all jump to common | 196 | at designated entry point. For other case, all jump to common |
| 197 | entry point and spin wait for Master's signal. | 197 | entry point and spin wait for Master's signal. |
| 198 | 198 | ||
| @@ -21,8 +21,6 @@ CONFIG_MODULES=y · 20 unmodified lines | |||
| 21 | CONFIG_MODULE_FORCE_LOAD=y | 21 | CONFIG_MODULE_FORCE_LOAD=y |
| 22 | CONFIG_MODULE_UNLOAD=y | 22 | CONFIG_MODULE_UNLOAD=y |
| 23 | # CONFIG_BLK_DEV_BSG is not set | 23 | # CONFIG_BLK_DEV_BSG is not set |
| 24 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 25 | # CONFIG_IOSCHED_CFQ is not set | ||
| 26 | CONFIG_ARC_PLAT_EZNPS=y | 24 | CONFIG_ARC_PLAT_EZNPS=y |
| 27 | CONFIG_SMP=y | 25 | CONFIG_SMP=y |
| 28 | CONFIG_NR_CPUS=4096 | 26 | CONFIG_NR_CPUS=4096 |
| @@ -20,8 +20,6 @@ CONFIG_ISA_ARCOMPACT=y · 19 unmodified lines | |||
| 20 | CONFIG_KPROBES=y | 20 | CONFIG_KPROBES=y |
| 21 | CONFIG_MODULES=y | 21 | CONFIG_MODULES=y |
| 22 | # CONFIG_BLK_DEV_BSG is not set | 22 | # CONFIG_BLK_DEV_BSG is not set |
| 23 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 24 | # CONFIG_IOSCHED_CFQ is not set | ||
| 25 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" | 23 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" |
| 26 | # CONFIG_COMPACTION is not set | 24 | # CONFIG_COMPACTION is not set |
| 27 | CONFIG_NET=y | 25 | CONFIG_NET=y |
| @@ -19,8 +19,6 @@ CONFIG_PERF_EVENTS=y · 18 unmodified lines | |||
| 19 | CONFIG_KPROBES=y | 19 | CONFIG_KPROBES=y |
| 20 | CONFIG_MODULES=y | 20 | CONFIG_MODULES=y |
| 21 | # CONFIG_BLK_DEV_BSG is not set | 21 | # CONFIG_BLK_DEV_BSG is not set |
| 22 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 23 | # CONFIG_IOSCHED_CFQ is not set | ||
| 24 | CONFIG_ISA_ARCV2=y | 22 | CONFIG_ISA_ARCV2=y |
| 25 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs" | 23 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs" |
| 26 | # CONFIG_COMPACTION is not set | 24 | # CONFIG_COMPACTION is not set |
| @@ -14,8 +14,6 @@ CONFIG_PERF_EVENTS=y · 13 unmodified lines | |||
| 14 | CONFIG_KPROBES=y | 14 | CONFIG_KPROBES=y |
| 15 | CONFIG_MODULES=y | 15 | CONFIG_MODULES=y |
| 16 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
| 17 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 18 | # CONFIG_IOSCHED_CFQ is not set | ||
| 19 | CONFIG_ISA_ARCV2=y | 17 | CONFIG_ISA_ARCV2=y |
| 20 | CONFIG_SMP=y | 18 | CONFIG_SMP=y |
| 21 | # CONFIG_ARC_TIMERS_64BIT is not set | 19 | # CONFIG_ARC_TIMERS_64BIT is not set |
| @@ -43,6 +43,8 @@ extern void fpu_init_task(struct pt_regs *regs); · 42 unmodified lines | |||
| 43 | 43 | ||
| 44 | #endif /* !CONFIG_ISA_ARCOMPACT */ | 44 | #endif /* !CONFIG_ISA_ARCOMPACT */ |
| 45 | 45 | ||
| 46 | struct task_struct; | ||
| 47 | |||
| 46 | extern void fpu_save_restore(struct task_struct *p, struct task_struct *n); | 48 | extern void fpu_save_restore(struct task_struct *p, struct task_struct *n); |
| 47 | 49 | ||
| 48 | #else /* !CONFIG_ARC_FPU_SAVE_RESTORE */ | 50 | #else /* !CONFIG_ARC_FPU_SAVE_RESTORE */ |
| @@ -29,6 +29,8 @@ · 28 unmodified lines | |||
| 29 | .endm | 29 | .endm |
| 30 | 30 | ||
| 31 | #define ASM_NL ` /* use '`' to mark new line in macro */ | 31 | #define ASM_NL ` /* use '`' to mark new line in macro */ |
| 32 | #define __ALIGN .align 4 | ||
| 33 | #define __ALIGN_STR __stringify(__ALIGN) | ||
| 32 | 34 | ||
| 33 | /* annotation for data we want in DCCM - if enabled in .config */ | 35 | /* annotation for data we want in DCCM - if enabled in .config */ |
| 34 | .macro ARCFP_DATA nm | 36 | .macro ARCFP_DATA nm |
| @@ -8,11 +8,11 @@ · 7 unmodified lines | |||
| 8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
| 9 | #include <linux/root_dev.h> | 9 | #include <linux/root_dev.h> |
| 10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
| 11 | #include <linux/clk-provider.h> | ||
| 12 | #include <linux/clocksource.h> | 11 | #include <linux/clocksource.h> |
| 13 | #include <linux/console.h> | 12 | #include <linux/console.h> |
| 14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 15 | #include <linux/cpu.h> | 14 | #include <linux/cpu.h> |
| 15 | #include <linux/of_clk.h> | ||
| 16 | #include <linux/of_fdt.h> | 16 | #include <linux/of_fdt.h> |
| 17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 18 | #include <linux/cache.h> | 18 | #include <linux/cache.h> |
| @@ -104,8 +104,7 @@ static void show_faulting_vma(unsigned long address) · 103 unmodified lines | |||
| 104 | if (IS_ERR(nm)) | 104 | if (IS_ERR(nm)) |
| 105 | nm = "?"; | 105 | nm = "?"; |
| 106 | } | 106 | } |
| 107 | pr_info(" @off 0x%lx in [%s]\n" | 107 | pr_info(" @off 0x%lx in [%s] VMA: 0x%08lx to 0x%08lx\n", |
| 108 | " VMA: 0x%08lx to 0x%08lx\n", | ||
| 109 | vma->vm_start < TASK_UNMAPPED_BASE ? | 108 | vma->vm_start < TASK_UNMAPPED_BASE ? |
| 110 | address : address - vma->vm_start, | 109 | address : address - vma->vm_start, |
| 111 | nm, vma->vm_start, vma->vm_end); | 110 | nm, vma->vm_start, vma->vm_end); |
| @@ -120,8 +119,6 @@ static void show_ecr_verbose(struct pt_regs *regs) · 8 unmodified lines | |||
| 120 | unsigned int vec, cause_code; | 119 | unsigned int vec, cause_code; |
| 121 | unsigned long address; | 120 | unsigned long address; |
| 122 | 121 | ||
| 123 | pr_info("\n[ECR ]: 0x%08lx => ", regs->event); | ||
| 124 | |||
| 125 | /* For Data fault, this is data address not instruction addr */ | 122 | /* For Data fault, this is data address not instruction addr */ |
| 126 | address = current->thread.fault_address; | 123 | address = current->thread.fault_address; |
| 127 | 124 | ||
| @@ -130,10 +127,10 @@ static void show_ecr_verbose(struct pt_regs *regs) · 2 unmodified lines | |||
| 130 | 127 | ||
| 131 | /* For DTLB Miss or ProtV, display the memory involved too */ | 128 | /* For DTLB Miss or ProtV, display the memory involved too */ |
| 132 | if (vec == ECR_V_DTLB_MISS) { | 129 | if (vec == ECR_V_DTLB_MISS) { |
| 133 | pr_cont("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n", | 130 | pr_cont("Invalid %s @ 0x%08lx by insn @ %pS\n", |
| 134 | (cause_code == 0x01) ? "Read" : | 131 | (cause_code == 0x01) ? "Read" : |
| 135 | ((cause_code == 0x02) ? "Write" : "EX"), | 132 | ((cause_code == 0x02) ? "Write" : "EX"), |
| 136 | address, regs->ret); | 133 | address, (void *)regs->ret); |
| 137 | } else if (vec == ECR_V_ITLB_MISS) { | 134 | } else if (vec == ECR_V_ITLB_MISS) { |
| 138 | pr_cont("Insn could not be fetched\n"); | 135 | pr_cont("Insn could not be fetched\n"); |
| 139 | } else if (vec == ECR_V_MACH_CHK) { | 136 | } else if (vec == ECR_V_MACH_CHK) { |
| @@ -191,31 +188,31 @@ void show_regs(struct pt_regs *regs) · 51 unmodified lines | |||
| 191 | 188 | ||
| 192 | show_ecr_verbose(regs); | 189 | show_ecr_verbose(regs); |
| 193 | 190 | ||
| 194 | pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n", | ||
| 195 | current->thread.fault_address, | ||
| 196 | (void *)regs->blink, (void *)regs->ret); | ||
| 197 | |||
| 198 | if (user_mode(regs)) | 191 | if (user_mode(regs)) |
| 199 | show_faulting_vma(regs->ret); /* faulting code, not data */ | 192 | show_faulting_vma(regs->ret); /* faulting code, not data */ |
| 200 | 193 | ||
| 201 | pr_info("[STAT32]: 0x%08lx", regs->status32); | 194 | pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n", |
| 195 | regs->event, current->thread.fault_address, regs->ret); | ||
| 196 | |||
| 197 | pr_info("STAT32: 0x%08lx", regs->status32); | ||
| 202 | 198 | ||
| 203 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" | 199 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" |
| 204 | 200 | ||
| 205 | #ifdef CONFIG_ISA_ARCOMPACT | 201 | #ifdef CONFIG_ISA_ARCOMPACT |
| 206 | pr_cont(" : %2s%2s%2s%2s%2s%2s%2s\n", | 202 | pr_cont(" [%2s%2s%2s%2s%2s%2s%2s]", |
| 207 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", | 203 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 208 | STS_BIT(regs, DE), STS_BIT(regs, AE), | 204 | STS_BIT(regs, DE), STS_BIT(regs, AE), |
| 209 | STS_BIT(regs, A2), STS_BIT(regs, A1), | 205 | STS_BIT(regs, A2), STS_BIT(regs, A1), |
| 210 | STS_BIT(regs, E2), STS_BIT(regs, E1)); | 206 | STS_BIT(regs, E2), STS_BIT(regs, E1)); |
| 211 | #else | 207 | #else |
| 212 | pr_cont(" : %2s%2s%2s%2s\n", | 208 | pr_cont(" [%2s%2s%2s%2s]", |
| 213 | STS_BIT(regs, IE), | 209 | STS_BIT(regs, IE), |
| 214 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", | 210 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 215 | STS_BIT(regs, DE), STS_BIT(regs, AE)); | 211 | STS_BIT(regs, DE), STS_BIT(regs, AE)); |
| 216 | #endif | 212 | #endif |
| 217 | pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", | 213 | pr_cont(" BTA: 0x%08lx\n", regs->bta); |
| 218 | regs->bta, regs->sp, regs->fp); | 214 | pr_info("BLK: %pS\n SP: 0x%08lx FP: 0x%08lx\n", |
| 215 | (void *)regs->blink, regs->sp, regs->fp); | ||
| 219 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", | 216 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", |
| 220 | regs->lp_start, regs->lp_end, regs->lp_count); | 217 | regs->lp_start, regs->lp_end, regs->lp_count); |
| 221 | 218 | ||
| @@ -307,13 +307,15 @@ endif · 306 unmodified lines | |||
| 307 | ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) | 307 | ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) |
| 308 | prepare: stack_protector_prepare | 308 | prepare: stack_protector_prepare |
| 309 | stack_protector_prepare: prepare0 | 309 | stack_protector_prepare: prepare0 |
| 310 | $(eval KBUILD_CFLAGS += \ | 310 | $(eval SSP_PLUGIN_CFLAGS := \ |
| 311 | -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ | 311 | -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ |
| 312 | awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ | 312 | awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ |
| 313 | include/generated/asm-offsets.h) \ | 313 | include/generated/asm-offsets.h) \ |
| 314 | -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ | 314 | -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ |
| 315 | awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ | 315 | awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ |
| 316 | include/generated/asm-offsets.h)) | 316 | include/generated/asm-offsets.h)) |
| 317 | $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) | ||
| 318 | $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) | ||
| 317 | endif | 319 | endif |
| 318 | 320 | ||
| 319 | all: $(notdir $(KBUILD_IMAGE)) | 321 | all: $(notdir $(KBUILD_IMAGE)) |
| @@ -101,7 +101,6 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ · 100 unmodified lines | |||
| 101 | $(libfdt) $(libfdt_hdrs) hyp-stub.S | 101 | $(libfdt) $(libfdt_hdrs) hyp-stub.S |
| 102 | 102 | ||
| 103 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING | 103 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| 104 | KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) | ||
| 105 | 104 | ||
| 106 | ifeq ($(CONFIG_FUNCTION_TRACER),y) | 105 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
| 107 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 106 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
| @@ -117,7 +116,8 @@ CFLAGS_fdt_ro.o := $(nossp-flags-y) · 9 unmodified lines | |||
| 117 | CFLAGS_fdt_rw.o := $(nossp-flags-y) | 116 | CFLAGS_fdt_rw.o := $(nossp-flags-y) |
| 118 | CFLAGS_fdt_wip.o := $(nossp-flags-y) | 117 | CFLAGS_fdt_wip.o := $(nossp-flags-y) |
| 119 | 118 | ||
| 120 | ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) | 119 | ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ |
| 120 | -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) | ||
| 121 | asflags-y := -DZIMAGE | 121 | asflags-y := -DZIMAGE |
| 122 | 122 | ||
| 123 | # Supply kernel BSS size to the decompressor via a linker symbol. | 123 | # Supply kernel BSS size to the decompressor via a linker symbol. |
| @@ -94,6 +94,8 @@ static bool __init cntvct_functional(void) · 93 unmodified lines | |||
| 94 | * this. | 94 | * this. |
| 95 | */ | 95 | */ |
| 96 | np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); | 96 | np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); |
| 97 | if (!np) | ||
| 98 | np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); | ||
| 97 | if (!np) | 99 | if (!np) |
| 98 | goto out_put; | 100 | goto out_put; |
| 99 | 101 | ||
| @@ -118,7 +118,7 @@ ENTRY(arm_copy_from_user) · 117 unmodified lines | |||
| 118 | 118 | ||
| 119 | ENDPROC(arm_copy_from_user) | 119 | ENDPROC(arm_copy_from_user) |
| 120 | 120 | ||
| 121 | .pushsection .fixup,"ax" | 121 | .pushsection .text.fixup,"ax" |
| 122 | .align 0 | 122 | .align 0 |
| 123 | copy_abort_preamble | 123 | copy_abort_preamble |
| 124 | ldmfd sp!, {r1, r2, r3} | 124 | ldmfd sp!, {r1, r2, r3} |
| @@ -119,12 +119,12 @@ · 118 unmodified lines | |||
| 119 | 119 | ||
| 120 | ethernet@e4000 { | 120 | ethernet@e4000 { |
| 121 | phy-handle = <&rgmii_phy1>; | 121 | phy-handle = <&rgmii_phy1>; |
| 122 | phy-connection-type = "rgmii-txid"; | 122 | phy-connection-type = "rgmii-id"; |
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | ethernet@e6000 { | 125 | ethernet@e6000 { |
| 126 | phy-handle = <&rgmii_phy2>; | 126 | phy-handle = <&rgmii_phy2>; |
| 127 | phy-connection-type = "rgmii-txid"; | 127 | phy-connection-type = "rgmii-id"; |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | ethernet@e8000 { | 130 | ethernet@e8000 { |
| @@ -131,12 +131,12 @@ · 130 unmodified lines | |||
| 131 | &fman0 { | 131 | &fman0 { |
| 132 | ethernet@e4000 { | 132 | ethernet@e4000 { |
| 133 | phy-handle = <&rgmii_phy1>; | 133 | phy-handle = <&rgmii_phy1>; |
| 134 | phy-connection-type = "rgmii"; | 134 | phy-connection-type = "rgmii-id"; |
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | ethernet@e6000 { | 137 | ethernet@e6000 { |
| 138 | phy-handle = <&rgmii_phy2>; | 138 | phy-handle = <&rgmii_phy2>; |
| 139 | phy-connection-type = "rgmii"; | 139 | phy-connection-type = "rgmii-id"; |
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | ethernet@e8000 { | 142 | ethernet@e8000 { |
| @@ -55,10 +55,10 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, · 54 unmodified lines | |||
| 55 | break; | 55 | break; |
| 56 | } | 56 | } |
| 57 | chacha_4block_xor_neon(state, dst, src, nrounds, l); | 57 | chacha_4block_xor_neon(state, dst, src, nrounds, l); |
| 58 | bytes -= CHACHA_BLOCK_SIZE * 5; | 58 | bytes -= l; |
| 59 | src += CHACHA_BLOCK_SIZE * 5; | 59 | src += l; |
| 60 | dst += CHACHA_BLOCK_SIZE * 5; | 60 | dst += l; |
| 61 | state[12] += 5; | 61 | state[12] += DIV_ROUND_UP(l, CHACHA_BLOCK_SIZE); |
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| @@ -29,11 +29,9 @@ typedef struct { · 28 unmodified lines | |||
| 29 | */ | 29 | */ |
| 30 | #define ASID(mm) ((mm)->context.id.counter & 0xffff) | 30 | #define ASID(mm) ((mm)->context.id.counter & 0xffff) |
| 31 | 31 | ||
| 32 | extern bool arm64_use_ng_mappings; | ||
| 33 | |||
| 34 | static inline bool arm64_kernel_unmapped_at_el0(void) | 32 | static inline bool arm64_kernel_unmapped_at_el0(void) |
| 35 | { | 33 | { |
| 36 | return arm64_use_ng_mappings; | 34 | return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0); |
| 37 | } | 35 | } |
| 38 | 36 | ||
| 39 | typedef void (*bp_hardening_cb_t)(void); | 37 | typedef void (*bp_hardening_cb_t)(void); |
| @@ -23,11 +23,13 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include <asm/pgtable-types.h> | 24 | #include <asm/pgtable-types.h> |
| 25 | 25 | ||
| 26 | extern bool arm64_use_ng_mappings; | ||
| 27 | |||
| 26 | #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) | 28 | #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) |
| 27 | #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) | 29 | #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) |
| 28 | 30 | ||
| 29 | #define PTE_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PTE_NG : 0) | 31 | #define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0) |
| 30 | #define PMD_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PMD_SECT_NG : 0) | 32 | #define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0) |
| 31 | 33 | ||
| 32 | #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) | 34 | #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) |
| 33 | #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) | 35 | #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) |
| @@ -25,8 +25,8 @@ · 24 unmodified lines | |||
| 25 | #define __NR_compat_gettimeofday 78 | 25 | #define __NR_compat_gettimeofday 78 |
| 26 | #define __NR_compat_sigreturn 119 | 26 | #define __NR_compat_sigreturn 119 |
| 27 | #define __NR_compat_rt_sigreturn 173 | 27 | #define __NR_compat_rt_sigreturn 173 |
| 28 | #define __NR_compat_clock_getres 247 | ||
| 29 | #define __NR_compat_clock_gettime 263 | 28 | #define __NR_compat_clock_gettime 263 |
| 29 | #define __NR_compat_clock_getres 264 | ||
| 30 | #define __NR_compat_clock_gettime64 403 | 30 | #define __NR_compat_clock_gettime64 403 |
| 31 | #define __NR_compat_clock_getres_time64 406 | 31 | #define __NR_compat_clock_getres_time64 406 |
| 32 | 32 | ||
| @@ -958,11 +958,22 @@ void tick_broadcast(const struct cpumask *mask) · 957 unmodified lines | |||
| 958 | } | 958 | } |
| 959 | #endif | 959 | #endif |
| 960 | 960 | ||
| 961 | /* | ||
| 962 | * The number of CPUs online, not counting this CPU (which may not be | ||
| 963 | * fully online and so not counted in num_online_cpus()). | ||
| 964 | */ | ||
| 965 | static inline unsigned int num_other_online_cpus(void) | ||
| 966 | { | ||
| 967 | unsigned int this_cpu_online = cpu_online(smp_processor_id()); | ||
| 968 | |||
| 969 | return num_online_cpus() - this_cpu_online; | ||
| 970 | } | ||
| 971 | |||
| 961 | void smp_send_stop(void) | 972 | void smp_send_stop(void) |
| 962 | { | 973 | { |
| 963 | unsigned long timeout; | 974 | unsigned long timeout; |
| 964 | 975 | ||
| 965 | if (num_online_cpus() > 1) { | 976 | if (num_other_online_cpus()) { |
| 966 | cpumask_t mask; | 977 | cpumask_t mask; |
| 967 | 978 | ||
| 968 | cpumask_copy(&mask, cpu_online_mask); | 979 | cpumask_copy(&mask, cpu_online_mask); |
| @@ -975,10 +986,10 @@ void smp_send_stop(void) · 6 unmodified lines | |||
| 975 | 986 | ||
| 976 | /* Wait up to one second for other CPUs to stop */ | 987 | /* Wait up to one second for other CPUs to stop */ |
| 977 | timeout = USEC_PER_SEC; | 988 | timeout = USEC_PER_SEC; |
| 978 | while (num_online_cpus() > 1 && timeout--) | 989 | while (num_other_online_cpus() && timeout--) |
| 979 | udelay(1); | 990 | udelay(1); |
| 980 | 991 | ||
| 981 | if (num_online_cpus() > 1) | 992 | if (num_other_online_cpus()) |
| 982 | pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", | 993 | pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", |
| 983 | cpumask_pr_args(cpu_online_mask)); | 994 | cpumask_pr_args(cpu_online_mask)); |
| 984 | 995 | ||
| @@ -1001,7 +1012,11 @@ void crash_smp_send_stop(void) · 16 unmodified lines | |||
| 1001 | 1012 | ||
| 1002 | cpus_stopped = 1; | 1013 | cpus_stopped = 1; |
| 1003 | 1014 | ||
| 1004 | if (num_online_cpus() == 1) { | 1015 | /* |
| 1016 | * If this cpu is the only one alive at this point in time, online or | ||
| 1017 | * not, there are no stop messages to be sent around, so just back out. | ||
| 1018 | */ | ||
| 1019 | if (num_other_online_cpus() == 0) { | ||
| 1005 | sdei_mask_local_cpu(); | 1020 | sdei_mask_local_cpu(); |
| 1006 | return; | 1021 | return; |
| 1007 | } | 1022 | } |
| @@ -1009,7 +1024,7 @@ void crash_smp_send_stop(void) · 1 unmodified line | |||
| 1009 | cpumask_copy(&mask, cpu_online_mask); | 1024 | cpumask_copy(&mask, cpu_online_mask); |
| 1010 | cpumask_clear_cpu(smp_processor_id(), &mask); | 1025 | cpumask_clear_cpu(smp_processor_id(), &mask); |
| 1011 | 1026 | ||
| 1012 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | 1027 | atomic_set(&waiting_for_crash_ipi, num_other_online_cpus()); |
| 1013 | 1028 | ||
| 1014 | pr_crit("SMP: stopping secondary CPUs\n"); | 1029 | pr_crit("SMP: stopping secondary CPUs\n"); |
| 1015 | smp_cross_call(&mask, IPI_CPU_CRASH_STOP); | 1030 | smp_cross_call(&mask, IPI_CPU_CRASH_STOP); |
| @@ -1817,6 +1817,7 @@ static void kvmppc_core_vcpu_free_pr(struct kvm_vcpu *vcpu) · 1816 unmodified lines | |||
| 1817 | { | 1817 | { |
| 1818 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); | 1818 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); |
| 1819 | 1819 | ||
| 1820 | kvmppc_mmu_destroy_pr(vcpu); | ||
| 1820 | free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); | 1821 | free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); |
| 1821 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER | 1822 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
| 1822 | kfree(vcpu->arch.shadow_vcpu); | 1823 | kfree(vcpu->arch.shadow_vcpu); |
| @@ -759,7 +759,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 758 unmodified lines | |||
| 759 | return 0; | 759 | return 0; |
| 760 | 760 | ||
| 761 | out_vcpu_uninit: | 761 | out_vcpu_uninit: |
| 762 | kvmppc_mmu_destroy(vcpu); | ||
| 763 | kvmppc_subarch_vcpu_uninit(vcpu); | 762 | kvmppc_subarch_vcpu_uninit(vcpu); |
| 764 | return err; | 763 | return err; |
| 765 | } | 764 | } |
| @@ -792,7 +791,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) · 26 unmodified lines | |||
| 792 | 791 | ||
| 793 | kvmppc_core_vcpu_free(vcpu); | 792 | kvmppc_core_vcpu_free(vcpu); |
| 794 | 793 | ||
| 795 | kvmppc_mmu_destroy(vcpu); | ||
| 796 | kvmppc_subarch_vcpu_uninit(vcpu); | 794 | kvmppc_subarch_vcpu_uninit(vcpu); |
| 797 | } | 795 | } |
| 798 | 796 | ||
| @@ -120,12 +120,6 @@ static void __init kasan_unmap_early_shadow_vmalloc(void) · 119 unmodified lines | |||
| 120 | unsigned long k_cur; | 120 | unsigned long k_cur; |
| 121 | phys_addr_t pa = __pa(kasan_early_shadow_page); | 121 | phys_addr_t pa = __pa(kasan_early_shadow_page); |
| 122 | 122 | ||
| 123 | if (!early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) { | ||
| 124 | int ret = kasan_init_shadow_page_tables(k_start, k_end); | ||
| 125 | |||
| 126 | if (ret) | ||
| 127 | panic("kasan: kasan_init_shadow_page_tables() failed"); | ||
| 128 | } | ||
| 129 | for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { | 123 | for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { |
| 130 | pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); | 124 | pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); |
| 131 | pte_t *ptep = pte_offset_kernel(pmd, k_cur); | 125 | pte_t *ptep = pte_offset_kernel(pmd, k_cur); |
| @@ -143,7 +137,8 @@ void __init kasan_mmu_init(void) · 11 unmodified lines | |||
| 143 | int ret; | 137 | int ret; |
| 144 | struct memblock_region *reg; | 138 | struct memblock_region *reg; |
| 145 | 139 | ||
| 146 | if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) { | 140 | if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE) || |
| 141 | IS_ENABLED(CONFIG_KASAN_VMALLOC)) { | ||
| 147 | ret = kasan_init_shadow_page_tables(KASAN_SHADOW_START, KASAN_SHADOW_END); | 142 | ret = kasan_init_shadow_page_tables(KASAN_SHADOW_START, KASAN_SHADOW_END); |
| 148 | 143 | ||
| 149 | if (ret) | 144 | if (ret) |
| @@ -3268,7 +3268,10 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) · 3267 unmodified lines | |||
| 3268 | /* Initial reset is a superset of the normal reset */ | 3268 | /* Initial reset is a superset of the normal reset */ |
| 3269 | kvm_arch_vcpu_ioctl_normal_reset(vcpu); | 3269 | kvm_arch_vcpu_ioctl_normal_reset(vcpu); |
| 3270 | 3270 | ||
| 3271 | /* this equals initial cpu reset in pop, but we don't switch to ESA */ | 3271 | /* |
| 3272 | * This equals initial cpu reset in pop, but we don't switch to ESA. | ||
| 3273 | * We do not only reset the internal data, but also ... | ||
| 3274 | */ | ||
| 3272 | vcpu->arch.sie_block->gpsw.mask = 0; | 3275 | vcpu->arch.sie_block->gpsw.mask = 0; |
| 3273 | vcpu->arch.sie_block->gpsw.addr = 0; | 3276 | vcpu->arch.sie_block->gpsw.addr = 0; |
| 3274 | kvm_s390_set_prefix(vcpu, 0); | 3277 | kvm_s390_set_prefix(vcpu, 0); |
| @@ -3278,6 +3281,19 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) · 3 unmodified lines | |||
| 3278 | memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr)); | 3281 | memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr)); |
| 3279 | vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK; | 3282 | vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK; |
| 3280 | vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK; | 3283 | vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK; |
| 3284 | |||
| 3285 | /* ... the data in sync regs */ | ||
| 3286 | memset(vcpu->run->s.regs.crs, 0, sizeof(vcpu->run->s.regs.crs)); | ||
| 3287 | vcpu->run->s.regs.ckc = 0; | ||
| 3288 | vcpu->run->s.regs.crs[0] = CR0_INITIAL_MASK; | ||
| 3289 | vcpu->run->s.regs.crs[14] = CR14_INITIAL_MASK; | ||
| 3290 | vcpu->run->psw_addr = 0; | ||
| 3291 | vcpu->run->psw_mask = 0; | ||
| 3292 | vcpu->run->s.regs.todpr = 0; | ||
| 3293 | vcpu->run->s.regs.cputm = 0; | ||
| 3294 | vcpu->run->s.regs.ckc = 0; | ||
| 3295 | vcpu->run->s.regs.pp = 0; | ||
| 3296 | vcpu->run->s.regs.gbea = 1; | ||
| 3281 | vcpu->run->s.regs.fpc = 0; | 3297 | vcpu->run->s.regs.fpc = 0; |
| 3282 | vcpu->arch.sie_block->gbea = 1; | 3298 | vcpu->arch.sie_block->gbea = 1; |
| 3283 | vcpu->arch.sie_block->pp = 0; | 3299 | vcpu->arch.sie_block->pp = 0; |
| @@ -190,15 +190,12 @@ static int amd_uncore_event_init(struct perf_event *event) · 189 unmodified lines | |||
| 190 | 190 | ||
| 191 | /* | 191 | /* |
| 192 | * NB and Last level cache counters (MSRs) are shared across all cores | 192 | * NB and Last level cache counters (MSRs) are shared across all cores |
| 193 | * that share the same NB / Last level cache. Interrupts can be directed | 193 | * that share the same NB / Last level cache. On family 16h and below, |
| 194 | * to a single target core, however, event counts generated by processes | 194 | * Interrupts can be directed to a single target core, however, event |
| 195 | * running on other cores cannot be masked out. So we do not support | 195 | * counts generated by processes running on other cores cannot be masked |
| 196 | * sampling and per-thread events. | 196 | * out. So we do not support sampling and per-thread events via |
| 197 | * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: | ||
| 197 | */ | 198 | */ |
| 198 | if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) | ||
| 199 | return -EINVAL; | ||
| 200 | |||
| 201 | /* and we do not enable counter overflow interrupts */ | ||
| 202 | hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; | 199 | hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; |
| 203 | hwc->idx = -1; | 200 | hwc->idx = -1; |
| 204 | 201 | ||
| @@ -306,7 +303,7 @@ static struct pmu amd_nb_pmu = { · 101 unmodified lines | |||
| 306 | .start = amd_uncore_start, | 303 | .start = amd_uncore_start, |
| 307 | .stop = amd_uncore_stop, | 304 | .stop = amd_uncore_stop, |
| 308 | .read = amd_uncore_read, | 305 | .read = amd_uncore_read, |
| 309 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE, | 306 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, |
| 310 | }; | 307 | }; |
| 311 | 308 | ||
| 312 | static struct pmu amd_llc_pmu = { | 309 | static struct pmu amd_llc_pmu = { |
| @@ -317,7 +314,7 @@ static struct pmu amd_llc_pmu = { · 4 unmodified lines | |||
| 317 | .start = amd_uncore_start, | 314 | .start = amd_uncore_start, |
| 318 | .stop = amd_uncore_stop, | 315 | .stop = amd_uncore_stop, |
| 319 | .read = amd_uncore_read, | 316 | .read = amd_uncore_read, |
| 320 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE, | 317 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, |
| 321 | }; | 318 | }; |
| 322 | 319 | ||
| 323 | static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) | 320 | static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) |
| @@ -360,7 +360,6 @@ struct x86_emulate_ctxt { · 359 unmodified lines | |||
| 360 | u64 d; | 360 | u64 d; |
| 361 | unsigned long _eip; | 361 | unsigned long _eip; |
| 362 | struct operand memop; | 362 | struct operand memop; |
| 363 | /* Fields above regs are cleared together. */ | ||
| 364 | unsigned long _regs[NR_VCPU_REGS]; | 363 | unsigned long _regs[NR_VCPU_REGS]; |
| 365 | struct operand *memopp; | 364 | struct operand *memopp; |
| 366 | struct fetch_cache fetch; | 365 | struct fetch_cache fetch; |
| @@ -838,13 +838,15 @@ static void free_moved_vector(struct apic_chip_data *apicd) · 837 unmodified lines | |||
| 838 | bool managed = apicd->is_managed; | 838 | bool managed = apicd->is_managed; |
| 839 | 839 | ||
| 840 | /* | 840 | /* |
| 841 | * This should never happen. Managed interrupts are not | 841 | * Managed interrupts are usually not migrated away |
| 842 | * migrated except on CPU down, which does not involve the | 842 | * from an online CPU, but CPU isolation 'managed_irq' |
| 843 | * cleanup vector. But try to keep the accounting correct | 843 | * can make that happen. |
| 844 | * nevertheless. | 844 | * 1) Activation does not take the isolation into account |
| 845 | * to keep the code simple | ||
| 846 | * 2) Migration away from an isolated CPU can happen when | ||
| 847 | * a non-isolated CPU which is in the calculated | ||
| 848 | * affinity mask comes online. | ||
| 845 | */ | 849 | */ |
| 846 | WARN_ON_ONCE(managed); | ||
| 847 | |||
| 848 | trace_vector_free_moved(apicd->irq, cpu, vector, managed); | 850 | trace_vector_free_moved(apicd->irq, cpu, vector, managed); |
| 849 | irq_matrix_free(vector_matrix, cpu, vector, managed); | 851 | irq_matrix_free(vector_matrix, cpu, vector, managed); |
| 850 | per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED; | 852 | per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED; |
| @@ -493,17 +493,18 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) · 492 unmodified lines | |||
| 493 | return; | 493 | return; |
| 494 | 494 | ||
| 495 | if ((val & 3UL) == 1UL) { | 495 | if ((val & 3UL) == 1UL) { |
| 496 | /* PPIN available but disabled: */ | 496 | /* PPIN locked in disabled mode */ |
| 497 | return; | 497 | return; |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | /* If PPIN is disabled, but not locked, try to enable: */ | 500 | /* If PPIN is disabled, try to enable */ |
| 501 | if (!(val & 3UL)) { | 501 | if (!(val & 2UL)) { |
| 502 | wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); | 502 | wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); |
| 503 | rdmsrl_safe(MSR_PPIN_CTL, &val); | 503 | rdmsrl_safe(MSR_PPIN_CTL, &val); |
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | if ((val & 3UL) == 2UL) | 506 | /* Is the enable bit set? */ |
| 507 | if (val & 2UL) | ||
| 507 | set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); | 508 | set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); |
| 508 | } | 509 | } |
| 509 | } | 510 | } |
| @@ -486,9 +486,14 @@ static int thermal_throttle_offline(unsigned int cpu) · 485 unmodified lines | |||
| 486 | { | 486 | { |
| 487 | struct thermal_state *state = &per_cpu(thermal_state, cpu); | 487 | struct thermal_state *state = &per_cpu(thermal_state, cpu); |
| 488 | struct device *dev = get_cpu_device(cpu); | 488 | struct device *dev = get_cpu_device(cpu); |
| 489 | u32 l; | ||
| 490 | |||
| 491 | /* Mask the thermal vector before draining evtl. pending work */ | ||
| 492 | l = apic_read(APIC_LVTTHMR); | ||
| 493 | apic_write(APIC_LVTTHMR, l | APIC_LVT_MASKED); | ||
| 489 | 494 | ||
| 490 | cancel_delayed_work(&state->package_throttle.therm_work); | 495 | cancel_delayed_work_sync(&state->package_throttle.therm_work); |
| 491 | cancel_delayed_work(&state->core_throttle.therm_work); | 496 | cancel_delayed_work_sync(&state->core_throttle.therm_work); |
| 492 | 497 | ||
| 493 | state->package_throttle.rate_control_active = false; | 498 | state->package_throttle.rate_control_active = false; |
| 494 | state->core_throttle.rate_control_active = false; | 499 | state->core_throttle.rate_control_active = false; |
| @@ -68,7 +68,7 @@ config KVM_WERROR · 67 unmodified lines | |||
| 68 | depends on (X86_64 && !KASAN) || !COMPILE_TEST | 68 | depends on (X86_64 && !KASAN) || !COMPILE_TEST |
| 69 | depends on EXPERT | 69 | depends on EXPERT |
| 70 | help | 70 | help |
| 71 | Add -Werror to the build flags for (and only for) i915.ko. | 71 | Add -Werror to the build flags for KVM. |
| 72 | 72 | ||
| 73 | If in doubt, say "N". | 73 | If in doubt, say "N". |
| 74 | 74 | ||
| @@ -5173,6 +5173,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) · 5172 unmodified lines | |||
| 5173 | ctxt->fetch.ptr = ctxt->fetch.data; | 5173 | ctxt->fetch.ptr = ctxt->fetch.data; |
| 5174 | ctxt->fetch.end = ctxt->fetch.data + insn_len; | 5174 | ctxt->fetch.end = ctxt->fetch.data + insn_len; |
| 5175 | ctxt->opcode_len = 1; | 5175 | ctxt->opcode_len = 1; |
| 5176 | ctxt->intercept = x86_intercept_none; | ||
| 5176 | if (insn_len > 0) | 5177 | if (insn_len > 0) |
| 5177 | memcpy(ctxt->fetch.data, insn, insn_len); | 5178 | memcpy(ctxt->fetch.data, insn, insn_len); |
| 5178 | else { | 5179 | else { |
| @@ -378,12 +378,15 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) · 377 unmodified lines | |||
| 378 | if (e->fields.delivery_mode == APIC_DM_FIXED) { | 378 | if (e->fields.delivery_mode == APIC_DM_FIXED) { |
| 379 | struct kvm_lapic_irq irq; | 379 | struct kvm_lapic_irq irq; |
| 380 | 380 | ||
| 381 | irq.shorthand = APIC_DEST_NOSHORT; | ||
| 382 | irq.vector = e->fields.vector; | 381 | irq.vector = e->fields.vector; |
| 383 | irq.delivery_mode = e->fields.delivery_mode << 8; | 382 | irq.delivery_mode = e->fields.delivery_mode << 8; |
| 384 | irq.dest_id = e->fields.dest_id; | ||
| 385 | irq.dest_mode = | 383 | irq.dest_mode = |
| 386 | kvm_lapic_irq_dest_mode(!!e->fields.dest_mode); | 384 | kvm_lapic_irq_dest_mode(!!e->fields.dest_mode); |
| 385 | irq.level = false; | ||
| 386 | irq.trig_mode = e->fields.trig_mode; | ||
| 387 | irq.shorthand = APIC_DEST_NOSHORT; | ||
| 388 | irq.dest_id = e->fields.dest_id; | ||
| 389 | irq.msi_redir_hint = false; | ||
| 387 | bitmap_zero(&vcpu_bitmap, 16); | 390 | bitmap_zero(&vcpu_bitmap, 16); |
| 388 | kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq, | 391 | kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq, |
| 389 | &vcpu_bitmap); | 392 | &vcpu_bitmap); |
| @@ -6312,7 +6312,8 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu, · 6311 unmodified lines | |||
| 6312 | enum exit_fastpath_completion *exit_fastpath) | 6312 | enum exit_fastpath_completion *exit_fastpath) |
| 6313 | { | 6313 | { |
| 6314 | if (!is_guest_mode(vcpu) && | 6314 | if (!is_guest_mode(vcpu) && |
| 6315 | to_svm(vcpu)->vmcb->control.exit_code == EXIT_REASON_MSR_WRITE) | 6315 | to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && |
| 6316 | to_svm(vcpu)->vmcb->control.exit_info_1) | ||
| 6316 | *exit_fastpath = handle_fastpath_set_msr_irqoff(vcpu); | 6317 | *exit_fastpath = handle_fastpath_set_msr_irqoff(vcpu); |
| 6317 | } | 6318 | } |
| 6318 | 6319 | ||
| @@ -224,7 +224,7 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu) · 223 unmodified lines | |||
| 224 | return; | 224 | return; |
| 225 | 225 | ||
| 226 | kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true); | 226 | kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true); |
| 227 | vmx->nested.hv_evmcs_vmptr = -1ull; | 227 | vmx->nested.hv_evmcs_vmptr = 0; |
| 228 | vmx->nested.hv_evmcs = NULL; | 228 | vmx->nested.hv_evmcs = NULL; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| @@ -1923,7 +1923,8 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu, · 1692 unmodified lines | |||
| 1923 | if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa)) | 1923 | if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa)) |
| 1924 | return 1; | 1924 | return 1; |
| 1925 | 1925 | ||
| 1926 | if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { | 1926 | if (unlikely(!vmx->nested.hv_evmcs || |
| 1927 | evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { | ||
| 1927 | if (!vmx->nested.hv_evmcs) | 1928 | if (!vmx->nested.hv_evmcs) |
| 1928 | vmx->nested.current_vmptr = -1ull; | 1929 | vmx->nested.current_vmptr = -1ull; |
| 1929 | 1930 | ||
| @@ -2338,6 +2338,17 @@ static void hardware_disable(void) · 2337 unmodified lines | |||
| 2338 | kvm_cpu_vmxoff(); | 2338 | kvm_cpu_vmxoff(); |
| 2339 | } | 2339 | } |
| 2340 | 2340 | ||
| 2341 | /* | ||
| 2342 | * There is no X86_FEATURE for SGX yet, but anyway we need to query CPUID | ||
| 2343 | * directly instead of going through cpu_has(), to ensure KVM is trapping | ||
| 2344 | * ENCLS whenever it's supported in hardware. It does not matter whether | ||
| 2345 | * the host OS supports or has enabled SGX. | ||
| 2346 | */ | ||
| 2347 | static bool cpu_has_sgx(void) | ||
| 2348 | { | ||
| 2349 | return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0)); | ||
| 2350 | } | ||
| 2351 | |||
| 2341 | static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, | 2352 | static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, |
| 2342 | u32 msr, u32 *result) | 2353 | u32 msr, u32 *result) |
| 2343 | { | 2354 | { |
| @@ -2418,8 +2429,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, · 74 unmodified lines | |||
| 2418 | SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | | 2429 | SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | |
| 2419 | SECONDARY_EXEC_PT_USE_GPA | | 2430 | SECONDARY_EXEC_PT_USE_GPA | |
| 2420 | SECONDARY_EXEC_PT_CONCEAL_VMX | | 2431 | SECONDARY_EXEC_PT_CONCEAL_VMX | |
| 2421 | SECONDARY_EXEC_ENABLE_VMFUNC | | 2432 | SECONDARY_EXEC_ENABLE_VMFUNC; |
| 2422 | SECONDARY_EXEC_ENCLS_EXITING; | 2433 | if (cpu_has_sgx()) |
| 2434 | opt2 |= SECONDARY_EXEC_ENCLS_EXITING; | ||
| 2423 | if (adjust_vmx_controls(min2, opt2, | 2435 | if (adjust_vmx_controls(min2, opt2, |
| 2424 | MSR_IA32_VMX_PROCBASED_CTLS2, | 2436 | MSR_IA32_VMX_PROCBASED_CTLS2, |
| 2425 | &_cpu_based_2nd_exec_control) < 0) | 2437 | &_cpu_based_2nd_exec_control) < 0) |
| @@ -7195,10 +7195,12 @@ static void kvm_timer_init(void) · 7194 unmodified lines | |||
| 7195 | 7195 | ||
| 7196 | cpu = get_cpu(); | 7196 | cpu = get_cpu(); |
| 7197 | policy = cpufreq_cpu_get(cpu); | 7197 | policy = cpufreq_cpu_get(cpu); |
| 7198 | if (policy && policy->cpuinfo.max_freq) | 7198 | if (policy) { |
| 7199 | max_tsc_khz = policy->cpuinfo.max_freq; | 7199 | if (policy->cpuinfo.max_freq) |
| 7200 | max_tsc_khz = policy->cpuinfo.max_freq; | ||
| 7201 | cpufreq_cpu_put(policy); | ||
| 7202 | } | ||
| 7200 | put_cpu(); | 7203 | put_cpu(); |
| 7201 | cpufreq_cpu_put(policy); | ||
| 7202 | #endif | 7204 | #endif |
| 7203 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, | 7205 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, |
| 7204 | CPUFREQ_TRANSITION_NOTIFIER); | 7206 | CPUFREQ_TRANSITION_NOTIFIER); |
| @@ -190,7 +190,7 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) · 189 unmodified lines | |||
| 190 | return pmd_k; | 190 | return pmd_k; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | void vmalloc_sync_all(void) | 193 | static void vmalloc_sync(void) |
| 194 | { | 194 | { |
| 195 | unsigned long address; | 195 | unsigned long address; |
| 196 | 196 | ||
| @@ -217,6 +217,16 @@ void vmalloc_sync_all(void) · 20 unmodified lines | |||
| 217 | } | 217 | } |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | void vmalloc_sync_mappings(void) | ||
| 221 | { | ||
| 222 | vmalloc_sync(); | ||
| 223 | } | ||
| 224 | |||
| 225 | void vmalloc_sync_unmappings(void) | ||
| 226 | { | ||
| 227 | vmalloc_sync(); | ||
| 228 | } | ||
| 229 | |||
| 220 | /* | 230 | /* |
| 221 | * 32-bit: | 231 | * 32-bit: |
| 222 | * | 232 | * |
| @@ -319,11 +329,23 @@ out: · 96 unmodified lines | |||
| 319 | 329 | ||
| 320 | #else /* CONFIG_X86_64: */ | 330 | #else /* CONFIG_X86_64: */ |
| 321 | 331 | ||
| 322 | void vmalloc_sync_all(void) | 332 | void vmalloc_sync_mappings(void) |
| 323 | { | 333 | { |
| 334 | /* | ||
| 335 | * 64-bit mappings might allocate new p4d/pud pages | ||
| 336 | * that need to be propagated to all tasks' PGDs. | ||
| 337 | */ | ||
| 324 | sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END); | 338 | sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END); |
| 325 | } | 339 | } |
| 326 | 340 | ||
| 341 | void vmalloc_sync_unmappings(void) | ||
| 342 | { | ||
| 343 | /* | ||
| 344 | * Unmappings never allocate or free p4d/pud pages. | ||
| 345 | * No work is required here. | ||
| 346 | */ | ||
| 347 | } | ||
| 348 | |||
| 327 | /* | 349 | /* |
| 328 | * 64-bit: | 350 | * 64-bit: |
| 329 | * | 351 | * |
| @@ -106,6 +106,22 @@ static unsigned int __ioremap_check_encrypted(struct resource *res) · 105 unmodified lines | |||
| 106 | return 0; | 106 | return 0; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | /* | ||
| 110 | * The EFI runtime services data area is not covered by walk_mem_res(), but must | ||
| 111 | * be mapped encrypted when SEV is active. | ||
| 112 | */ | ||
| 113 | static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *desc) | ||
| 114 | { | ||
| 115 | if (!sev_active()) | ||
| 116 | return; | ||
| 117 | |||
| 118 | if (!IS_ENABLED(CONFIG_EFI)) | ||
| 119 | return; | ||
| 120 | |||
| 121 | if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA) | ||
| 122 | desc->flags |= IORES_MAP_ENCRYPTED; | ||
| 123 | } | ||
| 124 | |||
| 109 | static int __ioremap_collect_map_flags(struct resource *res, void *arg) | 125 | static int __ioremap_collect_map_flags(struct resource *res, void *arg) |
| 110 | { | 126 | { |
| 111 | struct ioremap_desc *desc = arg; | 127 | struct ioremap_desc *desc = arg; |
| @@ -124,6 +140,9 @@ static int __ioremap_collect_map_flags(struct resource *res, void *arg) · 12 unmodified lines | |||
| 124 | * To avoid multiple resource walks, this function walks resources marked as | 140 | * To avoid multiple resource walks, this function walks resources marked as |
| 125 | * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a | 141 | * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a |
| 126 | * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). | 142 | * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). |
| 143 | * | ||
| 144 | * After that, deal with misc other ranges in __ioremap_check_other() which do | ||
| 145 | * not fall into the above category. | ||
| 127 | */ | 146 | */ |
| 128 | static void __ioremap_check_mem(resource_size_t addr, unsigned long size, | 147 | static void __ioremap_check_mem(resource_size_t addr, unsigned long size, |
| 129 | struct ioremap_desc *desc) | 148 | struct ioremap_desc *desc) |
| @@ -135,6 +154,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size, · 5 unmodified lines | |||
| 135 | memset(desc, 0, sizeof(struct ioremap_desc)); | 154 | memset(desc, 0, sizeof(struct ioremap_desc)); |
| 136 | 155 | ||
| 137 | walk_mem_res(start, end, desc, __ioremap_collect_map_flags); | 156 | walk_mem_res(start, end, desc, __ioremap_collect_map_flags); |
| 157 | |||
| 158 | __ioremap_check_other(addr, desc); | ||
| 138 | } | 159 | } |
| 139 | 160 | ||
| 140 | /* | 161 | /* |
| @@ -2039,10 +2039,12 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, · 2038 unmodified lines | |||
| 2039 | } | 2039 | } |
| 2040 | /* and dreg_lo,sreg_lo */ | 2040 | /* and dreg_lo,sreg_lo */ |
| 2041 | EMIT2(0x23, add_2reg(0xC0, sreg_lo, dreg_lo)); | 2041 | EMIT2(0x23, add_2reg(0xC0, sreg_lo, dreg_lo)); |
| 2042 | /* and dreg_hi,sreg_hi */ | 2042 | if (is_jmp64) { |
| 2043 | EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); | 2043 | /* and dreg_hi,sreg_hi */ |
| 2044 | /* or dreg_lo,dreg_hi */ | 2044 | EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); |
| 2045 | EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); | 2045 | /* or dreg_lo,dreg_hi */ |
| 2046 | EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); | ||
| 2047 | } | ||
| 2046 | goto emit_cond_jmp; | 2048 | goto emit_cond_jmp; |
| 2047 | } | 2049 | } |
| 2048 | case BPF_JMP | BPF_JSET | BPF_K: | 2050 | case BPF_JMP | BPF_JSET | BPF_K: |
| @@ -1318,7 +1318,7 @@ static bool iocg_is_idle(struct ioc_gq *iocg) · 1317 unmodified lines | |||
| 1318 | return false; | 1318 | return false; |
| 1319 | 1319 | ||
| 1320 | /* is something in flight? */ | 1320 | /* is something in flight? */ |
| 1321 | if (atomic64_read(&iocg->done_vtime) < atomic64_read(&iocg->vtime)) | 1321 | if (atomic64_read(&iocg->done_vtime) != atomic64_read(&iocg->vtime)) |
| 1322 | return false; | 1322 | return false; |
| 1323 | 1323 | ||
| 1324 | return true; | 1324 | return true; |
| @@ -398,6 +398,28 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head, · 397 unmodified lines | |||
| 398 | WARN_ON(e && (rq->tag != -1)); | 398 | WARN_ON(e && (rq->tag != -1)); |
| 399 | 399 | ||
| 400 | if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) { | 400 | if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) { |
| 401 | /* | ||
| 402 | * Firstly normal IO request is inserted to scheduler queue or | ||
| 403 | * sw queue, meantime we add flush request to dispatch queue( | ||
| 404 | * hctx->dispatch) directly and there is at most one in-flight | ||
| 405 | * flush request for each hw queue, so it doesn't matter to add | ||
| 406 | * flush request to tail or front of the dispatch queue. | ||
| 407 | * | ||
| 408 | * Secondly in case of NCQ, flush request belongs to non-NCQ | ||
| 409 | * command, and queueing it will fail when there is any | ||
| 410 | * in-flight normal IO request(NCQ command). When adding flush | ||
| 411 | * rq to the front of hctx->dispatch, it is easier to introduce | ||
| 412 | * extra time to flush rq's latency because of S_SCHED_RESTART | ||
| 413 | * compared with adding to the tail of dispatch queue, then | ||
| 414 | * chance of flush merge is increased, and less flush requests | ||
| 415 | * will be issued to controller. It is observed that ~10% time | ||
| 416 | * is saved in blktests block/004 on disk attached to AHCI/NCQ | ||
| 417 | * drive when adding flush rq to the front of hctx->dispatch. | ||
| 418 | * | ||
| 419 | * Simply queue flush rq to the front of hctx->dispatch so that | ||
| 420 | * intensive flush workloads can benefit in case of NCQ HW. | ||
| 421 | */ | ||
| 422 | at_head = (rq->rq_flags & RQF_FLUSH_SEQ) ? true : at_head; | ||
| 401 | blk_mq_request_bypass_insert(rq, at_head, false); | 423 | blk_mq_request_bypass_insert(rq, at_head, false); |
| 402 | goto run; | 424 | goto run; |
| 403 | } | 425 | } |
| @@ -301,6 +301,42 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) · 300 unmodified lines | |||
| 301 | } | 301 | } |
| 302 | EXPORT_SYMBOL_GPL(disk_map_sector_rcu); | 302 | EXPORT_SYMBOL_GPL(disk_map_sector_rcu); |
| 303 | 303 | ||
| 304 | /** | ||
| 305 | * disk_has_partitions | ||
| 306 | * @disk: gendisk of interest | ||
| 307 | * | ||
| 308 | * Walk through the partition table and check if valid partition exists. | ||
| 309 | * | ||
| 310 | * CONTEXT: | ||
| 311 | * Don't care. | ||
| 312 | * | ||
| 313 | * RETURNS: | ||
| 314 | * True if the gendisk has at least one valid non-zero size partition. | ||
| 315 | * Otherwise false. | ||
| 316 | */ | ||
| 317 | bool disk_has_partitions(struct gendisk *disk) | ||
| 318 | { | ||
| 319 | struct disk_part_tbl *ptbl; | ||
| 320 | int i; | ||
| 321 | bool ret = false; | ||
| 322 | |||
| 323 | rcu_read_lock(); | ||
| 324 | ptbl = rcu_dereference(disk->part_tbl); | ||
| 325 | |||
| 326 | /* Iterate partitions skipping the whole device at index 0 */ | ||
| 327 | for (i = 1; i < ptbl->len; i++) { | ||
| 328 | if (rcu_dereference(ptbl->part[i])) { | ||
| 329 | ret = true; | ||
| 330 | break; | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | rcu_read_unlock(); | ||
| 335 | |||
| 336 | return ret; | ||
| 337 | } | ||
| 338 | EXPORT_SYMBOL_GPL(disk_has_partitions); | ||
| 339 | |||
| 304 | /* | 340 | /* |
| 305 | * Can be deleted altogether. Later. | 341 | * Can be deleted altogether. Later. |
| 306 | * | 342 | * |
| @@ -171,7 +171,7 @@ int ghes_estatus_pool_init(int num_ghes) · 170 unmodified lines | |||
| 171 | * New allocation must be visible in all pgd before it can be found by | 171 | * New allocation must be visible in all pgd before it can be found by |
| 172 | * an NMI allocating from the pool. | 172 | * an NMI allocating from the pool. |
| 173 | */ | 173 | */ |
| 174 | vmalloc_sync_all(); | 174 | vmalloc_sync_mappings(); |
| 175 | 175 | ||
| 176 | rc = gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1); | 176 | rc = gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1); |
| 177 | if (rc) | 177 | if (rc) |
| @@ -448,6 +448,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb) · 447 unmodified lines | |||
| 448 | inode->i_uid = info->root_uid; | 448 | inode->i_uid = info->root_uid; |
| 449 | inode->i_gid = info->root_gid; | 449 | inode->i_gid = info->root_gid; |
| 450 | 450 | ||
| 451 | refcount_set(&device->ref, 1); | ||
| 451 | device->binderfs_inode = inode; | 452 | device->binderfs_inode = inode; |
| 452 | device->miscdev.minor = minor; | 453 | device->miscdev.minor = minor; |
| 453 | 454 | ||
| @@ -4713,7 +4713,7 @@ EXPORT_SYMBOL(of_clk_get_by_name); · 4712 unmodified lines | |||
| 4713 | * | 4713 | * |
| 4714 | * Returns: The number of clocks that are possible parents of this node | 4714 | * Returns: The number of clocks that are possible parents of this node |
| 4715 | */ | 4715 | */ |
| 4716 | unsigned int of_clk_get_parent_count(struct device_node *np) | 4716 | unsigned int of_clk_get_parent_count(const struct device_node *np) |
| 4717 | { | 4717 | { |
| 4718 | int count; | 4718 | int count; |
| 4719 | 4719 | ||
| @@ -4725,7 +4725,7 @@ unsigned int of_clk_get_parent_count(struct device_node *np) · 5 unmodified lines | |||
| 4725 | } | 4725 | } |
| 4726 | EXPORT_SYMBOL_GPL(of_clk_get_parent_count); | 4726 | EXPORT_SYMBOL_GPL(of_clk_get_parent_count); |
| 4727 | 4727 | ||
| 4728 | const char *of_clk_get_parent_name(struct device_node *np, int index) | 4728 | const char *of_clk_get_parent_name(const struct device_node *np, int index) |
| 4729 | { | 4729 | { |
| 4730 | struct of_phandle_args clkspec; | 4730 | struct of_phandle_args clkspec; |
| 4731 | struct property *prop; | 4731 | struct property *prop; |
| @@ -592,24 +592,6 @@ static struct clk_branch disp_cc_mdss_rot_clk = { · 591 unmodified lines | |||
| 592 | }, | 592 | }, |
| 593 | }; | 593 | }; |
| 594 | 594 | ||
| 595 | static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { | ||
| 596 | .halt_reg = 0x400c, | ||
| 597 | .halt_check = BRANCH_HALT, | ||
| 598 | .clkr = { | ||
| 599 | .enable_reg = 0x400c, | ||
| 600 | .enable_mask = BIT(0), | ||
| 601 | .hw.init = &(struct clk_init_data){ | ||
| 602 | .name = "disp_cc_mdss_rscc_ahb_clk", | ||
| 603 | .parent_data = &(const struct clk_parent_data){ | ||
| 604 | .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw, | ||
| 605 | }, | ||
| 606 | .num_parents = 1, | ||
| 607 | .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, | ||
| 608 | .ops = &clk_branch2_ops, | ||
| 609 | }, | ||
| 610 | }, | ||
| 611 | }; | ||
| 612 | |||
| 613 | static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { | 595 | static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { |
| 614 | .halt_reg = 0x4008, | 596 | .halt_reg = 0x4008, |
| 615 | .halt_check = BRANCH_HALT, | 597 | .halt_check = BRANCH_HALT, |
| @@ -687,7 +669,6 @@ static struct clk_regmap *disp_cc_sc7180_clocks[] = { · 71 unmodified lines | |||
| 687 | [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, | 669 | [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, |
| 688 | [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, | 670 | [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, |
| 689 | [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, | 671 | [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, |
| 690 | [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, | ||
| 691 | [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, | 672 | [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, |
| 692 | [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, | 673 | [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, |
| 693 | [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, | 674 | [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, |
| @@ -97,7 +97,7 @@ static struct clk_branch video_cc_vcodec0_axi_clk = { · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | static struct clk_branch video_cc_vcodec0_core_clk = { | 98 | static struct clk_branch video_cc_vcodec0_core_clk = { |
| 99 | .halt_reg = 0x890, | 99 | .halt_reg = 0x890, |
| 100 | .halt_check = BRANCH_HALT, | 100 | .halt_check = BRANCH_HALT_VOTED, |
| 101 | .clkr = { | 101 | .clkr = { |
| 102 | .enable_reg = 0x890, | 102 | .enable_reg = 0x890, |
| 103 | .enable_mask = BIT(0), | 103 | .enable_mask = BIT(0), |
| @@ -1151,7 +1151,7 @@ int dma_async_device_register(struct dma_device *device) · 1150 unmodified lines | |||
| 1151 | } | 1151 | } |
| 1152 | 1152 | ||
| 1153 | if (!device->device_release) | 1153 | if (!device->device_release) |
| 1154 | dev_warn(device->dev, | 1154 | dev_dbg(device->dev, |
| 1155 | "WARN: Device release is not defined so it is not safe to unbind this driver while in use\n"); | 1155 | "WARN: Device release is not defined so it is not safe to unbind this driver while in use\n"); |
| 1156 | 1156 | ||
| 1157 | kref_init(&device->ref); | 1157 | kref_init(&device->ref); |
| @@ -81,9 +81,9 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) · 80 unmodified lines | |||
| 81 | dev = &idxd->pdev->dev; | 81 | dev = &idxd->pdev->dev; |
| 82 | idxd_cdev = &wq->idxd_cdev; | 82 | idxd_cdev = &wq->idxd_cdev; |
| 83 | 83 | ||
| 84 | dev_dbg(dev, "%s called\n", __func__); | 84 | dev_dbg(dev, "%s called: %d\n", __func__, idxd_wq_refcount(wq)); |
| 85 | 85 | ||
| 86 | if (idxd_wq_refcount(wq) > 1 && wq_dedicated(wq)) | 86 | if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq)) |
| 87 | return -EBUSY; | 87 | return -EBUSY; |
| 88 | 88 | ||
| 89 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 89 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
| @@ -564,12 +564,12 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, · 563 unmodified lines | |||
| 564 | if (IS_ERR(flow->udma_rflow)) { | 564 | if (IS_ERR(flow->udma_rflow)) { |
| 565 | ret = PTR_ERR(flow->udma_rflow); | 565 | ret = PTR_ERR(flow->udma_rflow); |
| 566 | dev_err(dev, "UDMAX rflow get err %d\n", ret); | 566 | dev_err(dev, "UDMAX rflow get err %d\n", ret); |
| 567 | goto err; | 567 | return ret; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | if (flow->udma_rflow_id != xudma_rflow_get_id(flow->udma_rflow)) { | 570 | if (flow->udma_rflow_id != xudma_rflow_get_id(flow->udma_rflow)) { |
| 571 | xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow); | 571 | ret = -ENODEV; |
| 572 | return -ENODEV; | 572 | goto err_rflow_put; |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | /* request and cfg rings */ | 575 | /* request and cfg rings */ |
| @@ -578,7 +578,7 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, · 2 unmodified lines | |||
| 578 | if (!flow->ringrx) { | 578 | if (!flow->ringrx) { |
| 579 | ret = -ENODEV; | 579 | ret = -ENODEV; |
| 580 | dev_err(dev, "Failed to get RX ring\n"); | 580 | dev_err(dev, "Failed to get RX ring\n"); |
| 581 | goto err; | 581 | goto err_rflow_put; |
| 582 | } | 582 | } |
| 583 | 583 | ||
| 584 | flow->ringrxfdq = k3_ringacc_request_ring(rx_chn->common.ringacc, | 584 | flow->ringrxfdq = k3_ringacc_request_ring(rx_chn->common.ringacc, |
| @@ -586,19 +586,19 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, · 1 unmodified line | |||
| 586 | if (!flow->ringrxfdq) { | 586 | if (!flow->ringrxfdq) { |
| 587 | ret = -ENODEV; | 587 | ret = -ENODEV; |
| 588 | dev_err(dev, "Failed to get RXFDQ ring\n"); | 588 | dev_err(dev, "Failed to get RXFDQ ring\n"); |
| 589 | goto err; | 589 | goto err_ringrx_free; |
| 590 | } | 590 | } |
| 591 | 591 | ||
| 592 | ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg); | 592 | ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg); |
| 593 | if (ret) { | 593 | if (ret) { |
| 594 | dev_err(dev, "Failed to cfg ringrx %d\n", ret); | 594 | dev_err(dev, "Failed to cfg ringrx %d\n", ret); |
| 595 | goto err; | 595 | goto err_ringrxfdq_free; |
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | ret = k3_ringacc_ring_cfg(flow->ringrxfdq, &flow_cfg->rxfdq_cfg); | 598 | ret = k3_ringacc_ring_cfg(flow->ringrxfdq, &flow_cfg->rxfdq_cfg); |
| 599 | if (ret) { | 599 | if (ret) { |
| 600 | dev_err(dev, "Failed to cfg ringrxfdq %d\n", ret); | 600 | dev_err(dev, "Failed to cfg ringrxfdq %d\n", ret); |
| 601 | goto err; | 601 | goto err_ringrxfdq_free; |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | if (rx_chn->remote) { | 604 | if (rx_chn->remote) { |
| @@ -648,7 +648,7 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, · 43 unmodified lines | |||
| 648 | if (ret) { | 648 | if (ret) { |
| 649 | dev_err(dev, "flow%d config failed: %d\n", flow->udma_rflow_id, | 649 | dev_err(dev, "flow%d config failed: %d\n", flow->udma_rflow_id, |
| 650 | ret); | 650 | ret); |
| 651 | goto err; | 651 | goto err_ringrxfdq_free; |
| 652 | } | 652 | } |
| 653 | 653 | ||
| 654 | rx_chn->flows_ready++; | 654 | rx_chn->flows_ready++; |
| @@ -656,8 +656,17 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, · 1 unmodified line | |||
| 656 | flow->udma_rflow_id, rx_chn->flows_ready); | 656 | flow->udma_rflow_id, rx_chn->flows_ready); |
| 657 | 657 | ||
| 658 | return 0; | 658 | return 0; |
| 659 | err: | 659 | |
| 660 | k3_udma_glue_release_rx_flow(rx_chn, flow_idx); | 660 | err_ringrxfdq_free: |
| 661 | k3_ringacc_ring_free(flow->ringrxfdq); | ||
| 662 | |||
| 663 | err_ringrx_free: | ||
| 664 | k3_ringacc_ring_free(flow->ringrx); | ||
| 665 | |||
| 666 | err_rflow_put: | ||
| 667 | xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow); | ||
| 668 | flow->udma_rflow = NULL; | ||
| 669 | |||
| 661 | return ret; | 670 | return ret; |
| 662 | } | 671 | } |
| 663 | 672 | ||
| @@ -83,13 +83,16 @@ static ssize_t · 82 unmodified lines | |||
| 83 | efivar_attr_read(struct efivar_entry *entry, char *buf) | 83 | efivar_attr_read(struct efivar_entry *entry, char *buf) |
| 84 | { | 84 | { |
| 85 | struct efi_variable *var = &entry->var; | 85 | struct efi_variable *var = &entry->var; |
| 86 | unsigned long size = sizeof(var->Data); | ||
| 86 | char *str = buf; | 87 | char *str = buf; |
| 88 | int ret; | ||
| 87 | 89 | ||
| 88 | if (!entry || !buf) | 90 | if (!entry || !buf) |
| 89 | return -EINVAL; | 91 | return -EINVAL; |
| 90 | 92 | ||
| 91 | var->DataSize = 1024; | 93 | ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); |
| 92 | if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | 94 | var->DataSize = size; |
| 95 | if (ret) | ||
| 93 | return -EIO; | 96 | return -EIO; |
| 94 | 97 | ||
| 95 | if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) | 98 | if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) |
| @@ -116,13 +119,16 @@ static ssize_t · 20 unmodified lines | |||
| 116 | efivar_size_read(struct efivar_entry *entry, char *buf) | 119 | efivar_size_read(struct efivar_entry *entry, char *buf) |
| 117 | { | 120 | { |
| 118 | struct efi_variable *var = &entry->var; | 121 | struct efi_variable *var = &entry->var; |
| 122 | unsigned long size = sizeof(var->Data); | ||
| 119 | char *str = buf; | 123 | char *str = buf; |
| 124 | int ret; | ||
| 120 | 125 | ||
| 121 | if (!entry || !buf) | 126 | if (!entry || !buf) |
| 122 | return -EINVAL; | 127 | return -EINVAL; |
| 123 | 128 | ||
| 124 | var->DataSize = 1024; | 129 | ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); |
| 125 | if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | 130 | var->DataSize = size; |
| 131 | if (ret) | ||
| 126 | return -EIO; | 132 | return -EIO; |
| 127 | 133 | ||
| 128 | str += sprintf(str, "0x%lx\n", var->DataSize); | 134 | str += sprintf(str, "0x%lx\n", var->DataSize); |
| @@ -133,12 +139,15 @@ static ssize_t · 4 unmodified lines | |||
| 133 | efivar_data_read(struct efivar_entry *entry, char *buf) | 139 | efivar_data_read(struct efivar_entry *entry, char *buf) |
| 134 | { | 140 | { |
| 135 | struct efi_variable *var = &entry->var; | 141 | struct efi_variable *var = &entry->var; |
| 142 | unsigned long size = sizeof(var->Data); | ||
| 143 | int ret; | ||
| 136 | 144 | ||
| 137 | if (!entry || !buf) | 145 | if (!entry || !buf) |
| 138 | return -EINVAL; | 146 | return -EINVAL; |
| 139 | 147 | ||
| 140 | var->DataSize = 1024; | 148 | ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); |
| 141 | if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | 149 | var->DataSize = size; |
| 150 | if (ret) | ||
| 142 | return -EIO; | 151 | return -EIO; |
| 143 | 152 | ||
| 144 | memcpy(buf, var->Data, var->DataSize); | 153 | memcpy(buf, var->Data, var->DataSize); |
| @@ -199,6 +208,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) · 54 unmodified lines | |||
| 199 | u8 *data; | 208 | u8 *data; |
| 200 | int err; | 209 | int err; |
| 201 | 210 | ||
| 211 | if (!entry || !buf) | ||
| 212 | return -EINVAL; | ||
| 213 | |||
| 202 | if (in_compat_syscall()) { | 214 | if (in_compat_syscall()) { |
| 203 | struct compat_efi_variable *compat; | 215 | struct compat_efi_variable *compat; |
| 204 | 216 | ||
| @@ -250,14 +262,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) · 45 unmodified lines | |||
| 250 | { | 262 | { |
| 251 | struct efi_variable *var = &entry->var; | 263 | struct efi_variable *var = &entry->var; |
| 252 | struct compat_efi_variable *compat; | 264 | struct compat_efi_variable *compat; |
| 265 | unsigned long datasize = sizeof(var->Data); | ||
| 253 | size_t size; | 266 | size_t size; |
| 267 | int ret; | ||
| 254 | 268 | ||
| 255 | if (!entry || !buf) | 269 | if (!entry || !buf) |
| 256 | return 0; | 270 | return 0; |
| 257 | 271 | ||
| 258 | var->DataSize = 1024; | 272 | ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); |
| 259 | if (efivar_entry_get(entry, &entry->var.Attributes, | 273 | var->DataSize = datasize; |
| 260 | &entry->var.DataSize, entry->var.Data)) | 274 | if (ret) |
| 261 | return -EIO; | 275 | return -EIO; |
| 262 | 276 | ||
| 263 | if (in_compat_syscall()) { | 277 | if (in_compat_syscall()) { |
| @@ -21,18 +21,21 @@ · 20 unmodified lines | |||
| 21 | #include "gpiolib.h" | 21 | #include "gpiolib.h" |
| 22 | #include "gpiolib-acpi.h" | 22 | #include "gpiolib-acpi.h" |
| 23 | 23 | ||
| 24 | #define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l | ||
| 25 | #define QUIRK_NO_WAKEUP 0x02l | ||
| 26 | |||
| 27 | static int run_edge_events_on_boot = -1; | 24 | static int run_edge_events_on_boot = -1; |
| 28 | module_param(run_edge_events_on_boot, int, 0444); | 25 | module_param(run_edge_events_on_boot, int, 0444); |
| 29 | MODULE_PARM_DESC(run_edge_events_on_boot, | 26 | MODULE_PARM_DESC(run_edge_events_on_boot, |
| 30 | "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); | 27 | "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); |
| 31 | 28 | ||
| 32 | static int honor_wakeup = -1; | 29 | static char *ignore_wake; |
| 33 | module_param(honor_wakeup, int, 0444); | 30 | module_param(ignore_wake, charp, 0444); |
| 34 | MODULE_PARM_DESC(honor_wakeup, | 31 | MODULE_PARM_DESC(ignore_wake, |
| 35 | "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto"); | 32 | "controller@pin combos on which to ignore the ACPI wake flag " |
| 33 | "ignore_wake=controller@pin[,controller@pin[,...]]"); | ||
| 34 | |||
| 35 | struct acpi_gpiolib_dmi_quirk { | ||
| 36 | bool no_edge_events_on_boot; | ||
| 37 | char *ignore_wake; | ||
| 38 | }; | ||
| 36 | 39 | ||
| 37 | /** | 40 | /** |
| 38 | * struct acpi_gpio_event - ACPI GPIO event handler data | 41 | * struct acpi_gpio_event - ACPI GPIO event handler data |
| @@ -202,6 +205,57 @@ static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio) · 163 unmodified lines | |||
| 202 | acpi_gpiochip_request_irq(acpi_gpio, event); | 205 | acpi_gpiochip_request_irq(acpi_gpio, event); |
| 203 | } | 206 | } |
| 204 | 207 | ||
| 208 | static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in) | ||
| 209 | { | ||
| 210 | const char *controller, *pin_str; | ||
| 211 | int len, pin; | ||
| 212 | char *endp; | ||
| 213 | |||
| 214 | controller = ignore_wake; | ||
| 215 | while (controller) { | ||
| 216 | pin_str = strchr(controller, '@'); | ||
| 217 | if (!pin_str) | ||
| 218 | goto err; | ||
| 219 | |||
| 220 | len = pin_str - controller; | ||
| 221 | if (len == strlen(controller_in) && | ||
| 222 | strncmp(controller, controller_in, len) == 0) { | ||
| 223 | pin = simple_strtoul(pin_str + 1, &endp, 10); | ||
| 224 | if (*endp != 0 && *endp != ',') | ||
| 225 | goto err; | ||
| 226 | |||
| 227 | if (pin == pin_in) | ||
| 228 | return true; | ||
| 229 | } | ||
| 230 | |||
| 231 | controller = strchr(controller, ','); | ||
| 232 | if (controller) | ||
| 233 | controller++; | ||
| 234 | } | ||
| 235 | |||
| 236 | return false; | ||
| 237 | err: | ||
| 238 | pr_err_once("Error invalid value for gpiolib_acpi.ignore_wake: %s\n", | ||
| 239 | ignore_wake); | ||
| 240 | return false; | ||
| 241 | } | ||
| 242 | |||
| 243 | static bool acpi_gpio_irq_is_wake(struct device *parent, | ||
| 244 | struct acpi_resource_gpio *agpio) | ||
| 245 | { | ||
| 246 | int pin = agpio->pin_table[0]; | ||
| 247 | |||
| 248 | if (agpio->wake_capable != ACPI_WAKE_CAPABLE) | ||
| 249 | return false; | ||
| 250 | |||
| 251 | if (acpi_gpio_in_ignore_list(dev_name(parent), pin)) { | ||
| 252 | dev_info(parent, "Ignoring wakeup on pin %d\n", pin); | ||
| 253 | return false; | ||
| 254 | } | ||
| 255 | |||
| 256 | return true; | ||
| 257 | } | ||
| 258 | |||
| 205 | /* Always returns AE_OK so that we keep looping over the resources */ | 259 | /* Always returns AE_OK so that we keep looping over the resources */ |
| 206 | static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, | 260 | static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, |
| 207 | void *context) | 261 | void *context) |
| @@ -289,7 +343,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, · 81 unmodified lines | |||
| 289 | event->handle = evt_handle; | 343 | event->handle = evt_handle; |
| 290 | event->handler = handler; | 344 | event->handler = handler; |
| 291 | event->irq = irq; | 345 | event->irq = irq; |
| 292 | event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE; | 346 | event->irq_is_wake = acpi_gpio_irq_is_wake(chip->parent, agpio); |
| 293 | event->pin = pin; | 347 | event->pin = pin; |
| 294 | event->desc = desc; | 348 | event->desc = desc; |
| 295 | 349 | ||
| @@ -1328,7 +1382,9 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = { · 1032 unmodified lines | |||
| 1328 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), | 1382 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), |
| 1329 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), | 1383 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), |
| 1330 | }, | 1384 | }, |
| 1331 | .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, | 1385 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
| 1386 | .no_edge_events_on_boot = true, | ||
| 1387 | }, | ||
| 1332 | }, | 1388 | }, |
| 1333 | { | 1389 | { |
| 1334 | /* | 1390 | /* |
| @@ -1341,16 +1397,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = { · 6 unmodified lines | |||
| 1341 | DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), | 1397 | DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), |
| 1342 | DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), | 1398 | DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), |
| 1343 | }, | 1399 | }, |
| 1344 | .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, | 1400 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
| 1401 | .no_edge_events_on_boot = true, | ||
| 1402 | }, | ||
| 1345 | }, | 1403 | }, |
| 1346 | { | 1404 | { |
| 1347 | /* | 1405 | /* |
| 1348 | * Various HP X2 10 Cherry Trail models use an external | 1406 | * HP X2 10 models with Cherry Trail SoC + TI PMIC use an |
| 1349 | * embedded-controller connected via I2C + an ACPI GPIO | 1407 | * external embedded-controller connected via I2C + an ACPI GPIO |
| 1350 | * event handler. The embedded controller generates various | 1408 | * event handler on INT33FF:01 pin 0, causing spurious wakeups. |
| 1351 | * spurious wakeup events when suspended. So disable wakeup | 1409 | * When suspending by closing the LID, the power to the USB |
| 1352 | * for its handler (it uses the only ACPI GPIO event handler). | 1410 | * keyboard is turned off, causing INT0002 ACPI events to |
| 1353 | * This breaks wakeup when opening the lid, the user needs | 1411 | * trigger once the XHCI controller notices the keyboard is |
| 1412 | * gone. So INT0002 events cause spurious wakeups too. Ignoring | ||
| 1413 | * EC wakes breaks wakeup when opening the lid, the user needs | ||
| 1354 | * to press the power-button to wakeup the system. The | 1414 | * to press the power-button to wakeup the system. The |
| 1355 | * alternative is suspend simply not working, which is worse. | 1415 | * alternative is suspend simply not working, which is worse. |
| 1356 | */ | 1416 | */ |
| @@ -1358,33 +1418,61 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = { · 1 unmodified line | |||
| 1358 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), | 1418 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
| 1359 | DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), | 1419 | DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), |
| 1360 | }, | 1420 | }, |
| 1361 | .driver_data = (void *)QUIRK_NO_WAKEUP, | 1421 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
| 1422 | .ignore_wake = "INT33FF:01@0,INT0002:00@2", | ||
| 1423 | }, | ||
| 1424 | }, | ||
| 1425 | { | ||
| 1426 | /* | ||
| 1427 | * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an | ||
| 1428 | * external embedded-controller connected via I2C + an ACPI GPIO | ||
| 1429 | * event handler on INT33FC:02 pin 28, causing spurious wakeups. | ||
| 1430 | */ | ||
| 1431 | .matches = { | ||
| 1432 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 1433 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), | ||
| 1434 | DMI_MATCH(DMI_BOARD_NAME, "815D"), | ||
| 1435 | }, | ||
| 1436 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { | ||
| 1437 | .ignore_wake = "INT33FC:02@28", | ||
| 1438 | }, | ||
| 1439 | }, | ||
| 1440 | { | ||
| 1441 | /* | ||
| 1442 | * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an | ||
| 1443 | * external embedded-controller connected via I2C + an ACPI GPIO | ||
| 1444 | * event handler on INT33FF:01 pin 0, causing spurious wakeups. | ||
| 1445 | */ | ||
| 1446 | .matches = { | ||
| 1447 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), | ||
| 1448 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), | ||
| 1449 | DMI_MATCH(DMI_BOARD_NAME, "813E"), | ||
| 1450 | }, | ||
| 1451 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { | ||
| 1452 | .ignore_wake = "INT33FF:01@0", | ||
| 1453 | }, | ||
| 1362 | }, | 1454 | }, |
| 1363 | {} /* Terminating entry */ | 1455 | {} /* Terminating entry */ |
| 1364 | }; | 1456 | }; |
| 1365 | 1457 | ||
| 1366 | static int acpi_gpio_setup_params(void) | 1458 | static int acpi_gpio_setup_params(void) |
| 1367 | { | 1459 | { |
| 1460 | const struct acpi_gpiolib_dmi_quirk *quirk = NULL; | ||
| 1368 | const struct dmi_system_id *id; | 1461 | const struct dmi_system_id *id; |
| 1369 | long quirks = 0; | ||
| 1370 | 1462 | ||
| 1371 | id = dmi_first_match(gpiolib_acpi_quirks); | 1463 | id = dmi_first_match(gpiolib_acpi_quirks); |
| 1372 | if (id) | 1464 | if (id) |
| 1373 | quirks = (long)id->driver_data; | 1465 | quirk = id->driver_data; |
| 1374 | 1466 | ||
| 1375 | if (run_edge_events_on_boot < 0) { | 1467 | if (run_edge_events_on_boot < 0) { |
| 1376 | if (quirks & QUIRK_NO_EDGE_EVENTS_ON_BOOT) | 1468 | if (quirk && quirk->no_edge_events_on_boot) |
| 1377 | run_edge_events_on_boot = 0; | 1469 | run_edge_events_on_boot = 0; |
| 1378 | else | 1470 | else |
| 1379 | run_edge_events_on_boot = 1; | 1471 | run_edge_events_on_boot = 1; |
| 1380 | } | 1472 | } |
| 1381 | 1473 | ||
| 1382 | if (honor_wakeup < 0) { | 1474 | if (ignore_wake == NULL && quirk && quirk->ignore_wake) |
| 1383 | if (quirks & QUIRK_NO_WAKEUP) | 1475 | ignore_wake = quirk->ignore_wake; |
| 1384 | honor_wakeup = 0; | ||
| 1385 | else | ||
| 1386 | honor_wakeup = 1; | ||
| 1387 | } | ||
| 1388 | 1476 | ||
| 1389 | return 0; | 1477 | return 0; |
| 1390 | } | 1478 | } |
| @@ -2306,9 +2306,16 @@ static void gpiochip_irq_disable(struct irq_data *d) · 2305 unmodified lines | |||
| 2306 | { | 2306 | { |
| 2307 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); | 2307 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d); |
| 2308 | 2308 | ||
| 2309 | /* | ||
| 2310 | * Since we override .irq_disable() we need to mimic the | ||
| 2311 | * behaviour of __irq_disable() in irq/chip.c. | ||
| 2312 | * First call .irq_disable() if it exists, else mimic the | ||
| 2313 | * behaviour of mask_irq() which calls .irq_mask() if | ||
| 2314 | * it exists. | ||
| 2315 | */ | ||
| 2309 | if (chip->irq.irq_disable) | 2316 | if (chip->irq.irq_disable) |
| 2310 | chip->irq.irq_disable(d); | 2317 | chip->irq.irq_disable(d); |
| 2311 | else | 2318 | else if (chip->irq.chip->irq_mask) |
| 2312 | chip->irq.chip->irq_mask(d); | 2319 | chip->irq.chip->irq_mask(d); |
| 2313 | gpiochip_disable_irq(chip, d->hwirq); | 2320 | gpiochip_disable_irq(chip, d->hwirq); |
| 2314 | } | 2321 | } |
| @@ -781,11 +781,11 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, · 780 unmodified lines | |||
| 781 | ssize_t result = 0; | 781 | ssize_t result = 0; |
| 782 | uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; | 782 | uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; |
| 783 | 783 | ||
| 784 | if (size & 3 || *pos & 3) | 784 | if (size > 4096 || size & 3 || *pos & 3) |
| 785 | return -EINVAL; | 785 | return -EINVAL; |
| 786 | 786 | ||
| 787 | /* decode offset */ | 787 | /* decode offset */ |
| 788 | offset = *pos & GENMASK_ULL(11, 0); | 788 | offset = (*pos & GENMASK_ULL(11, 0)) >> 2; |
| 789 | se = (*pos & GENMASK_ULL(19, 12)) >> 12; | 789 | se = (*pos & GENMASK_ULL(19, 12)) >> 12; |
| 790 | sh = (*pos & GENMASK_ULL(27, 20)) >> 20; | 790 | sh = (*pos & GENMASK_ULL(27, 20)) >> 20; |
| 791 | cu = (*pos & GENMASK_ULL(35, 28)) >> 28; | 791 | cu = (*pos & GENMASK_ULL(35, 28)) >> 28; |
| @@ -823,7 +823,7 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, · 31 unmodified lines | |||
| 823 | while (size) { | 823 | while (size) { |
| 824 | uint32_t value; | 824 | uint32_t value; |
| 825 | 825 | ||
| 826 | value = data[offset++]; | 826 | value = data[result >> 2]; |
| 827 | r = put_user(value, (uint32_t *)buf); | 827 | r = put_user(value, (uint32_t *)buf); |
| 828 | if (r) { | 828 | if (r) { |
| 829 | result = r; | 829 | result = r; |
| @@ -3913,6 +3913,8 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, · 3912 unmodified lines | |||
| 3913 | if (r) | 3913 | if (r) |
| 3914 | goto out; | 3914 | goto out; |
| 3915 | 3915 | ||
| 3916 | amdgpu_fbdev_set_suspend(tmp_adev, 0); | ||
| 3917 | |||
| 3916 | /* must succeed. */ | 3918 | /* must succeed. */ |
| 3917 | amdgpu_ras_resume(tmp_adev); | 3919 | amdgpu_ras_resume(tmp_adev); |
| 3918 | 3920 | ||
| @@ -4086,6 +4088,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 167 unmodified lines | |||
| 4086 | */ | 4088 | */ |
| 4087 | amdgpu_unregister_gpu_instance(tmp_adev); | 4089 | amdgpu_unregister_gpu_instance(tmp_adev); |
| 4088 | 4090 | ||
| 4091 | amdgpu_fbdev_set_suspend(adev, 1); | ||
| 4092 | |||
| 4089 | /* disable ras on ALL IPs */ | 4093 | /* disable ras on ALL IPs */ |
| 4090 | if (!(in_ras_intr && !use_baco) && | 4094 | if (!(in_ras_intr && !use_baco) && |
| 4091 | amdgpu_device_ip_need_full_reset(tmp_adev)) | 4095 | amdgpu_device_ip_need_full_reset(tmp_adev)) |
| @@ -693,7 +693,7 @@ static int jpeg_v2_0_set_clockgating_state(void *handle, · 692 unmodified lines | |||
| 693 | bool enable = (state == AMD_CG_STATE_GATE); | 693 | bool enable = (state == AMD_CG_STATE_GATE); |
| 694 | 694 | ||
| 695 | if (enable) { | 695 | if (enable) { |
| 696 | if (jpeg_v2_0_is_idle(handle)) | 696 | if (!jpeg_v2_0_is_idle(handle)) |
| 697 | return -EBUSY; | 697 | return -EBUSY; |
| 698 | jpeg_v2_0_enable_clock_gating(adev); | 698 | jpeg_v2_0_enable_clock_gating(adev); |
| 699 | } else { | 699 | } else { |
| @@ -477,7 +477,7 @@ static int jpeg_v2_5_set_clockgating_state(void *handle, · 476 unmodified lines | |||
| 477 | continue; | 477 | continue; |
| 478 | 478 | ||
| 479 | if (enable) { | 479 | if (enable) { |
| 480 | if (jpeg_v2_5_is_idle(handle)) | 480 | if (!jpeg_v2_5_is_idle(handle)) |
| 481 | return -EBUSY; | 481 | return -EBUSY; |
| 482 | jpeg_v2_5_enable_clock_gating(adev, i); | 482 | jpeg_v2_5_enable_clock_gating(adev, i); |
| 483 | } else { | 483 | } else { |
| @@ -1352,7 +1352,7 @@ static int vcn_v1_0_set_clockgating_state(void *handle, · 1351 unmodified lines | |||
| 1352 | 1352 | ||
| 1353 | if (enable) { | 1353 | if (enable) { |
| 1354 | /* wait for STATUS to clear */ | 1354 | /* wait for STATUS to clear */ |
| 1355 | if (vcn_v1_0_is_idle(handle)) | 1355 | if (!vcn_v1_0_is_idle(handle)) |
| 1356 | return -EBUSY; | 1356 | return -EBUSY; |
| 1357 | vcn_v1_0_enable_clock_gating(adev); | 1357 | vcn_v1_0_enable_clock_gating(adev); |
| 1358 | } else { | 1358 | } else { |
| @@ -1217,7 +1217,7 @@ static int vcn_v2_0_set_clockgating_state(void *handle, · 1216 unmodified lines | |||
| 1217 | 1217 | ||
| 1218 | if (enable) { | 1218 | if (enable) { |
| 1219 | /* wait for STATUS to clear */ | 1219 | /* wait for STATUS to clear */ |
| 1220 | if (vcn_v2_0_is_idle(handle)) | 1220 | if (!vcn_v2_0_is_idle(handle)) |
| 1221 | return -EBUSY; | 1221 | return -EBUSY; |
| 1222 | vcn_v2_0_enable_clock_gating(adev); | 1222 | vcn_v2_0_enable_clock_gating(adev); |
| 1223 | } else { | 1223 | } else { |
| @@ -1672,7 +1672,7 @@ static int vcn_v2_5_set_clockgating_state(void *handle, · 1671 unmodified lines | |||
| 1672 | return 0; | 1672 | return 0; |
| 1673 | 1673 | ||
| 1674 | if (enable) { | 1674 | if (enable) { |
| 1675 | if (vcn_v2_5_is_idle(handle)) | 1675 | if (!vcn_v2_5_is_idle(handle)) |
| 1676 | return -EBUSY; | 1676 | return -EBUSY; |
| 1677 | vcn_v2_5_enable_clock_gating(adev); | 1677 | vcn_v2_5_enable_clock_gating(adev); |
| 1678 | } else { | 1678 | } else { |
| @@ -522,8 +522,9 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 521 unmodified lines | |||
| 522 | 522 | ||
| 523 | acrtc_state = to_dm_crtc_state(acrtc->base.state); | 523 | acrtc_state = to_dm_crtc_state(acrtc->base.state); |
| 524 | 524 | ||
| 525 | DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, | 525 | DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, |
| 526 | amdgpu_dm_vrr_active(acrtc_state)); | 526 | amdgpu_dm_vrr_active(acrtc_state), |
| 527 | acrtc_state->active_planes); | ||
| 527 | 528 | ||
| 528 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); | 529 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); |
| 529 | drm_crtc_handle_vblank(&acrtc->base); | 530 | drm_crtc_handle_vblank(&acrtc->base); |
| @@ -543,7 +544,18 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 13 unmodified lines | |||
| 543 | &acrtc_state->vrr_params.adjust); | 544 | &acrtc_state->vrr_params.adjust); |
| 544 | } | 545 | } |
| 545 | 546 | ||
| 546 | if (acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED) { | 547 | /* |
| 548 | * If there aren't any active_planes then DCH HUBP may be clock-gated. | ||
| 549 | * In that case, pageflip completion interrupts won't fire and pageflip | ||
| 550 | * completion events won't get delivered. Prevent this by sending | ||
| 551 | * pending pageflip events from here if a flip is still pending. | ||
| 552 | * | ||
| 553 | * If any planes are enabled, use dm_pflip_high_irq() instead, to | ||
| 554 | * avoid race conditions between flip programming and completion, | ||
| 555 | * which could cause too early flip completion events. | ||
| 556 | */ | ||
| 557 | if (acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && | ||
| 558 | acrtc_state->active_planes == 0) { | ||
| 547 | if (acrtc->event) { | 559 | if (acrtc->event) { |
| 548 | drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); | 560 | drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); |
| 549 | acrtc->event = NULL; | 561 | acrtc->event = NULL; |
| @@ -3401,6 +3401,17 @@ static bool retrieve_link_cap(struct dc_link *link) · 3400 unmodified lines | |||
| 3401 | sink_id.ieee_device_id, | 3401 | sink_id.ieee_device_id, |
| 3402 | sizeof(sink_id.ieee_device_id)); | 3402 | sizeof(sink_id.ieee_device_id)); |
| 3403 | 3403 | ||
| 3404 | /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */ | ||
| 3405 | { | ||
| 3406 | uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 }; | ||
| 3407 | |||
| 3408 | if ((link->dpcd_caps.sink_dev_id == 0x0010fa) && | ||
| 3409 | !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017, | ||
| 3410 | sizeof(str_mbp_2017))) { | ||
| 3411 | link->reported_link_cap.link_rate = 0x0c; | ||
| 3412 | } | ||
| 3413 | } | ||
| 3414 | |||
| 3404 | core_link_read_dpcd( | 3415 | core_link_read_dpcd( |
| 3405 | link, | 3416 | link, |
| 3406 | DP_SINK_HW_REVISION_START, | 3417 | DP_SINK_HW_REVISION_START, |
| @@ -108,7 +108,6 @@ static const struct hwseq_private_funcs dcn20_private_funcs = { · 107 unmodified lines | |||
| 108 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, | 108 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, |
| 109 | .dpp_pg_control = dcn20_dpp_pg_control, | 109 | .dpp_pg_control = dcn20_dpp_pg_control, |
| 110 | .hubp_pg_control = dcn20_hubp_pg_control, | 110 | .hubp_pg_control = dcn20_hubp_pg_control, |
| 111 | .dsc_pg_control = NULL, | ||
| 112 | .update_odm = dcn20_update_odm, | 111 | .update_odm = dcn20_update_odm, |
| 113 | .dsc_pg_control = dcn20_dsc_pg_control, | 112 | .dsc_pg_control = dcn20_dsc_pg_control, |
| 114 | .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, | 113 | .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, |
| @@ -116,7 +116,6 @@ static const struct hwseq_private_funcs dcn21_private_funcs = { · 115 unmodified lines | |||
| 116 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, | 116 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, |
| 117 | .dpp_pg_control = dcn20_dpp_pg_control, | 117 | .dpp_pg_control = dcn20_dpp_pg_control, |
| 118 | .hubp_pg_control = dcn20_hubp_pg_control, | 118 | .hubp_pg_control = dcn20_hubp_pg_control, |
| 119 | .dsc_pg_control = NULL, | ||
| 120 | .update_odm = dcn20_update_odm, | 119 | .update_odm = dcn20_update_odm, |
| 121 | .dsc_pg_control = dcn20_dsc_pg_control, | 120 | .dsc_pg_control = dcn20_dsc_pg_control, |
| 122 | .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, | 121 | .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, |
| @@ -146,14 +146,14 @@ static const struct of_device_id komeda_of_match[] = { · 145 unmodified lines | |||
| 146 | 146 | ||
| 147 | MODULE_DEVICE_TABLE(of, komeda_of_match); | 147 | MODULE_DEVICE_TABLE(of, komeda_of_match); |
| 148 | 148 | ||
| 149 | static int komeda_rt_pm_suspend(struct device *dev) | 149 | static int __maybe_unused komeda_rt_pm_suspend(struct device *dev) |
| 150 | { | 150 | { |
| 151 | struct komeda_drv *mdrv = dev_get_drvdata(dev); | 151 | struct komeda_drv *mdrv = dev_get_drvdata(dev); |
| 152 | 152 | ||
| 153 | return komeda_dev_suspend(mdrv->mdev); | 153 | return komeda_dev_suspend(mdrv->mdev); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | static int komeda_rt_pm_resume(struct device *dev) | 156 | static int __maybe_unused komeda_rt_pm_resume(struct device *dev) |
| 157 | { | 157 | { |
| 158 | struct komeda_drv *mdrv = dev_get_drvdata(dev); | 158 | struct komeda_drv *mdrv = dev_get_drvdata(dev); |
| 159 | 159 | ||
| @@ -156,10 +156,8 @@ int bochs_hw_init(struct drm_device *dev) · 155 unmodified lines | |||
| 156 | size = min(size, mem); | 156 | size = min(size, mem); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | if (pci_request_region(pdev, 0, "bochs-drm") != 0) { | 159 | if (pci_request_region(pdev, 0, "bochs-drm") != 0) |
| 160 | DRM_ERROR("Cannot request framebuffer\n"); | 160 | DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); |
| 161 | return -EBUSY; | ||
| 162 | } | ||
| 163 | 161 | ||
| 164 | bochs->fb_map = ioremap(addr, size); | 162 | bochs->fb_map = ioremap(addr, size); |
| 165 | if (bochs->fb_map == NULL) { | 163 | if (bochs->fb_map == NULL) { |
| @@ -1624,28 +1624,34 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) · 1623 unmodified lines | |||
| 1624 | frame.colorspace = HDMI_COLORSPACE_RGB; | 1624 | frame.colorspace = HDMI_COLORSPACE_RGB; |
| 1625 | 1625 | ||
| 1626 | /* Set up colorimetry */ | 1626 | /* Set up colorimetry */ |
| 1627 | switch (hdmi->hdmi_data.enc_out_encoding) { | 1627 | if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { |
| 1628 | case V4L2_YCBCR_ENC_601: | 1628 | switch (hdmi->hdmi_data.enc_out_encoding) { |
| 1629 | if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) | 1629 | case V4L2_YCBCR_ENC_601: |
| 1630 | frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | 1630 | if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) |
| 1631 | else | 1631 | frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; |
| 1632 | else | ||
| 1633 | frame.colorimetry = HDMI_COLORIMETRY_ITU_601; | ||
| 1634 | frame.extended_colorimetry = | ||
| 1635 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | ||
| 1636 | break; | ||
| 1637 | case V4L2_YCBCR_ENC_709: | ||
| 1638 | if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) | ||
| 1639 | frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | ||
| 1640 | else | ||
| 1641 | frame.colorimetry = HDMI_COLORIMETRY_ITU_709; | ||
| 1642 | frame.extended_colorimetry = | ||
| 1643 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; | ||
| 1644 | break; | ||
| 1645 | default: /* Carries no data */ | ||
| 1632 | frame.colorimetry = HDMI_COLORIMETRY_ITU_601; | 1646 | frame.colorimetry = HDMI_COLORIMETRY_ITU_601; |
| 1647 | frame.extended_colorimetry = | ||
| 1648 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | ||
| 1649 | break; | ||
| 1650 | } | ||
| 1651 | } else { | ||
| 1652 | frame.colorimetry = HDMI_COLORIMETRY_NONE; | ||
| 1633 | frame.extended_colorimetry = | 1653 | frame.extended_colorimetry = |
| 1634 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | 1654 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; |
| 1635 | break; | ||
| 1636 | case V4L2_YCBCR_ENC_709: | ||
| 1637 | if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) | ||
| 1638 | frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | ||
| 1639 | else | ||
| 1640 | frame.colorimetry = HDMI_COLORIMETRY_ITU_709; | ||
| 1641 | frame.extended_colorimetry = | ||
| 1642 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; | ||
| 1643 | break; | ||
| 1644 | default: /* Carries no data */ | ||
| 1645 | frame.colorimetry = HDMI_COLORIMETRY_ITU_601; | ||
| 1646 | frame.extended_colorimetry = | ||
| 1647 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | ||
| 1648 | break; | ||
| 1649 | } | 1655 | } |
| 1650 | 1656 | ||
| 1651 | frame.scan_mode = HDMI_SCAN_MODE_NONE; | 1657 | frame.scan_mode = HDMI_SCAN_MODE_NONE; |
| @@ -542,10 +542,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, · 541 unmodified lines | |||
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | DRM_DEBUG_LEASE("Creating lease\n"); | 544 | DRM_DEBUG_LEASE("Creating lease\n"); |
| 545 | /* lessee will take the ownership of leases */ | ||
| 545 | lessee = drm_lease_create(lessor, &leases); | 546 | lessee = drm_lease_create(lessor, &leases); |
| 546 | 547 | ||
| 547 | if (IS_ERR(lessee)) { | 548 | if (IS_ERR(lessee)) { |
| 548 | ret = PTR_ERR(lessee); | 549 | ret = PTR_ERR(lessee); |
| 550 | idr_destroy(&leases); | ||
| 549 | goto out_leases; | 551 | goto out_leases; |
| 550 | } | 552 | } |
| 551 | 553 | ||
| @@ -580,7 +582,6 @@ out_lessee: · 28 unmodified lines | |||
| 580 | 582 | ||
| 581 | out_leases: | 583 | out_leases: |
| 582 | put_unused_fd(fd); | 584 | put_unused_fd(fd); |
| 583 | idr_destroy(&leases); | ||
| 584 | 585 | ||
| 585 | DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); | 586 | DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); |
| 586 | return ret; | 587 | return ret; |
| @@ -1600,17 +1600,6 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve, · 1599 unmodified lines | |||
| 1600 | spin_unlock(&old->breadcrumbs.irq_lock); | 1600 | spin_unlock(&old->breadcrumbs.irq_lock); |
| 1601 | } | 1601 | } |
| 1602 | 1602 | ||
| 1603 | static struct i915_request * | ||
| 1604 | last_active(const struct intel_engine_execlists *execlists) | ||
| 1605 | { | ||
| 1606 | struct i915_request * const *last = READ_ONCE(execlists->active); | ||
| 1607 | |||
| 1608 | while (*last && i915_request_completed(*last)) | ||
| 1609 | last++; | ||
| 1610 | |||
| 1611 | return *last; | ||
| 1612 | } | ||
| 1613 | |||
| 1614 | #define for_each_waiter(p__, rq__) \ | 1603 | #define for_each_waiter(p__, rq__) \ |
| 1615 | list_for_each_entry_lockless(p__, \ | 1604 | list_for_each_entry_lockless(p__, \ |
| 1616 | &(rq__)->sched.waiters_list, \ | 1605 | &(rq__)->sched.waiters_list, \ |
| @@ -1740,11 +1729,9 @@ static void record_preemption(struct intel_engine_execlists *execlists) · 123 unmodified lines | |||
| 1740 | (void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++); | 1729 | (void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++); |
| 1741 | } | 1730 | } |
| 1742 | 1731 | ||
| 1743 | static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) | 1732 | static unsigned long active_preempt_timeout(struct intel_engine_cs *engine, |
| 1733 | const struct i915_request *rq) | ||
| 1744 | { | 1734 | { |
| 1745 | struct i915_request *rq; | ||
| 1746 | |||
| 1747 | rq = last_active(&engine->execlists); | ||
| 1748 | if (!rq) | 1735 | if (!rq) |
| 1749 | return 0; | 1736 | return 0; |
| 1750 | 1737 | ||
| @@ -1755,13 +1742,14 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) · 4 unmodified lines | |||
| 1755 | return READ_ONCE(engine->props.preempt_timeout_ms); | 1742 | return READ_ONCE(engine->props.preempt_timeout_ms); |
| 1756 | } | 1743 | } |
| 1757 | 1744 | ||
| 1758 | static void set_preempt_timeout(struct intel_engine_cs *engine) | 1745 | static void set_preempt_timeout(struct intel_engine_cs *engine, |
| 1746 | const struct i915_request *rq) | ||
| 1759 | { | 1747 | { |
| 1760 | if (!intel_engine_has_preempt_reset(engine)) | 1748 | if (!intel_engine_has_preempt_reset(engine)) |
| 1761 | return; | 1749 | return; |
| 1762 | 1750 | ||
| 1763 | set_timer_ms(&engine->execlists.preempt, | 1751 | set_timer_ms(&engine->execlists.preempt, |
| 1764 | active_preempt_timeout(engine)); | 1752 | active_preempt_timeout(engine, rq)); |
| 1765 | } | 1753 | } |
| 1766 | 1754 | ||
| 1767 | static inline void clear_ports(struct i915_request **ports, int count) | 1755 | static inline void clear_ports(struct i915_request **ports, int count) |
| @@ -1774,6 +1762,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 6 unmodified lines | |||
| 1774 | struct intel_engine_execlists * const execlists = &engine->execlists; | 1762 | struct intel_engine_execlists * const execlists = &engine->execlists; |
| 1775 | struct i915_request **port = execlists->pending; | 1763 | struct i915_request **port = execlists->pending; |
| 1776 | struct i915_request ** const last_port = port + execlists->port_mask; | 1764 | struct i915_request ** const last_port = port + execlists->port_mask; |
| 1765 | struct i915_request * const *active; | ||
| 1777 | struct i915_request *last; | 1766 | struct i915_request *last; |
| 1778 | struct rb_node *rb; | 1767 | struct rb_node *rb; |
| 1779 | bool submit = false; | 1768 | bool submit = false; |
| @@ -1828,7 +1817,10 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 48 unmodified lines | |||
| 1828 | * i.e. we will retrigger preemption following the ack in case | 1817 | * i.e. we will retrigger preemption following the ack in case |
| 1829 | * of trouble. | 1818 | * of trouble. |
| 1830 | */ | 1819 | */ |
| 1831 | last = last_active(execlists); | 1820 | active = READ_ONCE(execlists->active); |
| 1821 | while ((last = *active) && i915_request_completed(last)) | ||
| 1822 | active++; | ||
| 1823 | |||
| 1832 | if (last) { | 1824 | if (last) { |
| 1833 | if (need_preempt(engine, last, rb)) { | 1825 | if (need_preempt(engine, last, rb)) { |
| 1834 | ENGINE_TRACE(engine, | 1826 | ENGINE_TRACE(engine, |
| @@ -2110,7 +2102,7 @@ done: · 275 unmodified lines | |||
| 2110 | * Skip if we ended up with exactly the same set of requests, | 2102 | * Skip if we ended up with exactly the same set of requests, |
| 2111 | * e.g. trying to timeslice a pair of ordered contexts | 2103 | * e.g. trying to timeslice a pair of ordered contexts |
| 2112 | */ | 2104 | */ |
| 2113 | if (!memcmp(execlists->active, execlists->pending, | 2105 | if (!memcmp(active, execlists->pending, |
| 2114 | (port - execlists->pending + 1) * sizeof(*port))) { | 2106 | (port - execlists->pending + 1) * sizeof(*port))) { |
| 2115 | do | 2107 | do |
| 2116 | execlists_schedule_out(fetch_and_zero(port)); | 2108 | execlists_schedule_out(fetch_and_zero(port)); |
| @@ -2121,7 +2113,7 @@ done: · 4 unmodified lines | |||
| 2121 | clear_ports(port + 1, last_port - port); | 2113 | clear_ports(port + 1, last_port - port); |
| 2122 | 2114 | ||
| 2123 | execlists_submit_ports(engine); | 2115 | execlists_submit_ports(engine); |
| 2124 | set_preempt_timeout(engine); | 2116 | set_preempt_timeout(engine, *active); |
| 2125 | } else { | 2117 | } else { |
| 2126 | skip_submit: | 2118 | skip_submit: |
| 2127 | ring_set_paused(engine, 0); | 2119 | ring_set_paused(engine, 0); |
| @@ -4008,26 +4000,6 @@ static int gen12_emit_flush_render(struct i915_request *request, · 1880 unmodified lines | |||
| 4008 | 4000 | ||
| 4009 | *cs++ = preparser_disable(false); | 4001 | *cs++ = preparser_disable(false); |
| 4010 | intel_ring_advance(request, cs); | 4002 | intel_ring_advance(request, cs); |
| 4011 | |||
| 4012 | /* | ||
| 4013 | * Wa_1604544889:tgl | ||
| 4014 | */ | ||
| 4015 | if (IS_TGL_REVID(request->i915, TGL_REVID_A0, TGL_REVID_A0)) { | ||
| 4016 | flags = 0; | ||
| 4017 | flags |= PIPE_CONTROL_CS_STALL; | ||
| 4018 | flags |= PIPE_CONTROL_HDC_PIPELINE_FLUSH; | ||
| 4019 | |||
| 4020 | flags |= PIPE_CONTROL_STORE_DATA_INDEX; | ||
| 4021 | flags |= PIPE_CONTROL_QW_WRITE; | ||
| 4022 | |||
| 4023 | cs = intel_ring_begin(request, 6); | ||
| 4024 | if (IS_ERR(cs)) | ||
| 4025 | return PTR_ERR(cs); | ||
| 4026 | |||
| 4027 | cs = gen8_emit_pipe_control(cs, flags, | ||
| 4028 | LRC_PPHWSP_SCRATCH_ADDR); | ||
| 4029 | intel_ring_advance(request, cs); | ||
| 4030 | } | ||
| 4031 | } | 4003 | } |
| 4032 | 4004 | ||
| 4033 | return 0; | 4005 | return 0; |
| @@ -1529,15 +1529,34 @@ err_obj: · 1528 unmodified lines | |||
| 1529 | return ERR_PTR(err); | 1529 | return ERR_PTR(err); |
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | static const struct { | ||
| 1533 | u32 start; | ||
| 1534 | u32 end; | ||
| 1535 | } mcr_ranges_gen8[] = { | ||
| 1536 | { .start = 0x5500, .end = 0x55ff }, | ||
| 1537 | { .start = 0x7000, .end = 0x7fff }, | ||
| 1538 | { .start = 0x9400, .end = 0x97ff }, | ||
| 1539 | { .start = 0xb000, .end = 0xb3ff }, | ||
| 1540 | { .start = 0xe000, .end = 0xe7ff }, | ||
| 1541 | {}, | ||
| 1542 | }; | ||
| 1543 | |||
| 1532 | static bool mcr_range(struct drm_i915_private *i915, u32 offset) | 1544 | static bool mcr_range(struct drm_i915_private *i915, u32 offset) |
| 1533 | { | 1545 | { |
| 1546 | int i; | ||
| 1547 | |||
| 1548 | if (INTEL_GEN(i915) < 8) | ||
| 1549 | return false; | ||
| 1550 | |||
| 1534 | /* | 1551 | /* |
| 1535 | * Registers in this range are affected by the MCR selector | 1552 | * Registers in these ranges are affected by the MCR selector |
| 1536 | * which only controls CPU initiated MMIO. Routing does not | 1553 | * which only controls CPU initiated MMIO. Routing does not |
| 1537 | * work for CS access so we cannot verify them on this path. | 1554 | * work for CS access so we cannot verify them on this path. |
| 1538 | */ | 1555 | */ |
| 1539 | if (INTEL_GEN(i915) >= 8 && (offset >= 0xb000 && offset <= 0xb4ff)) | 1556 | for (i = 0; mcr_ranges_gen8[i].start; i++) |
| 1540 | return true; | 1557 | if (offset >= mcr_ranges_gen8[i].start && |
| 1558 | offset <= mcr_ranges_gen8[i].end) | ||
| 1559 | return true; | ||
| 1541 | 1560 | ||
| 1542 | return false; | 1561 | return false; |
| 1543 | } | 1562 | } |
| @@ -532,6 +532,8 @@ static const struct hid_device_id hammer_devices[] = { · 531 unmodified lines | |||
| 532 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, | 532 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, |
| 533 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 533 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 534 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, | 534 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, |
| 535 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | ||
| 536 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, | ||
| 535 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 537 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 536 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, | 538 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, |
| 537 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 539 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| @@ -478,6 +478,7 @@ · 477 unmodified lines | |||
| 478 | #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 | 478 | #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 |
| 479 | #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c | 479 | #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c |
| 480 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d | 480 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d |
| 481 | #define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 | ||
| 481 | 482 | ||
| 482 | #define USB_VENDOR_ID_GOTOP 0x08f2 | 483 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
| 483 | #define USB_DEVICE_ID_SUPER_Q2 0x007f | 484 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
| @@ -726,6 +727,7 @@ · 242 unmodified lines | |||
| 726 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 | 727 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 |
| 727 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 | 728 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 |
| 728 | #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 | 729 | #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 |
| 730 | #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d | ||
| 729 | 731 | ||
| 730 | #define USB_VENDOR_ID_LG 0x1fd2 | 732 | #define USB_VENDOR_ID_LG 0x1fd2 |
| 731 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 | 733 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
| @@ -458,9 +458,9 @@ static ssize_t picolcd_fb_update_rate_show(struct device *dev, · 457 unmodified lines | |||
| 458 | if (ret >= PAGE_SIZE) | 458 | if (ret >= PAGE_SIZE) |
| 459 | break; | 459 | break; |
| 460 | else if (i == fb_update_rate) | 460 | else if (i == fb_update_rate) |
| 461 | ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i); | 461 | ret += scnprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i); |
| 462 | else | 462 | else |
| 463 | ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); | 463 | ret += scnprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); |
| 464 | if (ret > 0) | 464 | if (ret > 0) |
| 465 | buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n'; | 465 | buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n'; |
| 466 | return ret; | 466 | return ret; |
| @@ -103,6 +103,7 @@ static const struct hid_device_id hid_quirks[] = { · 102 unmodified lines | |||
| 103 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, | 103 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, |
| 104 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, | 104 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, |
| 105 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, | 105 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, |
| 106 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, | ||
| 106 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, | 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, |
| 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, | 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, |
| 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, | 109 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, |
| @@ -313,7 +313,7 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr, · 312 unmodified lines | |||
| 313 | 313 | ||
| 314 | while (i < ret) { | 314 | while (i < ret) { |
| 315 | if (i + attribute->size > ret) { | 315 | if (i + attribute->size > ret) { |
| 316 | len += snprintf(&buf[len], | 316 | len += scnprintf(&buf[len], |
| 317 | PAGE_SIZE - len, | 317 | PAGE_SIZE - len, |
| 318 | "%d ", values[i]); | 318 | "%d ", values[i]); |
| 319 | break; | 319 | break; |
| @@ -336,10 +336,10 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr, · 16 unmodified lines | |||
| 336 | ++i; | 336 | ++i; |
| 337 | break; | 337 | break; |
| 338 | } | 338 | } |
| 339 | len += snprintf(&buf[len], PAGE_SIZE - len, | 339 | len += scnprintf(&buf[len], PAGE_SIZE - len, |
| 340 | "%lld ", value); | 340 | "%lld ", value); |
| 341 | } | 341 | } |
| 342 | len += snprintf(&buf[len], PAGE_SIZE - len, "\n"); | 342 | len += scnprintf(&buf[len], PAGE_SIZE - len, "\n"); |
| 343 | 343 | ||
| 344 | return len; | 344 | return len; |
| 345 | } else if (input) | 345 | } else if (input) |
| @@ -718,9 +718,6 @@ static int msc_win_set_lockout(struct msc_window *win, · 717 unmodified lines | |||
| 718 | 718 | ||
| 719 | if (old != expect) { | 719 | if (old != expect) { |
| 720 | ret = -EINVAL; | 720 | ret = -EINVAL; |
| 721 | dev_warn_ratelimited(msc_dev(win->msc), | ||
| 722 | "expected lockout state %d, got %d\n", | ||
| 723 | expect, old); | ||
| 724 | goto unlock; | 721 | goto unlock; |
| 725 | } | 722 | } |
| 726 | 723 | ||
| @@ -741,6 +738,10 @@ unlock: · 14 unmodified lines | |||
| 741 | /* from intel_th_msc_window_unlock(), don't warn if not locked */ | 738 | /* from intel_th_msc_window_unlock(), don't warn if not locked */ |
| 742 | if (expect == WIN_LOCKED && old == new) | 739 | if (expect == WIN_LOCKED && old == new) |
| 743 | return 0; | 740 | return 0; |
| 741 | |||
| 742 | dev_warn_ratelimited(msc_dev(win->msc), | ||
| 743 | "expected lockout state %d, got %d\n", | ||
| 744 | expect, old); | ||
| 744 | } | 745 | } |
| 745 | 746 | ||
| 746 | return ret; | 747 | return ret; |
| @@ -760,7 +761,7 @@ static int msc_configure(struct msc *msc) · 13 unmodified lines | |||
| 760 | lockdep_assert_held(&msc->buf_mutex); | 761 | lockdep_assert_held(&msc->buf_mutex); |
| 761 | 762 | ||
| 762 | if (msc->mode > MSC_MODE_MULTI) | 763 | if (msc->mode > MSC_MODE_MULTI) |
| 763 | return -ENOTSUPP; | 764 | return -EINVAL; |
| 764 | 765 | ||
| 765 | if (msc->mode == MSC_MODE_MULTI) { | 766 | if (msc->mode == MSC_MODE_MULTI) { |
| 766 | if (msc_win_set_lockout(msc->cur_win, WIN_READY, WIN_INUSE)) | 767 | if (msc_win_set_lockout(msc->cur_win, WIN_READY, WIN_INUSE)) |
| @@ -1294,7 +1295,7 @@ static int msc_buffer_alloc(struct msc *msc, unsigned long *nr_pages, · 527 unmodified lines | |||
| 1294 | } else if (msc->mode == MSC_MODE_MULTI) { | 1295 | } else if (msc->mode == MSC_MODE_MULTI) { |
| 1295 | ret = msc_buffer_multi_alloc(msc, nr_pages, nr_wins); | 1296 | ret = msc_buffer_multi_alloc(msc, nr_pages, nr_wins); |
| 1296 | } else { | 1297 | } else { |
| 1297 | ret = -ENOTSUPP; | 1298 | ret = -EINVAL; |
| 1298 | } | 1299 | } |
| 1299 | 1300 | ||
| 1300 | if (!ret) { | 1301 | if (!ret) { |
| @@ -1530,7 +1531,7 @@ static ssize_t intel_th_msc_read(struct file *file, char __user *buf, · 229 unmodified lines | |||
| 1530 | if (ret >= 0) | 1531 | if (ret >= 0) |
| 1531 | *ppos = iter->offset; | 1532 | *ppos = iter->offset; |
| 1532 | } else { | 1533 | } else { |
| 1533 | ret = -ENOTSUPP; | 1534 | ret = -EINVAL; |
| 1534 | } | 1535 | } |
| 1535 | 1536 | ||
| 1536 | put_count: | 1537 | put_count: |
| @@ -234,6 +234,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { · 233 unmodified lines | |||
| 234 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), | 234 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), |
| 235 | .driver_data = (kernel_ulong_t)&intel_th_2x, | 235 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
| 236 | }, | 236 | }, |
| 237 | { | ||
| 238 | /* Elkhart Lake CPU */ | ||
| 239 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529), | ||
| 240 | .driver_data = (kernel_ulong_t)&intel_th_2x, | ||
| 241 | }, | ||
| 237 | { | 242 | { |
| 238 | /* Elkhart Lake */ | 243 | /* Elkhart Lake */ |
| 239 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), | 244 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), |
| @@ -238,7 +238,7 @@ static struct configfs_attribute *sys_t_policy_attrs[] = { · 237 unmodified lines | |||
| 238 | static inline bool sys_t_need_ts(struct sys_t_output *op) | 238 | static inline bool sys_t_need_ts(struct sys_t_output *op) |
| 239 | { | 239 | { |
| 240 | if (op->node.ts_interval && | 240 | if (op->node.ts_interval && |
| 241 | time_after(op->ts_jiffies + op->node.ts_interval, jiffies)) { | 241 | time_after(jiffies, op->ts_jiffies + op->node.ts_interval)) { |
| 242 | op->ts_jiffies = jiffies; | 242 | op->ts_jiffies = jiffies; |
| 243 | 243 | ||
| 244 | return true; | 244 | return true; |
| @@ -250,8 +250,8 @@ static inline bool sys_t_need_ts(struct sys_t_output *op) · 5 unmodified lines | |||
| 250 | static bool sys_t_need_clock_sync(struct sys_t_output *op) | 250 | static bool sys_t_need_clock_sync(struct sys_t_output *op) |
| 251 | { | 251 | { |
| 252 | if (op->node.clocksync_interval && | 252 | if (op->node.clocksync_interval && |
| 253 | time_after(op->clocksync_jiffies + op->node.clocksync_interval, | 253 | time_after(jiffies, |
| 254 | jiffies)) { | 254 | op->clocksync_jiffies + op->node.clocksync_interval)) { |
| 255 | op->clocksync_jiffies = jiffies; | 255 | op->clocksync_jiffies = jiffies; |
| 256 | 256 | ||
| 257 | return true; | 257 | return true; |
| @@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) · 312 unmodified lines | |||
| 313 | pm_runtime_get_noresume(&pdev->dev); | 313 | pm_runtime_get_noresume(&pdev->dev); |
| 314 | 314 | ||
| 315 | i2c_del_adapter(&dev->adapter); | 315 | i2c_del_adapter(&dev->adapter); |
| 316 | devm_free_irq(&pdev->dev, dev->irq, dev); | ||
| 316 | pci_free_irq_vectors(pdev); | 317 | pci_free_irq_vectors(pdev); |
| 317 | } | 318 | } |
| 318 | 319 | ||
| @@ -348,7 +348,7 @@ static struct gpio_desc *i2c_gpio_get_desc(struct device *dev, · 347 unmodified lines | |||
| 348 | if (ret == -ENOENT) | 348 | if (ret == -ENOENT) |
| 349 | retdesc = ERR_PTR(-EPROBE_DEFER); | 349 | retdesc = ERR_PTR(-EPROBE_DEFER); |
| 350 | 350 | ||
| 351 | if (ret != -EPROBE_DEFER) | 351 | if (PTR_ERR(retdesc) != -EPROBE_DEFER) |
| 352 | dev_err(dev, "error trying to get descriptor: %d\n", ret); | 352 | dev_err(dev, "error trying to get descriptor: %d\n", ret); |
| 353 | 353 | ||
| 354 | return retdesc; | 354 | return retdesc; |
| @@ -132,11 +132,6 @@ · 131 unmodified lines | |||
| 132 | #define TCOBASE 0x050 | 132 | #define TCOBASE 0x050 |
| 133 | #define TCOCTL 0x054 | 133 | #define TCOCTL 0x054 |
| 134 | 134 | ||
| 135 | #define ACPIBASE 0x040 | ||
| 136 | #define ACPIBASE_SMI_OFF 0x030 | ||
| 137 | #define ACPICTRL 0x044 | ||
| 138 | #define ACPICTRL_EN 0x080 | ||
| 139 | |||
| 140 | #define SBREG_BAR 0x10 | 135 | #define SBREG_BAR 0x10 |
| 141 | #define SBREG_SMBCTRL 0xc6000c | 136 | #define SBREG_SMBCTRL 0xc6000c |
| 142 | #define SBREG_SMBCTRL_DNV 0xcf000c | 137 | #define SBREG_SMBCTRL_DNV 0xcf000c |
| @@ -1553,7 +1548,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, · 1410 unmodified lines | |||
| 1553 | pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); | 1548 | pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); |
| 1554 | spin_unlock(&p2sb_spinlock); | 1549 | spin_unlock(&p2sb_spinlock); |
| 1555 | 1550 | ||
| 1556 | res = &tco_res[ICH_RES_MEM_OFF]; | 1551 | res = &tco_res[1]; |
| 1557 | if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) | 1552 | if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) |
| 1558 | res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; | 1553 | res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; |
| 1559 | else | 1554 | else |
| @@ -1563,7 +1558,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, · 3 unmodified lines | |||
| 1563 | res->flags = IORESOURCE_MEM; | 1558 | res->flags = IORESOURCE_MEM; |
| 1564 | 1559 | ||
| 1565 | return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, | 1560 | return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, |
| 1566 | tco_res, 3, &spt_tco_platform_data, | 1561 | tco_res, 2, &spt_tco_platform_data, |
| 1567 | sizeof(spt_tco_platform_data)); | 1562 | sizeof(spt_tco_platform_data)); |
| 1568 | } | 1563 | } |
| 1569 | 1564 | ||
| @@ -1576,17 +1571,16 @@ static struct platform_device * · 6 unmodified lines | |||
| 1576 | i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, | 1571 | i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, |
| 1577 | struct resource *tco_res) | 1572 | struct resource *tco_res) |
| 1578 | { | 1573 | { |
| 1579 | return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, | 1574 | return platform_device_register_resndata(&pci_dev->dev, |
| 1580 | tco_res, 2, &cnl_tco_platform_data, | 1575 | "iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data, |
| 1581 | sizeof(cnl_tco_platform_data)); | 1576 | sizeof(cnl_tco_platform_data)); |
| 1582 | } | 1577 | } |
| 1583 | 1578 | ||
| 1584 | static void i801_add_tco(struct i801_priv *priv) | 1579 | static void i801_add_tco(struct i801_priv *priv) |
| 1585 | { | 1580 | { |
| 1586 | u32 base_addr, tco_base, tco_ctl, ctrl_val; | ||
| 1587 | struct pci_dev *pci_dev = priv->pci_dev; | 1581 | struct pci_dev *pci_dev = priv->pci_dev; |
| 1588 | struct resource tco_res[3], *res; | 1582 | struct resource tco_res[2], *res; |
| 1589 | unsigned int devfn; | 1583 | u32 tco_base, tco_ctl; |
| 1590 | 1584 | ||
| 1591 | /* If we have ACPI based watchdog use that instead */ | 1585 | /* If we have ACPI based watchdog use that instead */ |
| 1592 | if (acpi_has_watchdog()) | 1586 | if (acpi_has_watchdog()) |
| @@ -1601,30 +1595,15 @@ static void i801_add_tco(struct i801_priv *priv) · 8 unmodified lines | |||
| 1601 | return; | 1595 | return; |
| 1602 | 1596 | ||
| 1603 | memset(tco_res, 0, sizeof(tco_res)); | 1597 | memset(tco_res, 0, sizeof(tco_res)); |
| 1604 | |||
| 1605 | res = &tco_res[ICH_RES_IO_TCO]; | ||
| 1606 | res->start = tco_base & ~1; | ||
| 1607 | res->end = res->start + 32 - 1; | ||
| 1608 | res->flags = IORESOURCE_IO; | ||
| 1609 | |||
| 1610 | /* | 1598 | /* |
| 1611 | * Power Management registers. | 1599 | * Always populate the main iTCO IO resource here. The second entry |
| 1600 | * for NO_REBOOT MMIO is filled by the SPT specific function. | ||
| 1612 | */ | 1601 | */ |
| 1613 | devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2); | 1602 | res = &tco_res[0]; |
| 1614 | pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr); | 1603 | res->start = tco_base & ~1; |
| 1615 | 1604 | res->end = res->start + 32 - 1; | |
| 1616 | res = &tco_res[ICH_RES_IO_SMI]; | ||
| 1617 | res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF; | ||
| 1618 | res->end = res->start + 3; | ||
| 1619 | res->flags = IORESOURCE_IO; | 1605 | res->flags = IORESOURCE_IO; |
| 1620 | 1606 | ||
| 1621 | /* | ||
| 1622 | * Enable the ACPI I/O space. | ||
| 1623 | */ | ||
| 1624 | pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val); | ||
| 1625 | ctrl_val |= ACPICTRL_EN; | ||
| 1626 | pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val); | ||
| 1627 | |||
| 1628 | if (priv->features & FEATURE_TCO_CNL) | 1607 | if (priv->features & FEATURE_TCO_CNL) |
| 1629 | priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); | 1608 | priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); |
| 1630 | else | 1609 | else |
| @@ -394,9 +394,17 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); · 393 unmodified lines | |||
| 394 | static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) | 394 | static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) |
| 395 | { | 395 | { |
| 396 | struct device *dev; | 396 | struct device *dev; |
| 397 | struct i2c_client *client; | ||
| 397 | 398 | ||
| 398 | dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); | 399 | dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); |
| 399 | return dev ? i2c_verify_client(dev) : NULL; | 400 | if (!dev) |
| 401 | return NULL; | ||
| 402 | |||
| 403 | client = i2c_verify_client(dev); | ||
| 404 | if (!client) | ||
| 405 | put_device(dev); | ||
| 406 | |||
| 407 | return client; | ||
| 400 | } | 408 | } |
| 401 | 409 | ||
| 402 | static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, | 410 | static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, |
| @@ -237,6 +237,7 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { · 236 unmodified lines | |||
| 237 | .realbits = 12, \ | 237 | .realbits = 12, \ |
| 238 | .storagebits = 16, \ | 238 | .storagebits = 16, \ |
| 239 | .shift = 4, \ | 239 | .shift = 4, \ |
| 240 | .endianness = IIO_BE, \ | ||
| 240 | }, \ | 241 | }, \ |
| 241 | } | 242 | } |
| 242 | 243 | ||
| @@ -110,7 +110,7 @@ MODULE_DEVICE_TABLE(of, st_accel_of_match); · 109 unmodified lines | |||
| 110 | 110 | ||
| 111 | #ifdef CONFIG_ACPI | 111 | #ifdef CONFIG_ACPI |
| 112 | static const struct acpi_device_id st_accel_acpi_match[] = { | 112 | static const struct acpi_device_id st_accel_acpi_match[] = { |
| 113 | {"SMO8840", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, | 113 | {"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME}, |
| 114 | {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, | 114 | {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, |
| 115 | { }, | 115 | { }, |
| 116 | }; | 116 | }; |
| @@ -723,6 +723,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 722 unmodified lines | |||
| 723 | 723 | ||
| 724 | for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { | 724 | for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { |
| 725 | struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); | 725 | struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); |
| 726 | u32 cor; | ||
| 726 | 727 | ||
| 727 | if (!chan) | 728 | if (!chan) |
| 728 | continue; | 729 | continue; |
| @@ -731,6 +732,20 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 2 unmodified lines | |||
| 731 | chan->type == IIO_PRESSURE) | 732 | chan->type == IIO_PRESSURE) |
| 732 | continue; | 733 | continue; |
| 733 | 734 | ||
| 735 | if (state) { | ||
| 736 | cor = at91_adc_readl(st, AT91_SAMA5D2_COR); | ||
| 737 | |||
| 738 | if (chan->differential) | ||
| 739 | cor |= (BIT(chan->channel) | | ||
| 740 | BIT(chan->channel2)) << | ||
| 741 | AT91_SAMA5D2_COR_DIFF_OFFSET; | ||
| 742 | else | ||
| 743 | cor &= ~(BIT(chan->channel) << | ||
| 744 | AT91_SAMA5D2_COR_DIFF_OFFSET); | ||
| 745 | |||
| 746 | at91_adc_writel(st, AT91_SAMA5D2_COR, cor); | ||
| 747 | } | ||
| 748 | |||
| 734 | if (state) { | 749 | if (state) { |
| 735 | at91_adc_writel(st, AT91_SAMA5D2_CHER, | 750 | at91_adc_writel(st, AT91_SAMA5D2_CHER, |
| 736 | BIT(chan->channel)); | 751 | BIT(chan->channel)); |
| @@ -842,31 +842,6 @@ static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc, · 841 unmodified lines | |||
| 842 | } | 842 | } |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p) | ||
| 846 | { | ||
| 847 | struct iio_poll_func *pf = p; | ||
| 848 | struct iio_dev *indio_dev = pf->indio_dev; | ||
| 849 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
| 850 | int available = stm32_dfsdm_adc_dma_residue(adc); | ||
| 851 | |||
| 852 | while (available >= indio_dev->scan_bytes) { | ||
| 853 | s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi]; | ||
| 854 | |||
| 855 | stm32_dfsdm_process_data(adc, buffer); | ||
| 856 | |||
| 857 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, | ||
| 858 | pf->timestamp); | ||
| 859 | available -= indio_dev->scan_bytes; | ||
| 860 | adc->bufi += indio_dev->scan_bytes; | ||
| 861 | if (adc->bufi >= adc->buf_sz) | ||
| 862 | adc->bufi = 0; | ||
| 863 | } | ||
| 864 | |||
| 865 | iio_trigger_notify_done(indio_dev->trig); | ||
| 866 | |||
| 867 | return IRQ_HANDLED; | ||
| 868 | } | ||
| 869 | |||
| 870 | static void stm32_dfsdm_dma_buffer_done(void *data) | 845 | static void stm32_dfsdm_dma_buffer_done(void *data) |
| 871 | { | 846 | { |
| 872 | struct iio_dev *indio_dev = data; | 847 | struct iio_dev *indio_dev = data; |
| @@ -874,11 +849,6 @@ static void stm32_dfsdm_dma_buffer_done(void *data) · 1 unmodified line | |||
| 874 | int available = stm32_dfsdm_adc_dma_residue(adc); | 849 | int available = stm32_dfsdm_adc_dma_residue(adc); |
| 875 | size_t old_pos; | 850 | size_t old_pos; |
| 876 | 851 | ||
| 877 | if (indio_dev->currentmode & INDIO_BUFFER_TRIGGERED) { | ||
| 878 | iio_trigger_poll_chained(indio_dev->trig); | ||
| 879 | return; | ||
| 880 | } | ||
| 881 | |||
| 882 | /* | 852 | /* |
| 883 | * FIXME: In Kernel interface does not support cyclic DMA buffer,and | 853 | * FIXME: In Kernel interface does not support cyclic DMA buffer,and |
| 884 | * offers only an interface to push data samples per samples. | 854 | * offers only an interface to push data samples per samples. |
| @@ -906,7 +876,15 @@ static void stm32_dfsdm_dma_buffer_done(void *data) · 21 unmodified lines | |||
| 906 | adc->bufi = 0; | 876 | adc->bufi = 0; |
| 907 | old_pos = 0; | 877 | old_pos = 0; |
| 908 | } | 878 | } |
| 909 | /* regular iio buffer without trigger */ | 879 | /* |
| 880 | * In DMA mode the trigger services of IIO are not used | ||
| 881 | * (e.g. no call to iio_trigger_poll). | ||
| 882 | * Calling irq handler associated to the hardware trigger is not | ||
| 883 | * relevant as the conversions have already been done. Data | ||
| 884 | * transfers are performed directly in DMA callback instead. | ||
| 885 | * This implementation avoids to call trigger irq handler that | ||
| 886 | * may sleep, in an atomic context (DMA irq handler context). | ||
| 887 | */ | ||
| 910 | if (adc->dev_data->type == DFSDM_IIO) | 888 | if (adc->dev_data->type == DFSDM_IIO) |
| 911 | iio_push_to_buffers(indio_dev, buffer); | 889 | iio_push_to_buffers(indio_dev, buffer); |
| 912 | } | 890 | } |
| @@ -1536,8 +1514,7 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) · 623 unmodified lines | |||
| 1536 | } | 1514 | } |
| 1537 | 1515 | ||
| 1538 | ret = iio_triggered_buffer_setup(indio_dev, | 1516 | ret = iio_triggered_buffer_setup(indio_dev, |
| 1539 | &iio_pollfunc_store_time, | 1517 | &iio_pollfunc_store_time, NULL, |
| 1540 | &stm32_dfsdm_adc_trigger_handler, | ||
| 1541 | &stm32_dfsdm_buffer_setup_ops); | 1518 | &stm32_dfsdm_buffer_setup_ops); |
| 1542 | if (ret) { | 1519 | if (ret) { |
| 1543 | stm32_dfsdm_dma_release(indio_dev); | 1520 | stm32_dfsdm_dma_release(indio_dev); |
| @@ -91,6 +91,8 @@ config SPS30 · 90 unmodified lines | |||
| 91 | tristate "SPS30 particulate matter sensor" | 91 | tristate "SPS30 particulate matter sensor" |
| 92 | depends on I2C | 92 | depends on I2C |
| 93 | select CRC8 | 93 | select CRC8 |
| 94 | select IIO_BUFFER | ||
| 95 | select IIO_TRIGGERED_BUFFER | ||
| 94 | help | 96 | help |
| 95 | Say Y here to build support for the Sensirion SPS30 particulate | 97 | Say Y here to build support for the Sensirion SPS30 particulate |
| 96 | matter sensor. | 98 | matter sensor. |
| @@ -167,16 +167,17 @@ static int vcnl4200_init(struct vcnl4000_data *data) · 166 unmodified lines | |||
| 167 | data->vcnl4200_ps.reg = VCNL4200_PS_DATA; | 167 | data->vcnl4200_ps.reg = VCNL4200_PS_DATA; |
| 168 | switch (id) { | 168 | switch (id) { |
| 169 | case VCNL4200_PROD_ID: | 169 | case VCNL4200_PROD_ID: |
| 170 | /* Integration time is 50ms, but the experiments */ | 170 | /* Default wait time is 50ms, add 20% tolerance. */ |
| 171 | /* show 54ms in total. */ | 171 | data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000); |
| 172 | data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000); | 172 | /* Default wait time is 4.8ms, add 20% tolerance. */ |
| 173 | data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000); | 173 | data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000); |
| 174 | data->al_scale = 24000; | 174 | data->al_scale = 24000; |
| 175 | break; | 175 | break; |
| 176 | case VCNL4040_PROD_ID: | 176 | case VCNL4040_PROD_ID: |
| 177 | /* Integration time is 80ms, add 10ms. */ | 177 | /* Default wait time is 80ms, add 20% tolerance. */ |
| 178 | data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000); | 178 | data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000); |
| 179 | data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000); | 179 | /* Default wait time is 5ms, add 20% tolerance. */ |
| 180 | data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000); | ||
| 180 | data->al_scale = 120000; | 181 | data->al_scale = 120000; |
| 181 | break; | 182 | break; |
| 182 | } | 183 | } |
| @@ -564,7 +564,7 @@ static int ak8974_read_raw(struct iio_dev *indio_dev, · 563 unmodified lines | |||
| 564 | * We read all axes and discard all but one, for optimized | 564 | * We read all axes and discard all but one, for optimized |
| 565 | * reading, use the triggered buffer. | 565 | * reading, use the triggered buffer. |
| 566 | */ | 566 | */ |
| 567 | *val = le16_to_cpu(hw_values[chan->address]); | 567 | *val = (s16)le16_to_cpu(hw_values[chan->address]); |
| 568 | 568 | ||
| 569 | ret = IIO_VAL_INT; | 569 | ret = IIO_VAL_INT; |
| 570 | } | 570 | } |
| @@ -269,7 +269,7 @@ static const struct iio_chan_spec ping_chan_spec[] = { · 268 unmodified lines | |||
| 269 | 269 | ||
| 270 | static const struct of_device_id of_ping_match[] = { | 270 | static const struct of_device_id of_ping_match[] = { |
| 271 | { .compatible = "parallax,ping", .data = &pa_ping_cfg}, | 271 | { .compatible = "parallax,ping", .data = &pa_ping_cfg}, |
| 272 | { .compatible = "parallax,laserping", .data = &pa_ping_cfg}, | 272 | { .compatible = "parallax,laserping", .data = &pa_laser_ping_cfg}, |
| 273 | {}, | 273 | {}, |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| @@ -161,7 +161,8 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, · 160 unmodified lines | |||
| 161 | return 0; | 161 | return 0; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static void stm32_timer_stop(struct stm32_timer_trigger *priv) | 164 | static void stm32_timer_stop(struct stm32_timer_trigger *priv, |
| 165 | struct iio_trigger *trig) | ||
| 165 | { | 166 | { |
| 166 | u32 ccer, cr1; | 167 | u32 ccer, cr1; |
| 167 | 168 | ||
| @@ -179,6 +180,12 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv) · 11 unmodified lines | |||
| 179 | regmap_write(priv->regmap, TIM_PSC, 0); | 180 | regmap_write(priv->regmap, TIM_PSC, 0); |
| 180 | regmap_write(priv->regmap, TIM_ARR, 0); | 181 | regmap_write(priv->regmap, TIM_ARR, 0); |
| 181 | 182 | ||
| 183 | /* Force disable master mode */ | ||
| 184 | if (stm32_timer_is_trgo2_name(trig->name)) | ||
| 185 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0); | ||
| 186 | else | ||
| 187 | regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0); | ||
| 188 | |||
| 182 | /* Make sure that registers are updated */ | 189 | /* Make sure that registers are updated */ |
| 183 | regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); | 190 | regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); |
| 184 | } | 191 | } |
| @@ -197,7 +204,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev, · 12 unmodified lines | |||
| 197 | return ret; | 204 | return ret; |
| 198 | 205 | ||
| 199 | if (freq == 0) { | 206 | if (freq == 0) { |
| 200 | stm32_timer_stop(priv); | 207 | stm32_timer_stop(priv, trig); |
| 201 | } else { | 208 | } else { |
| 202 | ret = stm32_timer_start(priv, trig, freq); | 209 | ret = stm32_timer_start(priv, trig, freq); |
| 203 | if (ret) | 210 | if (ret) |
| @@ -3826,7 +3826,7 @@ int amd_iommu_activate_guest_mode(void *data) · 3825 unmodified lines | |||
| 3826 | entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; | 3826 | entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; |
| 3827 | 3827 | ||
| 3828 | return modify_irte_ga(ir_data->irq_2_irte.devid, | 3828 | return modify_irte_ga(ir_data->irq_2_irte.devid, |
| 3829 | ir_data->irq_2_irte.index, entry, NULL); | 3829 | ir_data->irq_2_irte.index, entry, ir_data); |
| 3830 | } | 3830 | } |
| 3831 | EXPORT_SYMBOL(amd_iommu_activate_guest_mode); | 3831 | EXPORT_SYMBOL(amd_iommu_activate_guest_mode); |
| 3832 | 3832 | ||
| @@ -3852,7 +3852,7 @@ int amd_iommu_deactivate_guest_mode(void *data) · 19 unmodified lines | |||
| 3852 | APICID_TO_IRTE_DEST_HI(cfg->dest_apicid); | 3852 | APICID_TO_IRTE_DEST_HI(cfg->dest_apicid); |
| 3853 | 3853 | ||
| 3854 | return modify_irte_ga(ir_data->irq_2_irte.devid, | 3854 | return modify_irte_ga(ir_data->irq_2_irte.devid, |
| 3855 | ir_data->irq_2_irte.index, entry, NULL); | 3855 | ir_data->irq_2_irte.index, entry, ir_data); |
| 3856 | } | 3856 | } |
| 3857 | EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode); | 3857 | EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode); |
| 3858 | 3858 | ||
| @@ -177,15 +177,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, · 176 unmodified lines | |||
| 177 | start -= iova_offset(iovad, start); | 177 | start -= iova_offset(iovad, start); |
| 178 | num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); | 178 | num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); |
| 179 | 179 | ||
| 180 | msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL); | ||
| 181 | if (!msi_page) | ||
| 182 | return -ENOMEM; | ||
| 183 | |||
| 184 | for (i = 0; i < num_pages; i++) { | 180 | for (i = 0; i < num_pages; i++) { |
| 185 | msi_page[i].phys = start; | 181 | msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); |
| 186 | msi_page[i].iova = start; | 182 | if (!msi_page) |
| 187 | INIT_LIST_HEAD(&msi_page[i].list); | 183 | return -ENOMEM; |
| 188 | list_add(&msi_page[i].list, &cookie->msi_page_list); | 184 | |
| 185 | msi_page->phys = start; | ||
| 186 | msi_page->iova = start; | ||
| 187 | INIT_LIST_HEAD(&msi_page->list); | ||
| 188 | list_add(&msi_page->list, &cookie->msi_page_list); | ||
| 189 | start += iovad->granule; | 189 | start += iovad->granule; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| @@ -28,6 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/iommu.h> | 29 | #include <linux/iommu.h> |
| 30 | #include <linux/numa.h> | 30 | #include <linux/numa.h> |
| 31 | #include <linux/limits.h> | ||
| 31 | #include <asm/irq_remapping.h> | 32 | #include <asm/irq_remapping.h> |
| 32 | #include <asm/iommu_table.h> | 33 | #include <asm/iommu_table.h> |
| 33 | 34 | ||
| @@ -128,6 +129,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) · 94 unmodified lines | |||
| 128 | 129 | ||
| 129 | BUG_ON(dev->is_virtfn); | 130 | BUG_ON(dev->is_virtfn); |
| 130 | 131 | ||
| 132 | /* | ||
| 133 | * Ignore devices that have a domain number higher than what can | ||
| 134 | * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000 | ||
| 135 | */ | ||
| 136 | if (pci_domain_nr(dev->bus) > U16_MAX) | ||
| 137 | return NULL; | ||
| 138 | |||
| 131 | /* Only generate path[] for device addition event */ | 139 | /* Only generate path[] for device addition event */ |
| 132 | if (event == BUS_NOTIFY_ADD_DEVICE) | 140 | if (event == BUS_NOTIFY_ADD_DEVICE) |
| 133 | for (tmp = dev; tmp; tmp = tmp->bus->self) | 141 | for (tmp = dev; tmp; tmp = tmp->bus->self) |
| @@ -363,7 +371,8 @@ dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd) · 229 unmodified lines | |||
| 363 | { | 371 | { |
| 364 | struct dmar_drhd_unit *dmaru; | 372 | struct dmar_drhd_unit *dmaru; |
| 365 | 373 | ||
| 366 | list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list) | 374 | list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list, |
| 375 | dmar_rcu_check()) | ||
| 367 | if (dmaru->segment == drhd->segment && | 376 | if (dmaru->segment == drhd->segment && |
| 368 | dmaru->reg_base_addr == drhd->address) | 377 | dmaru->reg_base_addr == drhd->address) |
| 369 | return dmaru; | 378 | return dmaru; |
| @@ -440,12 +449,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, · 70 unmodified lines | |||
| 440 | 449 | ||
| 441 | /* Check for NUL termination within the designated length */ | 450 | /* Check for NUL termination within the designated length */ |
| 442 | if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { | 451 | if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { |
| 443 | WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | 452 | pr_warn(FW_BUG |
| 444 | "Your BIOS is broken; ANDD object name is not NUL-terminated\n" | 453 | "Your BIOS is broken; ANDD object name is not NUL-terminated\n" |
| 445 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 454 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 446 | dmi_get_system_info(DMI_BIOS_VENDOR), | 455 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 447 | dmi_get_system_info(DMI_BIOS_VERSION), | 456 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 448 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 457 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 458 | add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
| 449 | return -EINVAL; | 459 | return -EINVAL; |
| 450 | } | 460 | } |
| 451 | pr_info("ANDD device: %x name: %s\n", andd->device_number, | 461 | pr_info("ANDD device: %x name: %s\n", andd->device_number, |
| @@ -471,14 +481,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) · 19 unmodified lines | |||
| 471 | return 0; | 481 | return 0; |
| 472 | } | 482 | } |
| 473 | } | 483 | } |
| 474 | WARN_TAINT( | 484 | pr_warn(FW_BUG |
| 475 | 1, TAINT_FIRMWARE_WORKAROUND, | ||
| 476 | "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" | 485 | "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" |
| 477 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 486 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 478 | drhd->reg_base_addr, | 487 | rhsa->base_address, |
| 479 | dmi_get_system_info(DMI_BIOS_VENDOR), | 488 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 480 | dmi_get_system_info(DMI_BIOS_VERSION), | 489 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 481 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 490 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 491 | add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
| 482 | 492 | ||
| 483 | return 0; | 493 | return 0; |
| 484 | } | 494 | } |
| @@ -827,14 +837,14 @@ int __init dmar_table_init(void) · 342 unmodified lines | |||
| 827 | 837 | ||
| 828 | static void warn_invalid_dmar(u64 addr, const char *message) | 838 | static void warn_invalid_dmar(u64 addr, const char *message) |
| 829 | { | 839 | { |
| 830 | WARN_TAINT_ONCE( | 840 | pr_warn_once(FW_BUG |
| 831 | 1, TAINT_FIRMWARE_WORKAROUND, | ||
| 832 | "Your BIOS is broken; DMAR reported at address %llx%s!\n" | 841 | "Your BIOS is broken; DMAR reported at address %llx%s!\n" |
| 833 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 842 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 834 | addr, message, | 843 | addr, message, |
| 835 | dmi_get_system_info(DMI_BIOS_VENDOR), | 844 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 836 | dmi_get_system_info(DMI_BIOS_VERSION), | 845 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 837 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 846 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 847 | add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
| 838 | } | 848 | } |
| 839 | 849 | ||
| 840 | static int __ref | 850 | static int __ref |
| @@ -33,38 +33,42 @@ struct iommu_regset { · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | #define IOMMU_REGSET_ENTRY(_reg_) \ | 34 | #define IOMMU_REGSET_ENTRY(_reg_) \ |
| 35 | { DMAR_##_reg_##_REG, __stringify(_reg_) } | 35 | { DMAR_##_reg_##_REG, __stringify(_reg_) } |
| 36 | static const struct iommu_regset iommu_regs[] = { | 36 | |
| 37 | static const struct iommu_regset iommu_regs_32[] = { | ||
| 37 | IOMMU_REGSET_ENTRY(VER), | 38 | IOMMU_REGSET_ENTRY(VER), |
| 38 | IOMMU_REGSET_ENTRY(CAP), | ||
| 39 | IOMMU_REGSET_ENTRY(ECAP), | ||
| 40 | IOMMU_REGSET_ENTRY(GCMD), | 39 | IOMMU_REGSET_ENTRY(GCMD), |
| 41 | IOMMU_REGSET_ENTRY(GSTS), | 40 | IOMMU_REGSET_ENTRY(GSTS), |
| 42 | IOMMU_REGSET_ENTRY(RTADDR), | ||
| 43 | IOMMU_REGSET_ENTRY(CCMD), | ||
| 44 | IOMMU_REGSET_ENTRY(FSTS), | 41 | IOMMU_REGSET_ENTRY(FSTS), |
| 45 | IOMMU_REGSET_ENTRY(FECTL), | 42 | IOMMU_REGSET_ENTRY(FECTL), |
| 46 | IOMMU_REGSET_ENTRY(FEDATA), | 43 | IOMMU_REGSET_ENTRY(FEDATA), |
| 47 | IOMMU_REGSET_ENTRY(FEADDR), | 44 | IOMMU_REGSET_ENTRY(FEADDR), |
| 48 | IOMMU_REGSET_ENTRY(FEUADDR), | 45 | IOMMU_REGSET_ENTRY(FEUADDR), |
| 49 | IOMMU_REGSET_ENTRY(AFLOG), | ||
| 50 | IOMMU_REGSET_ENTRY(PMEN), | 46 | IOMMU_REGSET_ENTRY(PMEN), |
| 51 | IOMMU_REGSET_ENTRY(PLMBASE), | 47 | IOMMU_REGSET_ENTRY(PLMBASE), |
| 52 | IOMMU_REGSET_ENTRY(PLMLIMIT), | 48 | IOMMU_REGSET_ENTRY(PLMLIMIT), |
| 49 | IOMMU_REGSET_ENTRY(ICS), | ||
| 50 | IOMMU_REGSET_ENTRY(PRS), | ||
| 51 | IOMMU_REGSET_ENTRY(PECTL), | ||
| 52 | IOMMU_REGSET_ENTRY(PEDATA), | ||
| 53 | IOMMU_REGSET_ENTRY(PEADDR), | ||
| 54 | IOMMU_REGSET_ENTRY(PEUADDR), | ||
| 55 | }; | ||
| 56 | |||
| 57 | static const struct iommu_regset iommu_regs_64[] = { | ||
| 58 | IOMMU_REGSET_ENTRY(CAP), | ||
| 59 | IOMMU_REGSET_ENTRY(ECAP), | ||
| 60 | IOMMU_REGSET_ENTRY(RTADDR), | ||
| 61 | IOMMU_REGSET_ENTRY(CCMD), | ||
| 62 | IOMMU_REGSET_ENTRY(AFLOG), | ||
| 53 | IOMMU_REGSET_ENTRY(PHMBASE), | 63 | IOMMU_REGSET_ENTRY(PHMBASE), |
| 54 | IOMMU_REGSET_ENTRY(PHMLIMIT), | 64 | IOMMU_REGSET_ENTRY(PHMLIMIT), |
| 55 | IOMMU_REGSET_ENTRY(IQH), | 65 | IOMMU_REGSET_ENTRY(IQH), |
| 56 | IOMMU_REGSET_ENTRY(IQT), | 66 | IOMMU_REGSET_ENTRY(IQT), |
| 57 | IOMMU_REGSET_ENTRY(IQA), | 67 | IOMMU_REGSET_ENTRY(IQA), |
| 58 | IOMMU_REGSET_ENTRY(ICS), | ||
| 59 | IOMMU_REGSET_ENTRY(IRTA), | 68 | IOMMU_REGSET_ENTRY(IRTA), |
| 60 | IOMMU_REGSET_ENTRY(PQH), | 69 | IOMMU_REGSET_ENTRY(PQH), |
| 61 | IOMMU_REGSET_ENTRY(PQT), | 70 | IOMMU_REGSET_ENTRY(PQT), |
| 62 | IOMMU_REGSET_ENTRY(PQA), | 71 | IOMMU_REGSET_ENTRY(PQA), |
| 63 | IOMMU_REGSET_ENTRY(PRS), | ||
| 64 | IOMMU_REGSET_ENTRY(PECTL), | ||
| 65 | IOMMU_REGSET_ENTRY(PEDATA), | ||
| 66 | IOMMU_REGSET_ENTRY(PEADDR), | ||
| 67 | IOMMU_REGSET_ENTRY(PEUADDR), | ||
| 68 | IOMMU_REGSET_ENTRY(MTRRCAP), | 72 | IOMMU_REGSET_ENTRY(MTRRCAP), |
| 69 | IOMMU_REGSET_ENTRY(MTRRDEF), | 73 | IOMMU_REGSET_ENTRY(MTRRDEF), |
| 70 | IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000), | 74 | IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000), |
| @@ -127,10 +131,16 @@ static int iommu_regset_show(struct seq_file *m, void *unused) · 56 unmodified lines | |||
| 127 | * by adding the offset to the pointer (virtual address). | 131 | * by adding the offset to the pointer (virtual address). |
| 128 | */ | 132 | */ |
| 129 | raw_spin_lock_irqsave(&iommu->register_lock, flag); | 133 | raw_spin_lock_irqsave(&iommu->register_lock, flag); |
| 130 | for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) { | 134 | for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) { |
| 131 | value = dmar_readq(iommu->reg + iommu_regs[i].offset); | 135 | value = dmar_readl(iommu->reg + iommu_regs_32[i].offset); |
| 136 | seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", | ||
| 137 | iommu_regs_32[i].regs, iommu_regs_32[i].offset, | ||
| 138 | value); | ||
| 139 | } | ||
| 140 | for (i = 0 ; i < ARRAY_SIZE(iommu_regs_64); i++) { | ||
| 141 | value = dmar_readq(iommu->reg + iommu_regs_64[i].offset); | ||
| 132 | seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", | 142 | seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", |
| 133 | iommu_regs[i].regs, iommu_regs[i].offset, | 143 | iommu_regs_64[i].regs, iommu_regs_64[i].offset, |
| 134 | value); | 144 | value); |
| 135 | } | 145 | } |
| 136 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); | 146 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); |
| @@ -272,9 +282,16 @@ static int dmar_translation_struct_show(struct seq_file *m, void *unused) · 135 unmodified lines | |||
| 272 | { | 282 | { |
| 273 | struct dmar_drhd_unit *drhd; | 283 | struct dmar_drhd_unit *drhd; |
| 274 | struct intel_iommu *iommu; | 284 | struct intel_iommu *iommu; |
| 285 | u32 sts; | ||
| 275 | 286 | ||
| 276 | rcu_read_lock(); | 287 | rcu_read_lock(); |
| 277 | for_each_active_iommu(iommu, drhd) { | 288 | for_each_active_iommu(iommu, drhd) { |
| 289 | sts = dmar_readl(iommu->reg + DMAR_GSTS_REG); | ||
| 290 | if (!(sts & DMA_GSTS_TES)) { | ||
| 291 | seq_printf(m, "DMA Remapping is not enabled on %s\n", | ||
| 292 | iommu->name); | ||
| 293 | continue; | ||
| 294 | } | ||
| 278 | root_tbl_walk(m, iommu); | 295 | root_tbl_walk(m, iommu); |
| 279 | seq_putc(m, '\n'); | 296 | seq_putc(m, '\n'); |
| 280 | } | 297 | } |
| @@ -415,6 +432,7 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused) · 134 unmodified lines | |||
| 415 | struct dmar_drhd_unit *drhd; | 432 | struct dmar_drhd_unit *drhd; |
| 416 | struct intel_iommu *iommu; | 433 | struct intel_iommu *iommu; |
| 417 | u64 irta; | 434 | u64 irta; |
| 435 | u32 sts; | ||
| 418 | 436 | ||
| 419 | rcu_read_lock(); | 437 | rcu_read_lock(); |
| 420 | for_each_active_iommu(iommu, drhd) { | 438 | for_each_active_iommu(iommu, drhd) { |
| @@ -424,7 +442,8 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused) · 3 unmodified lines | |||
| 424 | seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n", | 442 | seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n", |
| 425 | iommu->name); | 443 | iommu->name); |
| 426 | 444 | ||
| 427 | if (iommu->ir_table) { | 445 | sts = dmar_readl(iommu->reg + DMAR_GSTS_REG); |
| 446 | if (iommu->ir_table && (sts & DMA_GSTS_IRES)) { | ||
| 428 | irta = virt_to_phys(iommu->ir_table->base); | 447 | irta = virt_to_phys(iommu->ir_table->base); |
| 429 | seq_printf(m, " IR table address:%llx\n", irta); | 448 | seq_printf(m, " IR table address:%llx\n", irta); |
| 430 | ir_tbl_remap_entry_show(m, iommu); | 449 | ir_tbl_remap_entry_show(m, iommu); |
| @@ -4261,10 +4261,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) · 4260 unmodified lines | |||
| 4261 | 4261 | ||
| 4262 | /* we know that the this iommu should be at offset 0xa000 from vtbar */ | 4262 | /* we know that the this iommu should be at offset 0xa000 from vtbar */ |
| 4263 | drhd = dmar_find_matched_drhd_unit(pdev); | 4263 | drhd = dmar_find_matched_drhd_unit(pdev); |
| 4264 | if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, | 4264 | if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { |
| 4265 | TAINT_FIRMWARE_WORKAROUND, | 4265 | pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); |
| 4266 | "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) | 4266 | add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); |
| 4267 | pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; | 4267 | pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; |
| 4268 | } | ||
| 4268 | } | 4269 | } |
| 4269 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); | 4270 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); |
| 4270 | 4271 | ||
| @@ -4460,14 +4461,16 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg) · 189 unmodified lines | |||
| 4460 | struct dmar_rmrr_unit *rmrru; | 4461 | struct dmar_rmrr_unit *rmrru; |
| 4461 | 4462 | ||
| 4462 | rmrr = (struct acpi_dmar_reserved_memory *)header; | 4463 | rmrr = (struct acpi_dmar_reserved_memory *)header; |
| 4463 | if (rmrr_sanity_check(rmrr)) | 4464 | if (rmrr_sanity_check(rmrr)) { |
| 4464 | WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | 4465 | pr_warn(FW_BUG |
| 4465 | "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" | 4466 | "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" |
| 4466 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 4467 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 4467 | rmrr->base_address, rmrr->end_address, | 4468 | rmrr->base_address, rmrr->end_address, |
| 4468 | dmi_get_system_info(DMI_BIOS_VENDOR), | 4469 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 4469 | dmi_get_system_info(DMI_BIOS_VERSION), | 4470 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 4470 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 4471 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 4472 | add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | ||
| 4473 | } | ||
| 4471 | 4474 | ||
| 4472 | rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); | 4475 | rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); |
| 4473 | if (!rmrru) | 4476 | if (!rmrru) |
| @@ -5130,6 +5133,9 @@ int __init intel_iommu_init(void) · 656 unmodified lines | |||
| 5130 | 5133 | ||
| 5131 | down_write(&dmar_global_lock); | 5134 | down_write(&dmar_global_lock); |
| 5132 | 5135 | ||
| 5136 | if (!no_iommu) | ||
| 5137 | intel_iommu_debugfs_init(); | ||
| 5138 | |||
| 5133 | if (no_iommu || dmar_disabled) { | 5139 | if (no_iommu || dmar_disabled) { |
| 5134 | /* | 5140 | /* |
| 5135 | * We exit the function here to ensure IOMMU's remapping and | 5141 | * We exit the function here to ensure IOMMU's remapping and |
| @@ -5193,6 +5199,7 @@ int __init intel_iommu_init(void) · 57 unmodified lines | |||
| 5193 | 5199 | ||
| 5194 | init_iommu_pm_ops(); | 5200 | init_iommu_pm_ops(); |
| 5195 | 5201 | ||
| 5202 | down_read(&dmar_global_lock); | ||
| 5196 | for_each_active_iommu(iommu, drhd) { | 5203 | for_each_active_iommu(iommu, drhd) { |
| 5197 | iommu_device_sysfs_add(&iommu->iommu, NULL, | 5204 | iommu_device_sysfs_add(&iommu->iommu, NULL, |
| 5198 | intel_iommu_groups, | 5205 | intel_iommu_groups, |
| @@ -5200,6 +5207,7 @@ int __init intel_iommu_init(void) · 1 unmodified line | |||
| 5200 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); | 5207 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); |
| 5201 | iommu_device_register(&iommu->iommu); | 5208 | iommu_device_register(&iommu->iommu); |
| 5202 | } | 5209 | } |
| 5210 | up_read(&dmar_global_lock); | ||
| 5203 | 5211 | ||
| 5204 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); | 5212 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); |
| 5205 | if (si_domain && !hw_pass_through) | 5213 | if (si_domain && !hw_pass_through) |
| @@ -5210,7 +5218,6 @@ int __init intel_iommu_init(void) · 4 unmodified lines | |||
| 5210 | down_read(&dmar_global_lock); | 5218 | down_read(&dmar_global_lock); |
| 5211 | if (probe_acpi_namespace_devices()) | 5219 | if (probe_acpi_namespace_devices()) |
| 5212 | pr_warn("ACPI name space devices didn't probe correctly\n"); | 5220 | pr_warn("ACPI name space devices didn't probe correctly\n"); |
| 5213 | up_read(&dmar_global_lock); | ||
| 5214 | 5221 | ||
| 5215 | /* Finally, we enable the DMA remapping hardware. */ | 5222 | /* Finally, we enable the DMA remapping hardware. */ |
| 5216 | for_each_iommu(iommu, drhd) { | 5223 | for_each_iommu(iommu, drhd) { |
| @@ -5219,10 +5226,11 @@ int __init intel_iommu_init(void) · 2 unmodified lines | |||
| 5219 | 5226 | ||
| 5220 | iommu_disable_protect_mem_regions(iommu); | 5227 | iommu_disable_protect_mem_regions(iommu); |
| 5221 | } | 5228 | } |
| 5229 | up_read(&dmar_global_lock); | ||
| 5230 | |||
| 5222 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); | 5231 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); |
| 5223 | 5232 | ||
| 5224 | intel_iommu_enabled = 1; | 5233 | intel_iommu_enabled = 1; |
| 5225 | intel_iommu_debugfs_init(); | ||
| 5226 | 5234 | ||
| 5227 | return 0; | 5235 | return 0; |
| 5228 | 5236 | ||
| @@ -5700,8 +5708,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, · 471 unmodified lines | |||
| 5700 | u64 phys = 0; | 5708 | u64 phys = 0; |
| 5701 | 5709 | ||
| 5702 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); | 5710 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); |
| 5703 | if (pte) | 5711 | if (pte && dma_pte_present(pte)) |
| 5704 | phys = dma_pte_addr(pte); | 5712 | phys = dma_pte_addr(pte) + |
| 5713 | (iova & (BIT_MASK(level_to_offset_bits(level) + | ||
| 5714 | VTD_PAGE_SHIFT) - 1)); | ||
| 5705 | 5715 | ||
| 5706 | return phys; | 5716 | return phys; |
| 5707 | } | 5717 | } |
| @@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, · 467 unmodified lines | |||
| 468 | arm_lpae_iopte *ptep = data->pgd; | 468 | arm_lpae_iopte *ptep = data->pgd; |
| 469 | int ret, lvl = data->start_level; | 469 | int ret, lvl = data->start_level; |
| 470 | arm_lpae_iopte prot; | 470 | arm_lpae_iopte prot; |
| 471 | long iaext = (long)iova >> cfg->ias; | 471 | long iaext = (s64)iova >> cfg->ias; |
| 472 | 472 | ||
| 473 | /* If no access, then nothing to do */ | 473 | /* If no access, then nothing to do */ |
| 474 | if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) | 474 | if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) |
| @@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, · 170 unmodified lines | |||
| 645 | struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); | 645 | struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); |
| 646 | struct io_pgtable_cfg *cfg = &data->iop.cfg; | 646 | struct io_pgtable_cfg *cfg = &data->iop.cfg; |
| 647 | arm_lpae_iopte *ptep = data->pgd; | 647 | arm_lpae_iopte *ptep = data->pgd; |
| 648 | long iaext = (long)iova >> cfg->ias; | 648 | long iaext = (s64)iova >> cfg->ias; |
| 649 | 649 | ||
| 650 | if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) | 650 | if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) |
| 651 | return 0; | 651 | return 0; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80) | 34 | #define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80) |
| 35 | 35 | ||
| 36 | #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) | 36 | #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) |
| 37 | #define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) | ||
| 37 | 38 | ||
| 38 | struct redist_region { | 39 | struct redist_region { |
| 39 | void __iomem *redist_base; | 40 | void __iomem *redist_base; |
| @@ -1464,6 +1465,15 @@ static bool gic_enable_quirk_msm8996(void *data) · 1424 unmodified lines | |||
| 1464 | return true; | 1465 | return true; |
| 1465 | } | 1466 | } |
| 1466 | 1467 | ||
| 1468 | static bool gic_enable_quirk_cavium_38539(void *data) | ||
| 1469 | { | ||
| 1470 | struct gic_chip_data *d = data; | ||
| 1471 | |||
| 1472 | d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539; | ||
| 1473 | |||
| 1474 | return true; | ||
| 1475 | } | ||
| 1476 | |||
| 1467 | static bool gic_enable_quirk_hip06_07(void *data) | 1477 | static bool gic_enable_quirk_hip06_07(void *data) |
| 1468 | { | 1478 | { |
| 1469 | struct gic_chip_data *d = data; | 1479 | struct gic_chip_data *d = data; |
| @@ -1502,6 +1512,19 @@ static const struct gic_quirk gic_quirks[] = { · 32 unmodified lines | |||
| 1502 | .mask = 0xffffffff, | 1512 | .mask = 0xffffffff, |
| 1503 | .init = gic_enable_quirk_hip06_07, | 1513 | .init = gic_enable_quirk_hip06_07, |
| 1504 | }, | 1514 | }, |
| 1515 | { | ||
| 1516 | /* | ||
| 1517 | * Reserved register accesses generate a Synchronous | ||
| 1518 | * External Abort. This erratum applies to: | ||
| 1519 | * - ThunderX: CN88xx | ||
| 1520 | * - OCTEON TX: CN83xx, CN81xx | ||
| 1521 | * - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx* | ||
| 1522 | */ | ||
| 1523 | .desc = "GICv3: Cavium erratum 38539", | ||
| 1524 | .iidr = 0xa000034c, | ||
| 1525 | .mask = 0xe8f00fff, | ||
| 1526 | .init = gic_enable_quirk_cavium_38539, | ||
| 1527 | }, | ||
| 1505 | { | 1528 | { |
| 1506 | } | 1529 | } |
| 1507 | }; | 1530 | }; |
| @@ -1577,7 +1600,12 @@ static int __init gic_init_bases(void __iomem *dist_base, · 69 unmodified lines | |||
| 1577 | pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); | 1600 | pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); |
| 1578 | pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR); | 1601 | pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR); |
| 1579 | 1602 | ||
| 1580 | gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2); | 1603 | /* |
| 1604 | * ThunderX1 explodes on reading GICD_TYPER2, in violation of the | ||
| 1605 | * architecture spec (which says that reserved registers are RES0). | ||
| 1606 | */ | ||
| 1607 | if (!(gic_data.flags & FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539)) | ||
| 1608 | gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2); | ||
| 1581 | 1609 | ||
| 1582 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, | 1610 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, |
| 1583 | &gic_data); | 1611 | &gic_data); |
| @@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = { · 311 unmodified lines | |||
| 312 | }; | 312 | }; |
| 313 | MODULE_DEVICE_TABLE(i2c, wf_ad7417_id); | 313 | MODULE_DEVICE_TABLE(i2c, wf_ad7417_id); |
| 314 | 314 | ||
| 315 | static const struct of_device_id wf_ad7417_of_id[] = { | ||
| 316 | { .compatible = "ad7417", }, | ||
| 317 | { } | ||
| 318 | }; | ||
| 319 | MODULE_DEVICE_TABLE(of, wf_ad7417_of_id); | ||
| 320 | |||
| 315 | static struct i2c_driver wf_ad7417_driver = { | 321 | static struct i2c_driver wf_ad7417_driver = { |
| 316 | .driver = { | 322 | .driver = { |
| 317 | .name = "wf_ad7417", | 323 | .name = "wf_ad7417", |
| 324 | .of_match_table = wf_ad7417_of_id, | ||
| 318 | }, | 325 | }, |
| 319 | .probe = wf_ad7417_probe, | 326 | .probe = wf_ad7417_probe, |
| 320 | .remove = wf_ad7417_remove, | 327 | .remove = wf_ad7417_remove, |
| @@ -580,9 +580,16 @@ static const struct i2c_device_id wf_fcu_id[] = { · 579 unmodified lines | |||
| 580 | }; | 580 | }; |
| 581 | MODULE_DEVICE_TABLE(i2c, wf_fcu_id); | 581 | MODULE_DEVICE_TABLE(i2c, wf_fcu_id); |
| 582 | 582 | ||
| 583 | static const struct of_device_id wf_fcu_of_id[] = { | ||
| 584 | { .compatible = "fcu", }, | ||
| 585 | { } | ||
| 586 | }; | ||
| 587 | MODULE_DEVICE_TABLE(of, wf_fcu_of_id); | ||
| 588 | |||
| 583 | static struct i2c_driver wf_fcu_driver = { | 589 | static struct i2c_driver wf_fcu_driver = { |
| 584 | .driver = { | 590 | .driver = { |
| 585 | .name = "wf_fcu", | 591 | .name = "wf_fcu", |
| 592 | .of_match_table = wf_fcu_of_id, | ||
| 586 | }, | 593 | }, |
| 587 | .probe = wf_fcu_probe, | 594 | .probe = wf_fcu_probe, |
| 588 | .remove = wf_fcu_remove, | 595 | .remove = wf_fcu_remove, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/wait.h> | 15 | #include <linux/wait.h> |
| 16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
| 17 | #include <linux/of_device.h> | ||
| 17 | #include <asm/prom.h> | 18 | #include <asm/prom.h> |
| 18 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
| 19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
| @@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client, · 71 unmodified lines | |||
| 91 | const struct i2c_device_id *id) | 92 | const struct i2c_device_id *id) |
| 92 | { | 93 | { |
| 93 | struct wf_lm75_sensor *lm; | 94 | struct wf_lm75_sensor *lm; |
| 94 | int rc, ds1775 = id->driver_data; | 95 | int rc, ds1775; |
| 95 | const char *name, *loc; | 96 | const char *name, *loc; |
| 96 | 97 | ||
| 98 | if (id) | ||
| 99 | ds1775 = id->driver_data; | ||
| 100 | else | ||
| 101 | ds1775 = !!of_device_get_match_data(&client->dev); | ||
| 102 | |||
| 97 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | 103 | DBG("wf_lm75: creating %s device at address 0x%02x\n", |
| 98 | ds1775 ? "ds1775" : "lm75", client->addr); | 104 | ds1775 ? "ds1775" : "lm75", client->addr); |
| 99 | 105 | ||
| @@ -164,9 +170,17 @@ static const struct i2c_device_id wf_lm75_id[] = { · 64 unmodified lines | |||
| 164 | }; | 170 | }; |
| 165 | MODULE_DEVICE_TABLE(i2c, wf_lm75_id); | 171 | MODULE_DEVICE_TABLE(i2c, wf_lm75_id); |
| 166 | 172 | ||
| 173 | static const struct of_device_id wf_lm75_of_id[] = { | ||
| 174 | { .compatible = "lm75", .data = (void *)0}, | ||
| 175 | { .compatible = "ds1775", .data = (void *)1 }, | ||
| 176 | { } | ||
| 177 | }; | ||
| 178 | MODULE_DEVICE_TABLE(of, wf_lm75_of_id); | ||
| 179 | |||
| 167 | static struct i2c_driver wf_lm75_driver = { | 180 | static struct i2c_driver wf_lm75_driver = { |
| 168 | .driver = { | 181 | .driver = { |
| 169 | .name = "wf_lm75", | 182 | .name = "wf_lm75", |
| 183 | .of_match_table = wf_lm75_of_id, | ||
| 170 | }, | 184 | }, |
| 171 | .probe = wf_lm75_probe, | 185 | .probe = wf_lm75_probe, |
| 172 | .remove = wf_lm75_remove, | 186 | .remove = wf_lm75_remove, |
| @@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = { · 165 unmodified lines | |||
| 166 | }; | 166 | }; |
| 167 | MODULE_DEVICE_TABLE(i2c, wf_lm87_id); | 167 | MODULE_DEVICE_TABLE(i2c, wf_lm87_id); |
| 168 | 168 | ||
| 169 | static const struct of_device_id wf_lm87_of_id[] = { | ||
| 170 | { .compatible = "lm87cimt", }, | ||
| 171 | { } | ||
| 172 | }; | ||
| 173 | MODULE_DEVICE_TABLE(of, wf_lm87_of_id); | ||
| 174 | |||
| 169 | static struct i2c_driver wf_lm87_driver = { | 175 | static struct i2c_driver wf_lm87_driver = { |
| 170 | .driver = { | 176 | .driver = { |
| 171 | .name = "wf_lm87", | 177 | .name = "wf_lm87", |
| 178 | .of_match_table = wf_lm87_of_id, | ||
| 172 | }, | 179 | }, |
| 173 | .probe = wf_lm87_probe, | 180 | .probe = wf_lm87_probe, |
| 174 | .remove = wf_lm87_remove, | 181 | .remove = wf_lm87_remove, |
| @@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = { · 119 unmodified lines | |||
| 120 | }; | 120 | }; |
| 121 | MODULE_DEVICE_TABLE(i2c, wf_max6690_id); | 121 | MODULE_DEVICE_TABLE(i2c, wf_max6690_id); |
| 122 | 122 | ||
| 123 | static const struct of_device_id wf_max6690_of_id[] = { | ||
| 124 | { .compatible = "max6690", }, | ||
| 125 | { } | ||
| 126 | }; | ||
| 127 | MODULE_DEVICE_TABLE(of, wf_max6690_of_id); | ||
| 128 | |||
| 123 | static struct i2c_driver wf_max6690_driver = { | 129 | static struct i2c_driver wf_max6690_driver = { |
| 124 | .driver = { | 130 | .driver = { |
| 125 | .name = "wf_max6690", | 131 | .name = "wf_max6690", |
| 132 | .of_match_table = wf_max6690_of_id, | ||
| 126 | }, | 133 | }, |
| 127 | .probe = wf_max6690_probe, | 134 | .probe = wf_max6690_probe, |
| 128 | .remove = wf_max6690_remove, | 135 | .remove = wf_max6690_remove, |
| @@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = { · 340 unmodified lines | |||
| 341 | }; | 341 | }; |
| 342 | MODULE_DEVICE_TABLE(i2c, wf_sat_id); | 342 | MODULE_DEVICE_TABLE(i2c, wf_sat_id); |
| 343 | 343 | ||
| 344 | static const struct of_device_id wf_sat_of_id[] = { | ||
| 345 | { .compatible = "smu-sat", }, | ||
| 346 | { } | ||
| 347 | }; | ||
| 348 | MODULE_DEVICE_TABLE(of, wf_sat_of_id); | ||
| 349 | |||
| 344 | static struct i2c_driver wf_sat_driver = { | 350 | static struct i2c_driver wf_sat_driver = { |
| 345 | .driver = { | 351 | .driver = { |
| 346 | .name = "wf_smu_sat", | 352 | .name = "wf_smu_sat", |
| 353 | .of_match_table = wf_sat_of_id, | ||
| 347 | }, | 354 | }, |
| 348 | .probe = wf_sat_probe, | 355 | .probe = wf_sat_probe, |
| 349 | .remove = wf_sat_remove, | 356 | .remove = wf_sat_remove, |
| @@ -394,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = { · 393 unmodified lines | |||
| 394 | void rts522a_init_params(struct rtsx_pcr *pcr) | 394 | void rts522a_init_params(struct rtsx_pcr *pcr) |
| 395 | { | 395 | { |
| 396 | rts5227_init_params(pcr); | 396 | rts5227_init_params(pcr); |
| 397 | 397 | pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 20, 11); | |
| 398 | pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; | 398 | pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; |
| 399 | 399 | ||
| 400 | pcr->option.ocp_en = 1; | 400 | pcr->option.ocp_en = 1; |
| @@ -618,6 +618,7 @@ static const struct pcr_ops rts524a_pcr_ops = { · 617 unmodified lines | |||
| 618 | void rts524a_init_params(struct rtsx_pcr *pcr) | 618 | void rts524a_init_params(struct rtsx_pcr *pcr) |
| 619 | { | 619 | { |
| 620 | rts5249_init_params(pcr); | 620 | rts5249_init_params(pcr); |
| 621 | pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); | ||
| 621 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; | 622 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
| 622 | pcr->option.ltr_l1off_snooze_sspwrgate = | 623 | pcr->option.ltr_l1off_snooze_sspwrgate = |
| 623 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; | 624 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
| @@ -733,6 +734,7 @@ static const struct pcr_ops rts525a_pcr_ops = { · 109 unmodified lines | |||
| 733 | void rts525a_init_params(struct rtsx_pcr *pcr) | 734 | void rts525a_init_params(struct rtsx_pcr *pcr) |
| 734 | { | 735 | { |
| 735 | rts5249_init_params(pcr); | 736 | rts5249_init_params(pcr); |
| 737 | pcr->tx_initial_phase = SET_CLOCK_PHASE(25, 29, 11); | ||
| 736 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; | 738 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
| 737 | pcr->option.ltr_l1off_snooze_sspwrgate = | 739 | pcr->option.ltr_l1off_snooze_sspwrgate = |
| 738 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; | 740 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
| @@ -662,7 +662,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr) · 661 unmodified lines | |||
| 662 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; | 662 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
| 663 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; | 663 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
| 664 | pcr->aspm_en = ASPM_L1_EN; | 664 | pcr->aspm_en = ASPM_L1_EN; |
| 665 | pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16); | 665 | pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); |
| 666 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); | 666 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
| 667 | 667 | ||
| 668 | pcr->ic_version = rts5260_get_ic_version(pcr); | 668 | pcr->ic_version = rts5260_get_ic_version(pcr); |
| @@ -764,7 +764,7 @@ void rts5261_init_params(struct rtsx_pcr *pcr) · 763 unmodified lines | |||
| 764 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; | 764 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
| 765 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; | 765 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
| 766 | pcr->aspm_en = ASPM_L1_EN; | 766 | pcr->aspm_en = ASPM_L1_EN; |
| 767 | pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 27, 16); | 767 | pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 11); |
| 768 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); | 768 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
| 769 | 769 | ||
| 770 | pcr->ic_version = rts5261_get_ic_version(pcr); | 770 | pcr->ic_version = rts5261_get_ic_version(pcr); |
| @@ -712,13 +712,14 @@ static int at24_probe(struct i2c_client *client) · 711 unmodified lines | |||
| 712 | * chip is functional. | 712 | * chip is functional. |
| 713 | */ | 713 | */ |
| 714 | err = at24_read(at24, 0, &test_byte, 1); | 714 | err = at24_read(at24, 0, &test_byte, 1); |
| 715 | pm_runtime_idle(dev); | ||
| 716 | if (err) { | 715 | if (err) { |
| 717 | pm_runtime_disable(dev); | 716 | pm_runtime_disable(dev); |
| 718 | regulator_disable(at24->vcc_reg); | 717 | regulator_disable(at24->vcc_reg); |
| 719 | return -ENODEV; | 718 | return -ENODEV; |
| 720 | } | 719 | } |
| 721 | 720 | ||
| 721 | pm_runtime_idle(dev); | ||
| 722 | |||
| 722 | if (writable) | 723 | if (writable) |
| 723 | dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n", | 724 | dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n", |
| 724 | byte_len, client->name, at24->write_max); | 725 | byte_len, client->name, at24->write_max); |
| @@ -1732,8 +1732,11 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, · 1731 unmodified lines | |||
| 1732 | * the erase operation does not exceed the max_busy_timeout, we should | 1732 | * the erase operation does not exceed the max_busy_timeout, we should |
| 1733 | * use R1B response. Or we need to prevent the host from doing hw busy | 1733 | * use R1B response. Or we need to prevent the host from doing hw busy |
| 1734 | * detection, which is done by converting to a R1 response instead. | 1734 | * detection, which is done by converting to a R1 response instead. |
| 1735 | * Note, some hosts requires R1B, which also means they are on their own | ||
| 1736 | * when it comes to deal with the busy timeout. | ||
| 1735 | */ | 1737 | */ |
| 1736 | if (card->host->max_busy_timeout && | 1738 | if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) && |
| 1739 | card->host->max_busy_timeout && | ||
| 1737 | busy_timeout > card->host->max_busy_timeout) { | 1740 | busy_timeout > card->host->max_busy_timeout) { |
| 1738 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; | 1741 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
| 1739 | } else { | 1742 | } else { |
| @@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host) · 1909 unmodified lines | |||
| 1910 | * If the max_busy_timeout of the host is specified, validate it against | 1910 | * If the max_busy_timeout of the host is specified, validate it against |
| 1911 | * the sleep cmd timeout. A failure means we need to prevent the host | 1911 | * the sleep cmd timeout. A failure means we need to prevent the host |
| 1912 | * from doing hw busy detection, which is done by converting to a R1 | 1912 | * from doing hw busy detection, which is done by converting to a R1 |
| 1913 | * response instead of a R1B. | 1913 | * response instead of a R1B. Note, some hosts requires R1B, which also |
| 1914 | * means they are on their own when it comes to deal with the busy | ||
| 1915 | * timeout. | ||
| 1914 | */ | 1916 | */ |
| 1915 | if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { | 1917 | if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && |
| 1918 | (timeout_ms > host->max_busy_timeout)) { | ||
| 1916 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 1919 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 1917 | } else { | 1920 | } else { |
| 1918 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | 1921 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; |
| @@ -542,9 +542,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, · 541 unmodified lines | |||
| 542 | * If the max_busy_timeout of the host is specified, make sure it's | 542 | * If the max_busy_timeout of the host is specified, make sure it's |
| 543 | * enough to fit the used timeout_ms. In case it's not, let's instruct | 543 | * enough to fit the used timeout_ms. In case it's not, let's instruct |
| 544 | * the host to avoid HW busy detection, by converting to a R1 response | 544 | * the host to avoid HW busy detection, by converting to a R1 response |
| 545 | * instead of a R1B. | 545 | * instead of a R1B. Note, some hosts requires R1B, which also means |
| 546 | * they are on their own when it comes to deal with the busy timeout. | ||
| 546 | */ | 547 | */ |
| 547 | if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) | 548 | if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && |
| 549 | (timeout_ms > host->max_busy_timeout)) | ||
| 548 | use_r1b_resp = false; | 550 | use_r1b_resp = false; |
| 549 | 551 | ||
| 550 | cmd.opcode = MMC_SWITCH; | 552 | cmd.opcode = MMC_SWITCH; |
| @@ -606,19 +606,22 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host, · 605 unmodified lines | |||
| 606 | u8 sample_point, bool rx) | 606 | u8 sample_point, bool rx) |
| 607 | { | 607 | { |
| 608 | struct rtsx_pcr *pcr = host->pcr; | 608 | struct rtsx_pcr *pcr = host->pcr; |
| 609 | 609 | u16 SD_VP_CTL = 0; | |
| 610 | dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", | 610 | dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", |
| 611 | __func__, rx ? "RX" : "TX", sample_point); | 611 | __func__, rx ? "RX" : "TX", sample_point); |
| 612 | 612 | ||
| 613 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, CHANGE_CLK); | 613 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, CHANGE_CLK); |
| 614 | if (rx) | 614 | if (rx) { |
| 615 | SD_VP_CTL = SD_VPRX_CTL; | ||
| 615 | rtsx_pci_write_register(pcr, SD_VPRX_CTL, | 616 | rtsx_pci_write_register(pcr, SD_VPRX_CTL, |
| 616 | PHASE_SELECT_MASK, sample_point); | 617 | PHASE_SELECT_MASK, sample_point); |
| 617 | else | 618 | } else { |
| 619 | SD_VP_CTL = SD_VPTX_CTL; | ||
| 618 | rtsx_pci_write_register(pcr, SD_VPTX_CTL, | 620 | rtsx_pci_write_register(pcr, SD_VPTX_CTL, |
| 619 | PHASE_SELECT_MASK, sample_point); | 621 | PHASE_SELECT_MASK, sample_point); |
| 620 | rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); | 622 | } |
| 621 | rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, | 623 | rtsx_pci_write_register(pcr, SD_VP_CTL, PHASE_NOT_RESET, 0); |
| 624 | rtsx_pci_write_register(pcr, SD_VP_CTL, PHASE_NOT_RESET, | ||
| 622 | PHASE_NOT_RESET); | 625 | PHASE_NOT_RESET); |
| 623 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, 0); | 626 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, 0); |
| 624 | rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); | 627 | rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
| 24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
| 25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
| 26 | #include <linux/dmi.h> | ||
| 26 | 27 | ||
| 27 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
| 28 | #include <linux/mmc/pm.h> | 29 | #include <linux/mmc/pm.h> |
| @@ -72,9 +73,16 @@ struct sdhci_acpi_host { · 43 unmodified lines | |||
| 72 | const struct sdhci_acpi_slot *slot; | 73 | const struct sdhci_acpi_slot *slot; |
| 73 | struct platform_device *pdev; | 74 | struct platform_device *pdev; |
| 74 | bool use_runtime_pm; | 75 | bool use_runtime_pm; |
| 76 | bool is_intel; | ||
| 77 | bool reset_signal_volt_on_suspend; | ||
| 75 | unsigned long private[0] ____cacheline_aligned; | 78 | unsigned long private[0] ____cacheline_aligned; |
| 76 | }; | 79 | }; |
| 77 | 80 | ||
| 81 | enum { | ||
| 82 | DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP = BIT(0), | ||
| 83 | DMI_QUIRK_SD_NO_WRITE_PROTECT = BIT(1), | ||
| 84 | }; | ||
| 85 | |||
| 78 | static inline void *sdhci_acpi_priv(struct sdhci_acpi_host *c) | 86 | static inline void *sdhci_acpi_priv(struct sdhci_acpi_host *c) |
| 79 | { | 87 | { |
| 80 | return (void *)c->private; | 88 | return (void *)c->private; |
| @@ -391,6 +399,8 @@ static int intel_probe_slot(struct platform_device *pdev, struct acpi_device *ad · 310 unmodified lines | |||
| 391 | host->mmc_host_ops.start_signal_voltage_switch = | 399 | host->mmc_host_ops.start_signal_voltage_switch = |
| 392 | intel_start_signal_voltage_switch; | 400 | intel_start_signal_voltage_switch; |
| 393 | 401 | ||
| 402 | c->is_intel = true; | ||
| 403 | |||
| 394 | return 0; | 404 | return 0; |
| 395 | } | 405 | } |
| 396 | 406 | ||
| @@ -647,6 +657,36 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { · 250 unmodified lines | |||
| 647 | }; | 657 | }; |
| 648 | MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); | 658 | MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); |
| 649 | 659 | ||
| 660 | static const struct dmi_system_id sdhci_acpi_quirks[] = { | ||
| 661 | { | ||
| 662 | /* | ||
| 663 | * The Lenovo Miix 320-10ICR has a bug in the _PS0 method of | ||
| 664 | * the SHC1 ACPI device, this bug causes it to reprogram the | ||
| 665 | * wrong LDO (DLDO3) to 1.8V if 1.8V modes are used and the | ||
| 666 | * card is (runtime) suspended + resumed. DLDO3 is used for | ||
| 667 | * the LCD and setting it to 1.8V causes the LCD to go black. | ||
| 668 | */ | ||
| 669 | .matches = { | ||
| 670 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 671 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), | ||
| 672 | }, | ||
| 673 | .driver_data = (void *)DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP, | ||
| 674 | }, | ||
| 675 | { | ||
| 676 | /* | ||
| 677 | * The Acer Aspire Switch 10 (SW5-012) microSD slot always | ||
| 678 | * reports the card being write-protected even though microSD | ||
| 679 | * cards do not have a write-protect switch at all. | ||
| 680 | */ | ||
| 681 | .matches = { | ||
| 682 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 683 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), | ||
| 684 | }, | ||
| 685 | .driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT, | ||
| 686 | }, | ||
| 687 | {} /* Terminating entry */ | ||
| 688 | }; | ||
| 689 | |||
| 650 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(struct acpi_device *adev) | 690 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(struct acpi_device *adev) |
| 651 | { | 691 | { |
| 652 | const struct sdhci_acpi_uid_slot *u; | 692 | const struct sdhci_acpi_uid_slot *u; |
| @@ -663,17 +703,23 @@ static int sdhci_acpi_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 663 | struct device *dev = &pdev->dev; | 703 | struct device *dev = &pdev->dev; |
| 664 | const struct sdhci_acpi_slot *slot; | 704 | const struct sdhci_acpi_slot *slot; |
| 665 | struct acpi_device *device, *child; | 705 | struct acpi_device *device, *child; |
| 706 | const struct dmi_system_id *id; | ||
| 666 | struct sdhci_acpi_host *c; | 707 | struct sdhci_acpi_host *c; |
| 667 | struct sdhci_host *host; | 708 | struct sdhci_host *host; |
| 668 | struct resource *iomem; | 709 | struct resource *iomem; |
| 669 | resource_size_t len; | 710 | resource_size_t len; |
| 670 | size_t priv_size; | 711 | size_t priv_size; |
| 712 | int quirks = 0; | ||
| 671 | int err; | 713 | int err; |
| 672 | 714 | ||
| 673 | device = ACPI_COMPANION(dev); | 715 | device = ACPI_COMPANION(dev); |
| 674 | if (!device) | 716 | if (!device) |
| 675 | return -ENODEV; | 717 | return -ENODEV; |
| 676 | 718 | ||
| 719 | id = dmi_first_match(sdhci_acpi_quirks); | ||
| 720 | if (id) | ||
| 721 | quirks = (long)id->driver_data; | ||
| 722 | |||
| 677 | slot = sdhci_acpi_get_slot(device); | 723 | slot = sdhci_acpi_get_slot(device); |
| 678 | 724 | ||
| 679 | /* Power on the SDHCI controller and its children */ | 725 | /* Power on the SDHCI controller and its children */ |
| @@ -759,6 +805,12 @@ static int sdhci_acpi_probe(struct platform_device *pdev) · 79 unmodified lines | |||
| 759 | dev_warn(dev, "failed to setup card detect gpio\n"); | 805 | dev_warn(dev, "failed to setup card detect gpio\n"); |
| 760 | c->use_runtime_pm = false; | 806 | c->use_runtime_pm = false; |
| 761 | } | 807 | } |
| 808 | |||
| 809 | if (quirks & DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP) | ||
| 810 | c->reset_signal_volt_on_suspend = true; | ||
| 811 | |||
| 812 | if (quirks & DMI_QUIRK_SD_NO_WRITE_PROTECT) | ||
| 813 | host->mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; | ||
| 762 | } | 814 | } |
| 763 | 815 | ||
| 764 | err = sdhci_setup_host(host); | 816 | err = sdhci_setup_host(host); |
| @@ -823,17 +875,39 @@ static int sdhci_acpi_remove(struct platform_device *pdev) · 58 unmodified lines | |||
| 823 | return 0; | 875 | return 0; |
| 824 | } | 876 | } |
| 825 | 877 | ||
| 878 | static void __maybe_unused sdhci_acpi_reset_signal_voltage_if_needed( | ||
| 879 | struct device *dev) | ||
| 880 | { | ||
| 881 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); | ||
| 882 | struct sdhci_host *host = c->host; | ||
| 883 | |||
| 884 | if (c->is_intel && c->reset_signal_volt_on_suspend && | ||
| 885 | host->mmc->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_330) { | ||
| 886 | struct intel_host *intel_host = sdhci_acpi_priv(c); | ||
| 887 | unsigned int fn = INTEL_DSM_V33_SWITCH; | ||
| 888 | u32 result = 0; | ||
| 889 | |||
| 890 | intel_dsm(intel_host, dev, fn, &result); | ||
| 891 | } | ||
| 892 | } | ||
| 893 | |||
| 826 | #ifdef CONFIG_PM_SLEEP | 894 | #ifdef CONFIG_PM_SLEEP |
| 827 | 895 | ||
| 828 | static int sdhci_acpi_suspend(struct device *dev) | 896 | static int sdhci_acpi_suspend(struct device *dev) |
| 829 | { | 897 | { |
| 830 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); | 898 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 831 | struct sdhci_host *host = c->host; | 899 | struct sdhci_host *host = c->host; |
| 900 | int ret; | ||
| 832 | 901 | ||
| 833 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) | 902 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
| 834 | mmc_retune_needed(host->mmc); | 903 | mmc_retune_needed(host->mmc); |
| 835 | 904 | ||
| 836 | return sdhci_suspend_host(host); | 905 | ret = sdhci_suspend_host(host); |
| 906 | if (ret) | ||
| 907 | return ret; | ||
| 908 | |||
| 909 | sdhci_acpi_reset_signal_voltage_if_needed(dev); | ||
| 910 | return 0; | ||
| 837 | } | 911 | } |
| 838 | 912 | ||
| 839 | static int sdhci_acpi_resume(struct device *dev) | 913 | static int sdhci_acpi_resume(struct device *dev) |
| @@ -853,11 +927,17 @@ static int sdhci_acpi_runtime_suspend(struct device *dev) · 13 unmodified lines | |||
| 853 | { | 927 | { |
| 854 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); | 928 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 855 | struct sdhci_host *host = c->host; | 929 | struct sdhci_host *host = c->host; |
| 930 | int ret; | ||
| 856 | 931 | ||
| 857 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) | 932 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
| 858 | mmc_retune_needed(host->mmc); | 933 | mmc_retune_needed(host->mmc); |
| 859 | 934 | ||
| 860 | return sdhci_runtime_suspend_host(host); | 935 | ret = sdhci_runtime_suspend_host(host); |
| 936 | if (ret) | ||
| 937 | return ret; | ||
| 938 | |||
| 939 | sdhci_acpi_reset_signal_voltage_if_needed(dev); | ||
| 940 | return 0; | ||
| 861 | } | 941 | } |
| 862 | 942 | ||
| 863 | static int sdhci_acpi_runtime_resume(struct device *dev) | 943 | static int sdhci_acpi_runtime_resume(struct device *dev) |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/mmc/host.h> | 11 | #include <linux/mmc/host.h> |
| 12 | #include <linux/mmc/mmc.h> | 12 | #include <linux/mmc/mmc.h> |
| 13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
| 14 | #include <linux/of_device.h> | ||
| 14 | 15 | ||
| 15 | #include "sdhci-pltfm.h" | 16 | #include "sdhci-pltfm.h" |
| 16 | 17 | ||
| @@ -235,6 +236,11 @@ static const struct sdhci_ops sdhci_cdns_ops = { · 218 unmodified lines | |||
| 235 | .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, | 236 | .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, |
| 236 | }; | 237 | }; |
| 237 | 238 | ||
| 239 | static const struct sdhci_pltfm_data sdhci_cdns_uniphier_pltfm_data = { | ||
| 240 | .ops = &sdhci_cdns_ops, | ||
| 241 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | ||
| 242 | }; | ||
| 243 | |||
| 238 | static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { | 244 | static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { |
| 239 | .ops = &sdhci_cdns_ops, | 245 | .ops = &sdhci_cdns_ops, |
| 240 | }; | 246 | }; |
| @@ -334,6 +340,7 @@ static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc, · 93 unmodified lines | |||
| 334 | static int sdhci_cdns_probe(struct platform_device *pdev) | 340 | static int sdhci_cdns_probe(struct platform_device *pdev) |
| 335 | { | 341 | { |
| 336 | struct sdhci_host *host; | 342 | struct sdhci_host *host; |
| 343 | const struct sdhci_pltfm_data *data; | ||
| 337 | struct sdhci_pltfm_host *pltfm_host; | 344 | struct sdhci_pltfm_host *pltfm_host; |
| 338 | struct sdhci_cdns_priv *priv; | 345 | struct sdhci_cdns_priv *priv; |
| 339 | struct clk *clk; | 346 | struct clk *clk; |
| @@ -350,8 +357,12 @@ static int sdhci_cdns_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 350 | if (ret) | 357 | if (ret) |
| 351 | return ret; | 358 | return ret; |
| 352 | 359 | ||
| 360 | data = of_device_get_match_data(dev); | ||
| 361 | if (!data) | ||
| 362 | data = &sdhci_cdns_pltfm_data; | ||
| 363 | |||
| 353 | nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); | 364 | nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); |
| 354 | host = sdhci_pltfm_init(pdev, &sdhci_cdns_pltfm_data, | 365 | host = sdhci_pltfm_init(pdev, data, |
| 355 | struct_size(priv, phy_params, nr_phy_params)); | 366 | struct_size(priv, phy_params, nr_phy_params)); |
| 356 | if (IS_ERR(host)) { | 367 | if (IS_ERR(host)) { |
| 357 | ret = PTR_ERR(host); | 368 | ret = PTR_ERR(host); |
| @@ -431,7 +442,10 @@ static const struct dev_pm_ops sdhci_cdns_pm_ops = { · 73 unmodified lines | |||
| 431 | }; | 442 | }; |
| 432 | 443 | ||
| 433 | static const struct of_device_id sdhci_cdns_match[] = { | 444 | static const struct of_device_id sdhci_cdns_match[] = { |
| 434 | { .compatible = "socionext,uniphier-sd4hc" }, | 445 | { |
| 446 | .compatible = "socionext,uniphier-sd4hc", | ||
| 447 | .data = &sdhci_cdns_uniphier_pltfm_data, | ||
| 448 | }, | ||
| 435 | { .compatible = "cdns,sd4hc" }, | 449 | { .compatible = "cdns,sd4hc" }, |
| 436 | { /* sentinel */ } | 450 | { /* sentinel */ } |
| 437 | }; | 451 | }; |
| @@ -132,7 +132,8 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) · 131 unmodified lines | |||
| 132 | 132 | ||
| 133 | sdhci_reset(host, mask); | 133 | sdhci_reset(host, mask); |
| 134 | 134 | ||
| 135 | if (host->mmc->caps & MMC_CAP_NONREMOVABLE) | 135 | if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) |
| 136 | || mmc_gpio_get_cd(host->mmc) >= 0) | ||
| 136 | sdhci_at91_set_force_card_detect(host); | 137 | sdhci_at91_set_force_card_detect(host); |
| 137 | 138 | ||
| 138 | if (priv->cal_always_on && (mask & SDHCI_RESET_ALL)) | 139 | if (priv->cal_always_on && (mask & SDHCI_RESET_ALL)) |
| @@ -427,8 +428,11 @@ static int sdhci_at91_probe(struct platform_device *pdev) · 288 unmodified lines | |||
| 427 | * detection procedure using the SDMCC_CD signal is bypassed. | 428 | * detection procedure using the SDMCC_CD signal is bypassed. |
| 428 | * This bit is reset when a software reset for all command is performed | 429 | * This bit is reset when a software reset for all command is performed |
| 429 | * so we need to implement our own reset function to set back this bit. | 430 | * so we need to implement our own reset function to set back this bit. |
| 431 | * | ||
| 432 | * WA: SAMA5D2 doesn't drive CMD if using CD GPIO line. | ||
| 430 | */ | 433 | */ |
| 431 | if (host->mmc->caps & MMC_CAP_NONREMOVABLE) | 434 | if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) |
| 435 | || mmc_gpio_get_cd(host->mmc) >= 0) | ||
| 432 | sdhci_at91_set_force_card_detect(host); | 436 | sdhci_at91_set_force_card_detect(host); |
| 433 | 437 | ||
| 434 | pm_runtime_put_autosuspend(&pdev->dev); | 438 | pm_runtime_put_autosuspend(&pdev->dev); |
| @@ -1192,6 +1192,9 @@ static int sdhci_omap_probe(struct platform_device *pdev) · 1191 unmodified lines | |||
| 1192 | if (of_find_property(dev->of_node, "dmas", NULL)) | 1192 | if (of_find_property(dev->of_node, "dmas", NULL)) |
| 1193 | sdhci_switch_external_dma(host, true); | 1193 | sdhci_switch_external_dma(host, true); |
| 1194 | 1194 | ||
| 1195 | /* R1B responses is required to properly manage HW busy detection. */ | ||
| 1196 | mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | ||
| 1197 | |||
| 1195 | ret = sdhci_setup_host(host); | 1198 | ret = sdhci_setup_host(host); |
| 1196 | if (ret) | 1199 | if (ret) |
| 1197 | goto err_put_sync; | 1200 | goto err_put_sync; |
| @@ -1552,6 +1552,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev) · 1551 unmodified lines | |||
| 1552 | if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) | 1552 | if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) |
| 1553 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | 1553 | host->mmc->caps |= MMC_CAP_1_8V_DDR; |
| 1554 | 1554 | ||
| 1555 | /* R1B responses is required to properly manage HW busy detection. */ | ||
| 1556 | host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | ||
| 1557 | |||
| 1555 | tegra_sdhci_parse_dt(host); | 1558 | tegra_sdhci_parse_dt(host); |
| 1556 | 1559 | ||
| 1557 | tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", | 1560 | tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", |
| @@ -149,6 +149,7 @@ config NET_FC · 148 unmodified lines | |||
| 149 | config IFB | 149 | config IFB |
| 150 | tristate "Intermediate Functional Block support" | 150 | tristate "Intermediate Functional Block support" |
| 151 | depends on NET_CLS_ACT | 151 | depends on NET_CLS_ACT |
| 152 | select NET_REDIRECT | ||
| 152 | ---help--- | 153 | ---help--- |
| 153 | This is an intermediate driver that allows sharing of | 154 | This is an intermediate driver that allows sharing of |
| 154 | resources. | 155 | resources. |
| @@ -141,29 +141,29 @@ static ssize_t dbgfs_state(struct file *file, char __user *user_buf, · 140 unmodified lines | |||
| 141 | return 0; | 141 | return 0; |
| 142 | 142 | ||
| 143 | /* Print out debug information. */ | 143 | /* Print out debug information. */ |
| 144 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 144 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 145 | "CAIF SPI debug information:\n"); | 145 | "CAIF SPI debug information:\n"); |
| 146 | 146 | ||
| 147 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR); | 147 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR); |
| 148 | 148 | ||
| 149 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 149 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 150 | "STATE: %d\n", cfspi->dbg_state); | 150 | "STATE: %d\n", cfspi->dbg_state); |
| 151 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 151 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 152 | "Previous CMD: 0x%x\n", cfspi->pcmd); | 152 | "Previous CMD: 0x%x\n", cfspi->pcmd); |
| 153 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 153 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 154 | "Current CMD: 0x%x\n", cfspi->cmd); | 154 | "Current CMD: 0x%x\n", cfspi->cmd); |
| 155 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 155 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 156 | "Previous TX len: %d\n", cfspi->tx_ppck_len); | 156 | "Previous TX len: %d\n", cfspi->tx_ppck_len); |
| 157 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 157 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 158 | "Previous RX len: %d\n", cfspi->rx_ppck_len); | 158 | "Previous RX len: %d\n", cfspi->rx_ppck_len); |
| 159 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 159 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 160 | "Current TX len: %d\n", cfspi->tx_cpck_len); | 160 | "Current TX len: %d\n", cfspi->tx_cpck_len); |
| 161 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 161 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 162 | "Current RX len: %d\n", cfspi->rx_cpck_len); | 162 | "Current RX len: %d\n", cfspi->rx_cpck_len); |
| 163 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 163 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 164 | "Next TX len: %d\n", cfspi->tx_npck_len); | 164 | "Next TX len: %d\n", cfspi->tx_npck_len); |
| 165 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 165 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 166 | "Next RX len: %d\n", cfspi->rx_npck_len); | 166 | "Next RX len: %d\n", cfspi->rx_npck_len); |
| 167 | 167 | ||
| 168 | if (len > DEBUGFS_BUF_SIZE) | 168 | if (len > DEBUGFS_BUF_SIZE) |
| 169 | len = DEBUGFS_BUF_SIZE; | 169 | len = DEBUGFS_BUF_SIZE; |
| @@ -180,23 +180,23 @@ static ssize_t print_frame(char *buf, size_t size, char *frm, · 10 unmodified lines | |||
| 180 | int len = 0; | 180 | int len = 0; |
| 181 | int i; | 181 | int i; |
| 182 | for (i = 0; i < count; i++) { | 182 | for (i = 0; i < count; i++) { |
| 183 | len += snprintf((buf + len), (size - len), | 183 | len += scnprintf((buf + len), (size - len), |
| 184 | "[0x" BYTE_HEX_FMT "]", | 184 | "[0x" BYTE_HEX_FMT "]", |
| 185 | frm[i]); | 185 | frm[i]); |
| 186 | if ((i == cut) && (count > (cut * 2))) { | 186 | if ((i == cut) && (count > (cut * 2))) { |
| 187 | /* Fast forward. */ | 187 | /* Fast forward. */ |
| 188 | i = count - cut; | 188 | i = count - cut; |
| 189 | len += snprintf((buf + len), (size - len), | 189 | len += scnprintf((buf + len), (size - len), |
| 190 | "--- %zu bytes skipped ---\n", | 190 | "--- %zu bytes skipped ---\n", |
| 191 | count - (cut * 2)); | 191 | count - (cut * 2)); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | if ((!(i % 10)) && i) { | 194 | if ((!(i % 10)) && i) { |
| 195 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 195 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 196 | "\n"); | 196 | "\n"); |
| 197 | } | 197 | } |
| 198 | } | 198 | } |
| 199 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "\n"); | 199 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "\n"); |
| 200 | return len; | 200 | return len; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| @@ -214,18 +214,18 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, · 11 unmodified lines | |||
| 214 | return 0; | 214 | return 0; |
| 215 | 215 | ||
| 216 | /* Print out debug information. */ | 216 | /* Print out debug information. */ |
| 217 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 217 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 218 | "Current frame:\n"); | 218 | "Current frame:\n"); |
| 219 | 219 | ||
| 220 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 220 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 221 | "Tx data (Len: %d):\n", cfspi->tx_cpck_len); | 221 | "Tx data (Len: %d):\n", cfspi->tx_cpck_len); |
| 222 | 222 | ||
| 223 | len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), | 223 | len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 224 | cfspi->xfer.va_tx[0], | 224 | cfspi->xfer.va_tx[0], |
| 225 | (cfspi->tx_cpck_len + SPI_CMD_SZ), 100); | 225 | (cfspi->tx_cpck_len + SPI_CMD_SZ), 100); |
| 226 | 226 | ||
| 227 | len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | 227 | len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 228 | "Rx data (Len: %d):\n", cfspi->rx_cpck_len); | 228 | "Rx data (Len: %d):\n", cfspi->rx_cpck_len); |
| 229 | 229 | ||
| 230 | len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), | 230 | len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 231 | cfspi->xfer.va_rx, | 231 | cfspi->xfer.va_rx, |
| @@ -622,7 +622,10 @@ err_free_chan: · 621 unmodified lines | |||
| 622 | tty->disc_data = NULL; | 622 | tty->disc_data = NULL; |
| 623 | clear_bit(SLF_INUSE, &sl->flags); | 623 | clear_bit(SLF_INUSE, &sl->flags); |
| 624 | slc_free_netdev(sl->dev); | 624 | slc_free_netdev(sl->dev); |
| 625 | /* do not call free_netdev before rtnl_unlock */ | ||
| 626 | rtnl_unlock(); | ||
| 625 | free_netdev(sl->dev); | 627 | free_netdev(sl->dev); |
| 628 | return err; | ||
| 626 | 629 | ||
| 627 | err_exit: | 630 | err_exit: |
| 628 | rtnl_unlock(); | 631 | rtnl_unlock(); |
| @@ -566,7 +566,7 @@ mt7530_mib_reset(struct dsa_switch *ds) · 565 unmodified lines | |||
| 566 | static void | 566 | static void |
| 567 | mt7530_port_set_status(struct mt7530_priv *priv, int port, int enable) | 567 | mt7530_port_set_status(struct mt7530_priv *priv, int port, int enable) |
| 568 | { | 568 | { |
| 569 | u32 mask = PMCR_TX_EN | PMCR_RX_EN; | 569 | u32 mask = PMCR_TX_EN | PMCR_RX_EN | PMCR_FORCE_LNK; |
| 570 | 570 | ||
| 571 | if (enable) | 571 | if (enable) |
| 572 | mt7530_set(priv, MT7530_PMCR_P(port), mask); | 572 | mt7530_set(priv, MT7530_PMCR_P(port), mask); |
| @@ -1502,7 +1502,7 @@ static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port, · 929 unmodified lines | |||
| 1502 | mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 | | 1502 | mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 | |
| 1503 | PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN); | 1503 | PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN); |
| 1504 | mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN | | 1504 | mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN | |
| 1505 | PMCR_BACKPR_EN | PMCR_FORCE_MODE | PMCR_FORCE_LNK; | 1505 | PMCR_BACKPR_EN | PMCR_FORCE_MODE; |
| 1506 | 1506 | ||
| 1507 | /* Are we connected to external phy */ | 1507 | /* Are we connected to external phy */ |
| 1508 | if (port == 5 && dsa_is_user_port(ds, 5)) | 1508 | if (port == 5 && dsa_is_user_port(ds, 5)) |
| @@ -1015,13 +1015,9 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num) · 1014 unmodified lines | |||
| 1015 | struct ena_rx_buffer *rx_info; | 1015 | struct ena_rx_buffer *rx_info; |
| 1016 | 1016 | ||
| 1017 | req_id = rx_ring->free_ids[next_to_use]; | 1017 | req_id = rx_ring->free_ids[next_to_use]; |
| 1018 | rc = validate_rx_req_id(rx_ring, req_id); | ||
| 1019 | if (unlikely(rc < 0)) | ||
| 1020 | break; | ||
| 1021 | 1018 | ||
| 1022 | rx_info = &rx_ring->rx_buffer_info[req_id]; | 1019 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1023 | 1020 | ||
| 1024 | |||
| 1025 | rc = ena_alloc_rx_page(rx_ring, rx_info, | 1021 | rc = ena_alloc_rx_page(rx_ring, rx_info, |
| 1026 | GFP_ATOMIC | __GFP_COMP); | 1022 | GFP_ATOMIC | __GFP_COMP); |
| 1027 | if (unlikely(rc < 0)) { | 1023 | if (unlikely(rc < 0)) { |
| @@ -1376,9 +1372,15 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, · 348 unmodified lines | |||
| 1376 | struct ena_rx_buffer *rx_info; | 1372 | struct ena_rx_buffer *rx_info; |
| 1377 | u16 len, req_id, buf = 0; | 1373 | u16 len, req_id, buf = 0; |
| 1378 | void *va; | 1374 | void *va; |
| 1375 | int rc; | ||
| 1379 | 1376 | ||
| 1380 | len = ena_bufs[buf].len; | 1377 | len = ena_bufs[buf].len; |
| 1381 | req_id = ena_bufs[buf].req_id; | 1378 | req_id = ena_bufs[buf].req_id; |
| 1379 | |||
| 1380 | rc = validate_rx_req_id(rx_ring, req_id); | ||
| 1381 | if (unlikely(rc < 0)) | ||
| 1382 | return NULL; | ||
| 1383 | |||
| 1382 | rx_info = &rx_ring->rx_buffer_info[req_id]; | 1384 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1383 | 1385 | ||
| 1384 | if (unlikely(!rx_info->page)) { | 1386 | if (unlikely(!rx_info->page)) { |
| @@ -1451,6 +1453,11 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, · 66 unmodified lines | |||
| 1451 | buf++; | 1453 | buf++; |
| 1452 | len = ena_bufs[buf].len; | 1454 | len = ena_bufs[buf].len; |
| 1453 | req_id = ena_bufs[buf].req_id; | 1455 | req_id = ena_bufs[buf].req_id; |
| 1456 | |||
| 1457 | rc = validate_rx_req_id(rx_ring, req_id); | ||
| 1458 | if (unlikely(rc < 0)) | ||
| 1459 | return NULL; | ||
| 1460 | |||
| 1454 | rx_info = &rx_ring->rx_buffer_info[req_id]; | 1461 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1455 | } while (1); | 1462 | } while (1); |
| 1456 | 1463 | ||
| @@ -1965,7 +1972,7 @@ static int ena_enable_msix(struct ena_adapter *adapter) · 508 unmodified lines | |||
| 1965 | } | 1972 | } |
| 1966 | 1973 | ||
| 1967 | /* Reserved the max msix vectors we might need */ | 1974 | /* Reserved the max msix vectors we might need */ |
| 1968 | msix_vecs = ENA_MAX_MSIX_VEC(adapter->num_io_queues); | 1975 | msix_vecs = ENA_MAX_MSIX_VEC(adapter->max_num_io_queues); |
| 1969 | netif_dbg(adapter, probe, adapter->netdev, | 1976 | netif_dbg(adapter, probe, adapter->netdev, |
| 1970 | "trying to enable MSI-X, vectors %d\n", msix_vecs); | 1977 | "trying to enable MSI-X, vectors %d\n", msix_vecs); |
| 1971 | 1978 | ||
| @@ -2065,6 +2072,7 @@ static int ena_request_mgmnt_irq(struct ena_adapter *adapter) · 93 unmodified lines | |||
| 2065 | 2072 | ||
| 2066 | static int ena_request_io_irq(struct ena_adapter *adapter) | 2073 | static int ena_request_io_irq(struct ena_adapter *adapter) |
| 2067 | { | 2074 | { |
| 2075 | u32 io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; | ||
| 2068 | unsigned long flags = 0; | 2076 | unsigned long flags = 0; |
| 2069 | struct ena_irq *irq; | 2077 | struct ena_irq *irq; |
| 2070 | int rc = 0, i, k; | 2078 | int rc = 0, i, k; |
| @@ -2075,7 +2083,7 @@ static int ena_request_io_irq(struct ena_adapter *adapter) · 4 unmodified lines | |||
| 2075 | return -EINVAL; | 2083 | return -EINVAL; |
| 2076 | } | 2084 | } |
| 2077 | 2085 | ||
| 2078 | for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) { | 2086 | for (i = ENA_IO_IRQ_FIRST_IDX; i < ENA_MAX_MSIX_VEC(io_queue_count); i++) { |
| 2079 | irq = &adapter->irq_tbl[i]; | 2087 | irq = &adapter->irq_tbl[i]; |
| 2080 | rc = request_irq(irq->vector, irq->handler, flags, irq->name, | 2088 | rc = request_irq(irq->vector, irq->handler, flags, irq->name, |
| 2081 | irq->data); | 2089 | irq->data); |
| @@ -2116,6 +2124,7 @@ static void ena_free_mgmnt_irq(struct ena_adapter *adapter) · 34 unmodified lines | |||
| 2116 | 2124 | ||
| 2117 | static void ena_free_io_irq(struct ena_adapter *adapter) | 2125 | static void ena_free_io_irq(struct ena_adapter *adapter) |
| 2118 | { | 2126 | { |
| 2127 | u32 io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; | ||
| 2119 | struct ena_irq *irq; | 2128 | struct ena_irq *irq; |
| 2120 | int i; | 2129 | int i; |
| 2121 | 2130 | ||
| @@ -2126,7 +2135,7 @@ static void ena_free_io_irq(struct ena_adapter *adapter) · 4 unmodified lines | |||
| 2126 | } | 2135 | } |
| 2127 | #endif /* CONFIG_RFS_ACCEL */ | 2136 | #endif /* CONFIG_RFS_ACCEL */ |
| 2128 | 2137 | ||
| 2129 | for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) { | 2138 | for (i = ENA_IO_IRQ_FIRST_IDX; i < ENA_MAX_MSIX_VEC(io_queue_count); i++) { |
| 2130 | irq = &adapter->irq_tbl[i]; | 2139 | irq = &adapter->irq_tbl[i]; |
| 2131 | irq_set_affinity_hint(irq->vector, NULL); | 2140 | irq_set_affinity_hint(irq->vector, NULL); |
| 2132 | free_irq(irq->vector, irq->data); | 2141 | free_irq(irq->vector, irq->data); |
| @@ -2141,12 +2150,13 @@ static void ena_disable_msix(struct ena_adapter *adapter) · 8 unmodified lines | |||
| 2141 | 2150 | ||
| 2142 | static void ena_disable_io_intr_sync(struct ena_adapter *adapter) | 2151 | static void ena_disable_io_intr_sync(struct ena_adapter *adapter) |
| 2143 | { | 2152 | { |
| 2153 | u32 io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; | ||
| 2144 | int i; | 2154 | int i; |
| 2145 | 2155 | ||
| 2146 | if (!netif_running(adapter->netdev)) | 2156 | if (!netif_running(adapter->netdev)) |
| 2147 | return; | 2157 | return; |
| 2148 | 2158 | ||
| 2149 | for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) | 2159 | for (i = ENA_IO_IRQ_FIRST_IDX; i < ENA_MAX_MSIX_VEC(io_queue_count); i++) |
| 2150 | synchronize_irq(adapter->irq_tbl[i].vector); | 2160 | synchronize_irq(adapter->irq_tbl[i].vector); |
| 2151 | } | 2161 | } |
| 2152 | 2162 | ||
| @@ -3474,6 +3484,7 @@ static int ena_restore_device(struct ena_adapter *adapter) · 1321 unmodified lines | |||
| 3474 | 3484 | ||
| 3475 | mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); | 3485 | mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); |
| 3476 | dev_err(&pdev->dev, "Device reset completed successfully\n"); | 3486 | dev_err(&pdev->dev, "Device reset completed successfully\n"); |
| 3487 | adapter->last_keep_alive_jiffies = jiffies; | ||
| 3477 | 3488 | ||
| 3478 | return rc; | 3489 | return rc; |
| 3479 | err_disable_msix: | 3490 | err_disable_msix: |
| @@ -4318,13 +4329,15 @@ err_disable_device: · 838 unmodified lines | |||
| 4318 | 4329 | ||
| 4319 | /*****************************************************************************/ | 4330 | /*****************************************************************************/ |
| 4320 | 4331 | ||
| 4321 | /* ena_remove - Device Removal Routine | 4332 | /* __ena_shutoff - Helper used in both PCI remove/shutdown routines |
| 4322 | * @pdev: PCI device information struct | 4333 | * @pdev: PCI device information struct |
| 4334 | * @shutdown: Is it a shutdown operation? If false, means it is a removal | ||
| 4323 | * | 4335 | * |
| 4324 | * ena_remove is called by the PCI subsystem to alert the driver | 4336 | * __ena_shutoff is a helper routine that does the real work on shutdown and |
| 4325 | * that it should release a PCI device. | 4337 | * removal paths; the difference between those paths is with regards to whether |
| 4338 | * dettach or unregister the netdevice. | ||
| 4326 | */ | 4339 | */ |
| 4327 | static void ena_remove(struct pci_dev *pdev) | 4340 | static void __ena_shutoff(struct pci_dev *pdev, bool shutdown) |
| 4328 | { | 4341 | { |
| 4329 | struct ena_adapter *adapter = pci_get_drvdata(pdev); | 4342 | struct ena_adapter *adapter = pci_get_drvdata(pdev); |
| 4330 | struct ena_com_dev *ena_dev; | 4343 | struct ena_com_dev *ena_dev; |
| @@ -4343,13 +4356,17 @@ static void ena_remove(struct pci_dev *pdev) · 12 unmodified lines | |||
| 4343 | 4356 | ||
| 4344 | cancel_work_sync(&adapter->reset_task); | 4357 | cancel_work_sync(&adapter->reset_task); |
| 4345 | 4358 | ||
| 4346 | rtnl_lock(); | 4359 | rtnl_lock(); /* lock released inside the below if-else block */ |
| 4347 | ena_destroy_device(adapter, true); | 4360 | ena_destroy_device(adapter, true); |
| 4348 | rtnl_unlock(); | 4361 | if (shutdown) { |
| 4349 | 4362 | netif_device_detach(netdev); | |
| 4350 | unregister_netdev(netdev); | 4363 | dev_close(netdev); |
| 4351 | 4364 | rtnl_unlock(); | |
| 4352 | free_netdev(netdev); | 4365 | } else { |
| 4366 | rtnl_unlock(); | ||
| 4367 | unregister_netdev(netdev); | ||
| 4368 | free_netdev(netdev); | ||
| 4369 | } | ||
| 4353 | 4370 | ||
| 4354 | ena_com_rss_destroy(ena_dev); | 4371 | ena_com_rss_destroy(ena_dev); |
| 4355 | 4372 | ||
| @@ -4364,6 +4381,30 @@ static void ena_remove(struct pci_dev *pdev) · 8 unmodified lines | |||
| 4364 | vfree(ena_dev); | 4381 | vfree(ena_dev); |
| 4365 | } | 4382 | } |
| 4366 | 4383 | ||
| 4384 | /* ena_remove - Device Removal Routine | ||
| 4385 | * @pdev: PCI device information struct | ||
| 4386 | * | ||
| 4387 | * ena_remove is called by the PCI subsystem to alert the driver | ||
| 4388 | * that it should release a PCI device. | ||
| 4389 | */ | ||
| 4390 | |||
| 4391 | static void ena_remove(struct pci_dev *pdev) | ||
| 4392 | { | ||
| 4393 | __ena_shutoff(pdev, false); | ||
| 4394 | } | ||
| 4395 | |||
| 4396 | /* ena_shutdown - Device Shutdown Routine | ||
| 4397 | * @pdev: PCI device information struct | ||
| 4398 | * | ||
| 4399 | * ena_shutdown is called by the PCI subsystem to alert the driver that | ||
| 4400 | * a shutdown/reboot (or kexec) is happening and device must be disabled. | ||
| 4401 | */ | ||
| 4402 | |||
| 4403 | static void ena_shutdown(struct pci_dev *pdev) | ||
| 4404 | { | ||
| 4405 | __ena_shutoff(pdev, true); | ||
| 4406 | } | ||
| 4407 | |||
| 4367 | #ifdef CONFIG_PM | 4408 | #ifdef CONFIG_PM |
| 4368 | /* ena_suspend - PM suspend callback | 4409 | /* ena_suspend - PM suspend callback |
| 4369 | * @pdev: PCI device information struct | 4410 | * @pdev: PCI device information struct |
| @@ -4413,6 +4454,7 @@ static struct pci_driver ena_pci_driver = { · 43 unmodified lines | |||
| 4413 | .id_table = ena_pci_tbl, | 4454 | .id_table = ena_pci_tbl, |
| 4414 | .probe = ena_probe, | 4455 | .probe = ena_probe, |
| 4415 | .remove = ena_remove, | 4456 | .remove = ena_remove, |
| 4457 | .shutdown = ena_shutdown, | ||
| 4416 | #ifdef CONFIG_PM | 4458 | #ifdef CONFIG_PM |
| 4417 | .suspend = ena_suspend, | 4459 | .suspend = ena_suspend, |
| 4418 | .resume = ena_resume, | 4460 | .resume = ena_resume, |
| @@ -6860,12 +6860,12 @@ skip_rdma: · 6859 unmodified lines | |||
| 6860 | } | 6860 | } |
| 6861 | ena |= FUNC_BACKING_STORE_CFG_REQ_DFLT_ENABLES; | 6861 | ena |= FUNC_BACKING_STORE_CFG_REQ_DFLT_ENABLES; |
| 6862 | rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); | 6862 | rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); |
| 6863 | if (rc) | 6863 | if (rc) { |
| 6864 | netdev_err(bp->dev, "Failed configuring context mem, rc = %d.\n", | 6864 | netdev_err(bp->dev, "Failed configuring context mem, rc = %d.\n", |
| 6865 | rc); | 6865 | rc); |
| 6866 | else | 6866 | return rc; |
| 6867 | ctx->flags |= BNXT_CTX_FLAG_INITED; | 6867 | } |
| 6868 | 6868 | ctx->flags |= BNXT_CTX_FLAG_INITED; | |
| 6869 | return 0; | 6869 | return 0; |
| 6870 | } | 6870 | } |
| 6871 | 6871 | ||
| @@ -7384,14 +7384,22 @@ static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp) · 512 unmodified lines | |||
| 7384 | pri2cos = &resp2->pri0_cos_queue_id; | 7384 | pri2cos = &resp2->pri0_cos_queue_id; |
| 7385 | for (i = 0; i < 8; i++) { | 7385 | for (i = 0; i < 8; i++) { |
| 7386 | u8 queue_id = pri2cos[i]; | 7386 | u8 queue_id = pri2cos[i]; |
| 7387 | u8 queue_idx; | ||
| 7387 | 7388 | ||
| 7389 | /* Per port queue IDs start from 0, 10, 20, etc */ | ||
| 7390 | queue_idx = queue_id % 10; | ||
| 7391 | if (queue_idx > BNXT_MAX_QUEUE) { | ||
| 7392 | bp->pri2cos_valid = false; | ||
| 7393 | goto qstats_done; | ||
| 7394 | } | ||
| 7388 | for (j = 0; j < bp->max_q; j++) { | 7395 | for (j = 0; j < bp->max_q; j++) { |
| 7389 | if (bp->q_ids[j] == queue_id) | 7396 | if (bp->q_ids[j] == queue_id) |
| 7390 | bp->pri2cos[i] = j; | 7397 | bp->pri2cos_idx[i] = queue_idx; |
| 7391 | } | 7398 | } |
| 7392 | } | 7399 | } |
| 7393 | bp->pri2cos_valid = 1; | 7400 | bp->pri2cos_valid = 1; |
| 7394 | } | 7401 | } |
| 7402 | qstats_done: | ||
| 7395 | mutex_unlock(&bp->hwrm_cmd_lock); | 7403 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 7396 | return rc; | 7404 | return rc; |
| 7397 | } | 7405 | } |
| @@ -11644,6 +11652,10 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) · 4246 unmodified lines | |||
| 11644 | bp->rx_nr_rings++; | 11652 | bp->rx_nr_rings++; |
| 11645 | bp->cp_nr_rings++; | 11653 | bp->cp_nr_rings++; |
| 11646 | } | 11654 | } |
| 11655 | if (rc) { | ||
| 11656 | bp->tx_nr_rings = 0; | ||
| 11657 | bp->rx_nr_rings = 0; | ||
| 11658 | } | ||
| 11647 | return rc; | 11659 | return rc; |
| 11648 | } | 11660 | } |
| 11649 | 11661 | ||
| @@ -11929,12 +11941,12 @@ init_err_pci_clean: · 279 unmodified lines | |||
| 11929 | bnxt_hwrm_func_drv_unrgtr(bp); | 11941 | bnxt_hwrm_func_drv_unrgtr(bp); |
| 11930 | bnxt_free_hwrm_short_cmd_req(bp); | 11942 | bnxt_free_hwrm_short_cmd_req(bp); |
| 11931 | bnxt_free_hwrm_resources(bp); | 11943 | bnxt_free_hwrm_resources(bp); |
| 11932 | bnxt_free_ctx_mem(bp); | ||
| 11933 | kfree(bp->ctx); | ||
| 11934 | bp->ctx = NULL; | ||
| 11935 | kfree(bp->fw_health); | 11944 | kfree(bp->fw_health); |
| 11936 | bp->fw_health = NULL; | 11945 | bp->fw_health = NULL; |
| 11937 | bnxt_cleanup_pci(bp); | 11946 | bnxt_cleanup_pci(bp); |
| 11947 | bnxt_free_ctx_mem(bp); | ||
| 11948 | kfree(bp->ctx); | ||
| 11949 | bp->ctx = NULL; | ||
| 11938 | 11950 | ||
| 11939 | init_err_free: | 11951 | init_err_free: |
| 11940 | free_netdev(dev); | 11952 | free_netdev(dev); |
| @@ -1718,7 +1718,7 @@ struct bnxt { · 1717 unmodified lines | |||
| 1718 | u16 fw_rx_stats_ext_size; | 1718 | u16 fw_rx_stats_ext_size; |
| 1719 | u16 fw_tx_stats_ext_size; | 1719 | u16 fw_tx_stats_ext_size; |
| 1720 | u16 hw_ring_stats_size; | 1720 | u16 hw_ring_stats_size; |
| 1721 | u8 pri2cos[8]; | 1721 | u8 pri2cos_idx[8]; |
| 1722 | u8 pri2cos_valid; | 1722 | u8 pri2cos_valid; |
| 1723 | 1723 | ||
| 1724 | u16 hwrm_max_req_len; | 1724 | u16 hwrm_max_req_len; |
| @@ -472,24 +472,26 @@ static int bnxt_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets) · 471 unmodified lines | |||
| 472 | { | 472 | { |
| 473 | struct bnxt *bp = netdev_priv(dev); | 473 | struct bnxt *bp = netdev_priv(dev); |
| 474 | struct ieee_ets *my_ets = bp->ieee_ets; | 474 | struct ieee_ets *my_ets = bp->ieee_ets; |
| 475 | int rc; | ||
| 475 | 476 | ||
| 476 | ets->ets_cap = bp->max_tc; | 477 | ets->ets_cap = bp->max_tc; |
| 477 | 478 | ||
| 478 | if (!my_ets) { | 479 | if (!my_ets) { |
| 479 | int rc; | ||
| 480 | |||
| 481 | if (bp->dcbx_cap & DCB_CAP_DCBX_HOST) | 480 | if (bp->dcbx_cap & DCB_CAP_DCBX_HOST) |
| 482 | return 0; | 481 | return 0; |
| 483 | 482 | ||
| 484 | my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL); | 483 | my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL); |
| 485 | if (!my_ets) | 484 | if (!my_ets) |
| 486 | return 0; | 485 | return -ENOMEM; |
| 487 | rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets); | 486 | rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets); |
| 488 | if (rc) | 487 | if (rc) |
| 489 | return 0; | 488 | goto error; |
| 490 | rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets); | 489 | rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets); |
| 491 | if (rc) | 490 | if (rc) |
| 492 | return 0; | 491 | goto error; |
| 492 | |||
| 493 | /* cache result */ | ||
| 494 | bp->ieee_ets = my_ets; | ||
| 493 | } | 495 | } |
| 494 | 496 | ||
| 495 | ets->cbs = my_ets->cbs; | 497 | ets->cbs = my_ets->cbs; |
| @@ -498,6 +500,9 @@ static int bnxt_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets) · 2 unmodified lines | |||
| 498 | memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); | 500 | memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); |
| 499 | memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); | 501 | memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); |
| 500 | return 0; | 502 | return 0; |
| 503 | error: | ||
| 504 | kfree(my_ets); | ||
| 505 | return rc; | ||
| 501 | } | 506 | } |
| 502 | 507 | ||
| 503 | static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets) | 508 | static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets) |
| @@ -589,25 +589,25 @@ skip_ring_stats: · 588 unmodified lines | |||
| 589 | if (bp->pri2cos_valid) { | 589 | if (bp->pri2cos_valid) { |
| 590 | for (i = 0; i < 8; i++, j++) { | 590 | for (i = 0; i < 8; i++, j++) { |
| 591 | long n = bnxt_rx_bytes_pri_arr[i].base_off + | 591 | long n = bnxt_rx_bytes_pri_arr[i].base_off + |
| 592 | bp->pri2cos[i]; | 592 | bp->pri2cos_idx[i]; |
| 593 | 593 | ||
| 594 | buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); | 594 | buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); |
| 595 | } | 595 | } |
| 596 | for (i = 0; i < 8; i++, j++) { | 596 | for (i = 0; i < 8; i++, j++) { |
| 597 | long n = bnxt_rx_pkts_pri_arr[i].base_off + | 597 | long n = bnxt_rx_pkts_pri_arr[i].base_off + |
| 598 | bp->pri2cos[i]; | 598 | bp->pri2cos_idx[i]; |
| 599 | 599 | ||
| 600 | buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); | 600 | buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); |
| 601 | } | 601 | } |
| 602 | for (i = 0; i < 8; i++, j++) { | 602 | for (i = 0; i < 8; i++, j++) { |
| 603 | long n = bnxt_tx_bytes_pri_arr[i].base_off + | 603 | long n = bnxt_tx_bytes_pri_arr[i].base_off + |
| 604 | bp->pri2cos[i]; | 604 | bp->pri2cos_idx[i]; |
| 605 | 605 | ||
| 606 | buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); | 606 | buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); |
| 607 | } | 607 | } |
| 608 | for (i = 0; i < 8; i++, j++) { | 608 | for (i = 0; i < 8; i++, j++) { |
| 609 | long n = bnxt_tx_pkts_pri_arr[i].base_off + | 609 | long n = bnxt_tx_pkts_pri_arr[i].base_off + |
| 610 | bp->pri2cos[i]; | 610 | bp->pri2cos_idx[i]; |
| 611 | 611 | ||
| 612 | buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); | 612 | buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); |
| 613 | } | 613 | } |
| @@ -95,12 +95,6 @@ static inline void dmadesc_set_length_status(struct bcmgenet_priv *priv, · 94 unmodified lines | |||
| 95 | bcmgenet_writel(value, d + DMA_DESC_LENGTH_STATUS); | 95 | bcmgenet_writel(value, d + DMA_DESC_LENGTH_STATUS); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static inline u32 dmadesc_get_length_status(struct bcmgenet_priv *priv, | ||
| 99 | void __iomem *d) | ||
| 100 | { | ||
| 101 | return bcmgenet_readl(d + DMA_DESC_LENGTH_STATUS); | ||
| 102 | } | ||
| 103 | |||
| 104 | static inline void dmadesc_set_addr(struct bcmgenet_priv *priv, | 98 | static inline void dmadesc_set_addr(struct bcmgenet_priv *priv, |
| 105 | void __iomem *d, | 99 | void __iomem *d, |
| 106 | dma_addr_t addr) | 100 | dma_addr_t addr) |
| @@ -509,61 +503,6 @@ static int bcmgenet_set_link_ksettings(struct net_device *dev, · 402 unmodified lines | |||
| 509 | return phy_ethtool_ksettings_set(dev->phydev, cmd); | 503 | return phy_ethtool_ksettings_set(dev->phydev, cmd); |
| 510 | } | 504 | } |
| 511 | 505 | ||
| 512 | static void bcmgenet_set_rx_csum(struct net_device *dev, | ||
| 513 | netdev_features_t wanted) | ||
| 514 | { | ||
| 515 | struct bcmgenet_priv *priv = netdev_priv(dev); | ||
| 516 | u32 rbuf_chk_ctrl; | ||
| 517 | bool rx_csum_en; | ||
| 518 | |||
| 519 | rx_csum_en = !!(wanted & NETIF_F_RXCSUM); | ||
| 520 | |||
| 521 | rbuf_chk_ctrl = bcmgenet_rbuf_readl(priv, RBUF_CHK_CTRL); | ||
| 522 | |||
| 523 | /* enable rx checksumming */ | ||
| 524 | if (rx_csum_en) | ||
| 525 | rbuf_chk_ctrl |= RBUF_RXCHK_EN | RBUF_L3_PARSE_DIS; | ||
| 526 | else | ||
| 527 | rbuf_chk_ctrl &= ~RBUF_RXCHK_EN; | ||
| 528 | priv->desc_rxchk_en = rx_csum_en; | ||
| 529 | |||
| 530 | /* If UniMAC forwards CRC, we need to skip over it to get | ||
| 531 | * a valid CHK bit to be set in the per-packet status word | ||
| 532 | */ | ||
| 533 | if (rx_csum_en && priv->crc_fwd_en) | ||
| 534 | rbuf_chk_ctrl |= RBUF_SKIP_FCS; | ||
| 535 | else | ||
| 536 | rbuf_chk_ctrl &= ~RBUF_SKIP_FCS; | ||
| 537 | |||
| 538 | bcmgenet_rbuf_writel(priv, rbuf_chk_ctrl, RBUF_CHK_CTRL); | ||
| 539 | } | ||
| 540 | |||
| 541 | static void bcmgenet_set_tx_csum(struct net_device *dev, | ||
| 542 | netdev_features_t wanted) | ||
| 543 | { | ||
| 544 | struct bcmgenet_priv *priv = netdev_priv(dev); | ||
| 545 | bool desc_64b_en; | ||
| 546 | u32 tbuf_ctrl, rbuf_ctrl; | ||
| 547 | |||
| 548 | tbuf_ctrl = bcmgenet_tbuf_ctrl_get(priv); | ||
| 549 | rbuf_ctrl = bcmgenet_rbuf_readl(priv, RBUF_CTRL); | ||
| 550 | |||
| 551 | desc_64b_en = !!(wanted & NETIF_F_HW_CSUM); | ||
| 552 | |||
| 553 | /* enable 64 bytes descriptor in both directions (RBUF and TBUF) */ | ||
| 554 | if (desc_64b_en) { | ||
| 555 | tbuf_ctrl |= RBUF_64B_EN; | ||
| 556 | rbuf_ctrl |= RBUF_64B_EN; | ||
| 557 | } else { | ||
| 558 | tbuf_ctrl &= ~RBUF_64B_EN; | ||
| 559 | rbuf_ctrl &= ~RBUF_64B_EN; | ||
| 560 | } | ||
| 561 | priv->desc_64b_en = desc_64b_en; | ||
| 562 | |||
| 563 | bcmgenet_tbuf_ctrl_set(priv, tbuf_ctrl); | ||
| 564 | bcmgenet_rbuf_writel(priv, rbuf_ctrl, RBUF_CTRL); | ||
| 565 | } | ||
| 566 | |||
| 567 | static int bcmgenet_set_features(struct net_device *dev, | 506 | static int bcmgenet_set_features(struct net_device *dev, |
| 568 | netdev_features_t features) | 507 | netdev_features_t features) |
| 569 | { | 508 | { |
| @@ -579,9 +518,6 @@ static int bcmgenet_set_features(struct net_device *dev, · 9 unmodified lines | |||
| 579 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); | 518 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 580 | priv->crc_fwd_en = !!(reg & CMD_CRC_FWD); | 519 | priv->crc_fwd_en = !!(reg & CMD_CRC_FWD); |
| 581 | 520 | ||
| 582 | bcmgenet_set_tx_csum(dev, features); | ||
| 583 | bcmgenet_set_rx_csum(dev, features); | ||
| 584 | |||
| 585 | clk_disable_unprepare(priv->clk); | 521 | clk_disable_unprepare(priv->clk); |
| 586 | 522 | ||
| 587 | return ret; | 523 | return ret; |
| @@ -1474,8 +1410,8 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev) · 886 unmodified lines | |||
| 1474 | /* Reallocate the SKB to put enough headroom in front of it and insert | 1410 | /* Reallocate the SKB to put enough headroom in front of it and insert |
| 1475 | * the transmit checksum offsets in the descriptors | 1411 | * the transmit checksum offsets in the descriptors |
| 1476 | */ | 1412 | */ |
| 1477 | static struct sk_buff *bcmgenet_put_tx_csum(struct net_device *dev, | 1413 | static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev, |
| 1478 | struct sk_buff *skb) | 1414 | struct sk_buff *skb) |
| 1479 | { | 1415 | { |
| 1480 | struct bcmgenet_priv *priv = netdev_priv(dev); | 1416 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 1481 | struct status_64 *status = NULL; | 1417 | struct status_64 *status = NULL; |
| @@ -1589,13 +1525,11 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 107 unmodified lines | |||
| 1589 | */ | 1525 | */ |
| 1590 | GENET_CB(skb)->bytes_sent = skb->len; | 1526 | GENET_CB(skb)->bytes_sent = skb->len; |
| 1591 | 1527 | ||
| 1592 | /* set the SKB transmit checksum */ | 1528 | /* add the Transmit Status Block */ |
| 1593 | if (priv->desc_64b_en) { | 1529 | skb = bcmgenet_add_tsb(dev, skb); |
| 1594 | skb = bcmgenet_put_tx_csum(dev, skb); | 1530 | if (!skb) { |
| 1595 | if (!skb) { | 1531 | ret = NETDEV_TX_OK; |
| 1596 | ret = NETDEV_TX_OK; | 1532 | goto out; |
| 1597 | goto out; | ||
| 1598 | } | ||
| 1599 | } | 1533 | } |
| 1600 | 1534 | ||
| 1601 | for (i = 0; i <= nr_frags; i++) { | 1535 | for (i = 0; i <= nr_frags; i++) { |
| @@ -1774,6 +1708,9 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, · 172 unmodified lines | |||
| 1774 | 1708 | ||
| 1775 | while ((rxpktprocessed < rxpkttoprocess) && | 1709 | while ((rxpktprocessed < rxpkttoprocess) && |
| 1776 | (rxpktprocessed < budget)) { | 1710 | (rxpktprocessed < budget)) { |
| 1711 | struct status_64 *status; | ||
| 1712 | __be16 rx_csum; | ||
| 1713 | |||
| 1777 | cb = &priv->rx_cbs[ring->read_ptr]; | 1714 | cb = &priv->rx_cbs[ring->read_ptr]; |
| 1778 | skb = bcmgenet_rx_refill(priv, cb); | 1715 | skb = bcmgenet_rx_refill(priv, cb); |
| 1779 | 1716 | ||
| @@ -1782,20 +1719,12 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, · 2 unmodified lines | |||
| 1782 | goto next; | 1719 | goto next; |
| 1783 | } | 1720 | } |
| 1784 | 1721 | ||
| 1785 | if (!priv->desc_64b_en) { | 1722 | status = (struct status_64 *)skb->data; |
| 1786 | dma_length_status = | 1723 | dma_length_status = status->length_status; |
| 1787 | dmadesc_get_length_status(priv, cb->bd_addr); | 1724 | if (dev->features & NETIF_F_RXCSUM) { |
| 1788 | } else { | ||
| 1789 | struct status_64 *status; | ||
| 1790 | __be16 rx_csum; | ||
| 1791 | |||
| 1792 | status = (struct status_64 *)skb->data; | ||
| 1793 | dma_length_status = status->length_status; | ||
| 1794 | rx_csum = (__force __be16)(status->rx_csum & 0xffff); | 1725 | rx_csum = (__force __be16)(status->rx_csum & 0xffff); |
| 1795 | if (priv->desc_rxchk_en) { | 1726 | skb->csum = (__force __wsum)ntohs(rx_csum); |
| 1796 | skb->csum = (__force __wsum)ntohs(rx_csum); | 1727 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 1797 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
| 1798 | } | ||
| 1799 | } | 1728 | } |
| 1800 | 1729 | ||
| 1801 | /* DMA flags and length are still valid no matter how | 1730 | /* DMA flags and length are still valid no matter how |
| @@ -1839,14 +1768,10 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, · 37 unmodified lines | |||
| 1839 | } /* error packet */ | 1768 | } /* error packet */ |
| 1840 | 1769 | ||
| 1841 | skb_put(skb, len); | 1770 | skb_put(skb, len); |
| 1842 | if (priv->desc_64b_en) { | ||
| 1843 | skb_pull(skb, 64); | ||
| 1844 | len -= 64; | ||
| 1845 | } | ||
| 1846 | 1771 | ||
| 1847 | /* remove hardware 2bytes added for IP alignment */ | 1772 | /* remove RSB and hardware 2bytes added for IP alignment */ |
| 1848 | skb_pull(skb, 2); | 1773 | skb_pull(skb, 66); |
| 1849 | len -= 2; | 1774 | len -= 66; |
| 1850 | 1775 | ||
| 1851 | if (priv->crc_fwd_en) { | 1776 | if (priv->crc_fwd_en) { |
| 1852 | skb_trim(skb, len - ETH_FCS_LEN); | 1777 | skb_trim(skb, len - ETH_FCS_LEN); |
| @@ -1964,6 +1889,8 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable) · 111 unmodified lines | |||
| 1964 | u32 reg; | 1889 | u32 reg; |
| 1965 | 1890 | ||
| 1966 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); | 1891 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 1892 | if (reg & CMD_SW_RESET) | ||
| 1893 | return; | ||
| 1967 | if (enable) | 1894 | if (enable) |
| 1968 | reg |= mask; | 1895 | reg |= mask; |
| 1969 | else | 1896 | else |
| @@ -1983,11 +1910,9 @@ static void reset_umac(struct bcmgenet_priv *priv) · 13 unmodified lines | |||
| 1983 | bcmgenet_rbuf_ctrl_set(priv, 0); | 1910 | bcmgenet_rbuf_ctrl_set(priv, 0); |
| 1984 | udelay(10); | 1911 | udelay(10); |
| 1985 | 1912 | ||
| 1986 | /* disable MAC while updating its registers */ | 1913 | /* issue soft reset and disable MAC while updating its registers */ |
| 1987 | bcmgenet_umac_writel(priv, 0, UMAC_CMD); | 1914 | bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); |
| 1988 | 1915 | udelay(2); | |
| 1989 | /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */ | ||
| 1990 | bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD); | ||
| 1991 | } | 1916 | } |
| 1992 | 1917 | ||
| 1993 | static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) | 1918 | static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) |
| @@ -2037,11 +1962,28 @@ static void init_umac(struct bcmgenet_priv *priv) · 43 unmodified lines | |||
| 2037 | 1962 | ||
| 2038 | bcmgenet_umac_writel(priv, ENET_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN); | 1963 | bcmgenet_umac_writel(priv, ENET_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN); |
| 2039 | 1964 | ||
| 2040 | /* init rx registers, enable ip header optimization */ | 1965 | /* init tx registers, enable TSB */ |
| 1966 | reg = bcmgenet_tbuf_ctrl_get(priv); | ||
| 1967 | reg |= TBUF_64B_EN; | ||
| 1968 | bcmgenet_tbuf_ctrl_set(priv, reg); | ||
| 1969 | |||
| 1970 | /* init rx registers, enable ip header optimization and RSB */ | ||
| 2041 | reg = bcmgenet_rbuf_readl(priv, RBUF_CTRL); | 1971 | reg = bcmgenet_rbuf_readl(priv, RBUF_CTRL); |
| 2042 | reg |= RBUF_ALIGN_2B; | 1972 | reg |= RBUF_ALIGN_2B | RBUF_64B_EN; |
| 2043 | bcmgenet_rbuf_writel(priv, reg, RBUF_CTRL); | 1973 | bcmgenet_rbuf_writel(priv, reg, RBUF_CTRL); |
| 2044 | 1974 | ||
| 1975 | /* enable rx checksumming */ | ||
| 1976 | reg = bcmgenet_rbuf_readl(priv, RBUF_CHK_CTRL); | ||
| 1977 | reg |= RBUF_RXCHK_EN | RBUF_L3_PARSE_DIS; | ||
| 1978 | /* If UniMAC forwards CRC, we need to skip over it to get | ||
| 1979 | * a valid CHK bit to be set in the per-packet status word | ||
| 1980 | */ | ||
| 1981 | if (priv->crc_fwd_en) | ||
| 1982 | reg |= RBUF_SKIP_FCS; | ||
| 1983 | else | ||
| 1984 | reg &= ~RBUF_SKIP_FCS; | ||
| 1985 | bcmgenet_rbuf_writel(priv, reg, RBUF_CHK_CTRL); | ||
| 1986 | |||
| 2045 | if (!GENET_IS_V1(priv) && !GENET_IS_V2(priv)) | 1987 | if (!GENET_IS_V1(priv) && !GENET_IS_V2(priv)) |
| 2046 | bcmgenet_rbuf_writel(priv, 1, RBUF_TBUF_SIZE_CTRL); | 1988 | bcmgenet_rbuf_writel(priv, 1, RBUF_TBUF_SIZE_CTRL); |
| 2047 | 1989 | ||
| @@ -273,6 +273,7 @@ struct bcmgenet_mib_counters { · 272 unmodified lines | |||
| 273 | #define RBUF_FLTR_LEN_SHIFT 8 | 273 | #define RBUF_FLTR_LEN_SHIFT 8 |
| 274 | 274 | ||
| 275 | #define TBUF_CTRL 0x00 | 275 | #define TBUF_CTRL 0x00 |
| 276 | #define TBUF_64B_EN (1 << 0) | ||
| 276 | #define TBUF_BP_MC 0x0C | 277 | #define TBUF_BP_MC 0x0C |
| 277 | #define TBUF_ENERGY_CTRL 0x14 | 278 | #define TBUF_ENERGY_CTRL 0x14 |
| 278 | #define TBUF_EEE_EN (1 << 0) | 279 | #define TBUF_EEE_EN (1 << 0) |
| @@ -662,8 +663,6 @@ struct bcmgenet_priv { · 383 unmodified lines | |||
| 662 | unsigned int irq0_stat; | 663 | unsigned int irq0_stat; |
| 663 | 664 | ||
| 664 | /* HW descriptors/checksum variables */ | 665 | /* HW descriptors/checksum variables */ |
| 665 | bool desc_64b_en; | ||
| 666 | bool desc_rxchk_en; | ||
| 667 | bool crc_fwd_en; | 666 | bool crc_fwd_en; |
| 668 | 667 | ||
| 669 | u32 dma_max_burst_length; | 668 | u32 dma_max_burst_length; |
| @@ -132,8 +132,12 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, · 131 unmodified lines | |||
| 132 | return -EINVAL; | 132 | return -EINVAL; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | /* disable RX */ | 135 | /* Can't suspend with WoL if MAC is still in reset */ |
| 136 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); | 136 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 137 | if (reg & CMD_SW_RESET) | ||
| 138 | reg &= ~CMD_SW_RESET; | ||
| 139 | |||
| 140 | /* disable RX */ | ||
| 137 | reg &= ~CMD_RX_EN; | 141 | reg &= ~CMD_RX_EN; |
| 138 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); | 142 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); |
| 139 | mdelay(10); | 143 | mdelay(10); |
| @@ -95,6 +95,12 @@ void bcmgenet_mii_setup(struct net_device *dev) · 94 unmodified lines | |||
| 95 | CMD_HD_EN | | 95 | CMD_HD_EN | |
| 96 | CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE); | 96 | CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE); |
| 97 | reg |= cmd_bits; | 97 | reg |= cmd_bits; |
| 98 | if (reg & CMD_SW_RESET) { | ||
| 99 | reg &= ~CMD_SW_RESET; | ||
| 100 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); | ||
| 101 | udelay(2); | ||
| 102 | reg |= CMD_TX_EN | CMD_RX_EN; | ||
| 103 | } | ||
| 98 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); | 104 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); |
| 99 | } else { | 105 | } else { |
| 100 | /* done if nothing has changed */ | 106 | /* done if nothing has changed */ |
| @@ -181,38 +187,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) · 80 unmodified lines | |||
| 181 | const char *phy_name = NULL; | 187 | const char *phy_name = NULL; |
| 182 | u32 id_mode_dis = 0; | 188 | u32 id_mode_dis = 0; |
| 183 | u32 port_ctrl; | 189 | u32 port_ctrl; |
| 184 | int bmcr = -1; | ||
| 185 | int ret; | ||
| 186 | u32 reg; | 190 | u32 reg; |
| 187 | 191 | ||
| 188 | /* MAC clocking workaround during reset of umac state machines */ | ||
| 189 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); | ||
| 190 | if (reg & CMD_SW_RESET) { | ||
| 191 | /* An MII PHY must be isolated to prevent TXC contention */ | ||
| 192 | if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { | ||
| 193 | ret = phy_read(phydev, MII_BMCR); | ||
| 194 | if (ret >= 0) { | ||
| 195 | bmcr = ret; | ||
| 196 | ret = phy_write(phydev, MII_BMCR, | ||
| 197 | bmcr | BMCR_ISOLATE); | ||
| 198 | } | ||
| 199 | if (ret) { | ||
| 200 | netdev_err(dev, "failed to isolate PHY\n"); | ||
| 201 | return ret; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | /* Switch MAC clocking to RGMII generated clock */ | ||
| 205 | bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL); | ||
| 206 | /* Ensure 5 clks with Rx disabled | ||
| 207 | * followed by 5 clks with Reset asserted | ||
| 208 | */ | ||
| 209 | udelay(4); | ||
| 210 | reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN); | ||
| 211 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); | ||
| 212 | /* Ensure 5 more clocks before Rx is enabled */ | ||
| 213 | udelay(2); | ||
| 214 | } | ||
| 215 | |||
| 216 | switch (priv->phy_interface) { | 192 | switch (priv->phy_interface) { |
| 217 | case PHY_INTERFACE_MODE_INTERNAL: | 193 | case PHY_INTERFACE_MODE_INTERNAL: |
| 218 | phy_name = "internal PHY"; | 194 | phy_name = "internal PHY"; |
| @@ -282,10 +258,6 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) · 63 unmodified lines | |||
| 282 | 258 | ||
| 283 | bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL); | 259 | bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL); |
| 284 | 260 | ||
| 285 | /* Restore the MII PHY after isolation */ | ||
| 286 | if (bmcr >= 0) | ||
| 287 | phy_write(phydev, MII_BMCR, bmcr); | ||
| 288 | |||
| 289 | priv->ext_phy = !priv->internal_phy && | 261 | priv->ext_phy = !priv->internal_phy && |
| 290 | (priv->phy_interface != PHY_INTERFACE_MODE_MOCA); | 262 | (priv->phy_interface != PHY_INTERFACE_MODE_MOCA); |
| 291 | 263 | ||
| @@ -1033,7 +1033,7 @@ void clear_all_filters(struct adapter *adapter) · 1032 unmodified lines | |||
| 1033 | adapter->tids.tid_tab[i]; | 1033 | adapter->tids.tid_tab[i]; |
| 1034 | 1034 | ||
| 1035 | if (f && (f->valid || f->pending)) | 1035 | if (f && (f->valid || f->pending)) |
| 1036 | cxgb4_del_filter(dev, i, &f->fs); | 1036 | cxgb4_del_filter(dev, f->tid, &f->fs); |
| 1037 | } | 1037 | } |
| 1038 | 1038 | ||
| 1039 | sb = t4_read_reg(adapter, LE_DB_SRVR_START_INDEX_A); | 1039 | sb = t4_read_reg(adapter, LE_DB_SRVR_START_INDEX_A); |
| @@ -1041,7 +1041,7 @@ void clear_all_filters(struct adapter *adapter) · 1 unmodified line | |||
| 1041 | f = (struct filter_entry *)adapter->tids.tid_tab[i]; | 1041 | f = (struct filter_entry *)adapter->tids.tid_tab[i]; |
| 1042 | 1042 | ||
| 1043 | if (f && (f->valid || f->pending)) | 1043 | if (f && (f->valid || f->pending)) |
| 1044 | cxgb4_del_filter(dev, i, &f->fs); | 1044 | cxgb4_del_filter(dev, f->tid, &f->fs); |
| 1045 | } | 1045 | } |
| 1046 | } | 1046 | } |
| 1047 | } | 1047 | } |
| @@ -246,6 +246,9 @@ static int cxgb4_ptp_fineadjtime(struct adapter *adapter, s64 delta) · 245 unmodified lines | |||
| 246 | FW_PTP_CMD_PORTID_V(0)); | 246 | FW_PTP_CMD_PORTID_V(0)); |
| 247 | c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16)); | 247 | c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16)); |
| 248 | c.u.ts.sc = FW_PTP_SC_ADJ_FTIME; | 248 | c.u.ts.sc = FW_PTP_SC_ADJ_FTIME; |
| 249 | c.u.ts.sign = (delta < 0) ? 1 : 0; | ||
| 250 | if (delta < 0) | ||
| 251 | delta = -delta; | ||
| 249 | c.u.ts.tm = cpu_to_be64(delta); | 252 | c.u.ts.tm = cpu_to_be64(delta); |
| 250 | 253 | ||
| 251 | err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL); | 254 | err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL); |
| @@ -1307,8 +1307,9 @@ static inline void *write_tso_wr(struct adapter *adap, struct sk_buff *skb, · 1306 unmodified lines | |||
| 1307 | int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq, | 1307 | int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq, |
| 1308 | int maxreclaim) | 1308 | int maxreclaim) |
| 1309 | { | 1309 | { |
| 1310 | unsigned int reclaimed, hw_cidx; | ||
| 1310 | struct sge_txq *q = &eq->q; | 1311 | struct sge_txq *q = &eq->q; |
| 1311 | unsigned int reclaimed; | 1312 | int hw_in_use; |
| 1312 | 1313 | ||
| 1313 | if (!q->in_use || !__netif_tx_trylock(eq->txq)) | 1314 | if (!q->in_use || !__netif_tx_trylock(eq->txq)) |
| 1314 | return 0; | 1315 | return 0; |
| @@ -1316,12 +1317,17 @@ int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq, · 1 unmodified line | |||
| 1316 | /* Reclaim pending completed TX Descriptors. */ | 1317 | /* Reclaim pending completed TX Descriptors. */ |
| 1317 | reclaimed = reclaim_completed_tx(adap, &eq->q, maxreclaim, true); | 1318 | reclaimed = reclaim_completed_tx(adap, &eq->q, maxreclaim, true); |
| 1318 | 1319 | ||
| 1320 | hw_cidx = ntohs(READ_ONCE(q->stat->cidx)); | ||
| 1321 | hw_in_use = q->pidx - hw_cidx; | ||
| 1322 | if (hw_in_use < 0) | ||
| 1323 | hw_in_use += q->size; | ||
| 1324 | |||
| 1319 | /* If the TX Queue is currently stopped and there's now more than half | 1325 | /* If the TX Queue is currently stopped and there's now more than half |
| 1320 | * the queue available, restart it. Otherwise bail out since the rest | 1326 | * the queue available, restart it. Otherwise bail out since the rest |
| 1321 | * of what we want do here is with the possibility of shipping any | 1327 | * of what we want do here is with the possibility of shipping any |
| 1322 | * currently buffered Coalesced TX Work Request. | 1328 | * currently buffered Coalesced TX Work Request. |
| 1323 | */ | 1329 | */ |
| 1324 | if (netif_tx_queue_stopped(eq->txq) && txq_avail(q) > (q->size / 2)) { | 1330 | if (netif_tx_queue_stopped(eq->txq) && hw_in_use < (q->size / 2)) { |
| 1325 | netif_tx_wake_queue(eq->txq); | 1331 | netif_tx_wake_queue(eq->txq); |
| 1326 | eq->q.restarts++; | 1332 | eq->q.restarts++; |
| 1327 | } | 1333 | } |
| @@ -1491,16 +1497,7 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 163 unmodified lines | |||
| 1491 | * has opened up. | 1497 | * has opened up. |
| 1492 | */ | 1498 | */ |
| 1493 | eth_txq_stop(q); | 1499 | eth_txq_stop(q); |
| 1494 | 1500 | wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; | |
| 1495 | /* If we're using the SGE Doorbell Queue Timer facility, we | ||
| 1496 | * don't need to ask the Firmware to send us Egress Queue CIDX | ||
| 1497 | * Updates: the Hardware will do this automatically. And | ||
| 1498 | * since we send the Ingress Queue CIDX Updates to the | ||
| 1499 | * corresponding Ethernet Response Queue, we'll get them very | ||
| 1500 | * quickly. | ||
| 1501 | */ | ||
| 1502 | if (!q->dbqt) | ||
| 1503 | wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; | ||
| 1504 | } | 1501 | } |
| 1505 | 1502 | ||
| 1506 | wr = (void *)&q->q.desc[q->q.pidx]; | 1503 | wr = (void *)&q->q.desc[q->q.pidx]; |
| @@ -1810,16 +1807,7 @@ static netdev_tx_t cxgb4_vf_eth_xmit(struct sk_buff *skb, · 303 unmodified lines | |||
| 1810 | * has opened up. | 1807 | * has opened up. |
| 1811 | */ | 1808 | */ |
| 1812 | eth_txq_stop(txq); | 1809 | eth_txq_stop(txq); |
| 1813 | 1810 | wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; | |
| 1814 | /* If we're using the SGE Doorbell Queue Timer facility, we | ||
| 1815 | * don't need to ask the Firmware to send us Egress Queue CIDX | ||
| 1816 | * Updates: the Hardware will do this automatically. And | ||
| 1817 | * since we send the Ingress Queue CIDX Updates to the | ||
| 1818 | * corresponding Ethernet Response Queue, we'll get them very | ||
| 1819 | * quickly. | ||
| 1820 | */ | ||
| 1821 | if (!txq->dbqt) | ||
| 1822 | wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; | ||
| 1823 | } | 1811 | } |
| 1824 | 1812 | ||
| 1825 | /* Start filling in our Work Request. Note that we do _not_ handle | 1813 | /* Start filling in our Work Request. Note that we do _not_ handle |
| @@ -3375,26 +3363,6 @@ static void t4_tx_completion_handler(struct sge_rspq *rspq, · 1549 unmodified lines | |||
| 3375 | } | 3363 | } |
| 3376 | 3364 | ||
| 3377 | txq = &s->ethtxq[pi->first_qset + rspq->idx]; | 3365 | txq = &s->ethtxq[pi->first_qset + rspq->idx]; |
| 3378 | |||
| 3379 | /* We've got the Hardware Consumer Index Update in the Egress Update | ||
| 3380 | * message. If we're using the SGE Doorbell Queue Timer mechanism, | ||
| 3381 | * these Egress Update messages will be our sole CIDX Updates we get | ||
| 3382 | * since we don't want to chew up PCIe bandwidth for both Ingress | ||
| 3383 | * Messages and Status Page writes. However, The code which manages | ||
| 3384 | * reclaiming successfully DMA'ed TX Work Requests uses the CIDX value | ||
| 3385 | * stored in the Status Page at the end of the TX Queue. It's easiest | ||
| 3386 | * to simply copy the CIDX Update value from the Egress Update message | ||
| 3387 | * to the Status Page. Also note that no Endian issues need to be | ||
| 3388 | * considered here since both are Big Endian and we're just copying | ||
| 3389 | * bytes consistently ... | ||
| 3390 | */ | ||
| 3391 | if (txq->dbqt) { | ||
| 3392 | struct cpl_sge_egr_update *egr; | ||
| 3393 | |||
| 3394 | egr = (struct cpl_sge_egr_update *)rsp; | ||
| 3395 | WRITE_ONCE(txq->q.stat->cidx, egr->cidx); | ||
| 3396 | } | ||
| 3397 | |||
| 3398 | t4_sge_eth_txq_egress_update(adapter, txq, -1); | 3366 | t4_sge_eth_txq_egress_update(adapter, txq, -1); |
| 3399 | } | 3367 | } |
| 3400 | 3368 | ||
| @@ -778,7 +778,7 @@ int memac_adjust_link(struct fman_mac *memac, u16 speed) · 777 unmodified lines | |||
| 778 | /* Set full duplex */ | 778 | /* Set full duplex */ |
| 779 | tmp &= ~IF_MODE_HD; | 779 | tmp &= ~IF_MODE_HD; |
| 780 | 780 | ||
| 781 | if (memac->phy_if == PHY_INTERFACE_MODE_RGMII) { | 781 | if (phy_interface_mode_is_rgmii(memac->phy_if)) { |
| 782 | /* Configure RGMII in manual mode */ | 782 | /* Configure RGMII in manual mode */ |
| 783 | tmp &= ~IF_MODE_RGMII_AUTO; | 783 | tmp &= ~IF_MODE_RGMII_AUTO; |
| 784 | tmp &= ~IF_MODE_RGMII_SP_MASK; | 784 | tmp &= ~IF_MODE_RGMII_SP_MASK; |
| @@ -389,7 +389,8 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq, · 388 unmodified lines | |||
| 389 | 389 | ||
| 390 | spin_unlock_bh(&cmdq->cmdq_lock); | 390 | spin_unlock_bh(&cmdq->cmdq_lock); |
| 391 | 391 | ||
| 392 | if (!wait_for_completion_timeout(&done, CMDQ_TIMEOUT)) { | 392 | if (!wait_for_completion_timeout(&done, |
| 393 | msecs_to_jiffies(CMDQ_TIMEOUT))) { | ||
| 393 | spin_lock_bh(&cmdq->cmdq_lock); | 394 | spin_lock_bh(&cmdq->cmdq_lock); |
| 394 | 395 | ||
| 395 | if (cmdq->errcode[curr_prod_idx] == &errcode) | 396 | if (cmdq->errcode[curr_prod_idx] == &errcode) |
| @@ -623,6 +624,8 @@ static int cmdq_cmd_ceq_handler(struct hinic_cmdq *cmdq, u16 ci, · 227 unmodified lines | |||
| 623 | if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info))) | 624 | if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info))) |
| 624 | return -EBUSY; | 625 | return -EBUSY; |
| 625 | 626 | ||
| 627 | dma_rmb(); | ||
| 628 | |||
| 626 | errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL); | 629 | errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL); |
| 627 | 630 | ||
| 628 | cmdq_sync_cmd_handler(cmdq, ci, errcode); | 631 | cmdq_sync_cmd_handler(cmdq, ci, errcode); |
| @@ -360,50 +360,6 @@ static int wait_for_db_state(struct hinic_hwdev *hwdev) · 359 unmodified lines | |||
| 360 | return -EFAULT; | 360 | return -EFAULT; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | static int wait_for_io_stopped(struct hinic_hwdev *hwdev) | ||
| 364 | { | ||
| 365 | struct hinic_cmd_io_status cmd_io_status; | ||
| 366 | struct hinic_hwif *hwif = hwdev->hwif; | ||
| 367 | struct pci_dev *pdev = hwif->pdev; | ||
| 368 | struct hinic_pfhwdev *pfhwdev; | ||
| 369 | unsigned long end; | ||
| 370 | u16 out_size; | ||
| 371 | int err; | ||
| 372 | |||
| 373 | if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { | ||
| 374 | dev_err(&pdev->dev, "Unsupported PCI Function type\n"); | ||
| 375 | return -EINVAL; | ||
| 376 | } | ||
| 377 | |||
| 378 | pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); | ||
| 379 | |||
| 380 | cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif); | ||
| 381 | |||
| 382 | end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT); | ||
| 383 | do { | ||
| 384 | err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, | ||
| 385 | HINIC_COMM_CMD_IO_STATUS_GET, | ||
| 386 | &cmd_io_status, sizeof(cmd_io_status), | ||
| 387 | &cmd_io_status, &out_size, | ||
| 388 | HINIC_MGMT_MSG_SYNC); | ||
| 389 | if ((err) || (out_size != sizeof(cmd_io_status))) { | ||
| 390 | dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n", | ||
| 391 | err); | ||
| 392 | return err; | ||
| 393 | } | ||
| 394 | |||
| 395 | if (cmd_io_status.status == IO_STOPPED) { | ||
| 396 | dev_info(&pdev->dev, "IO stopped\n"); | ||
| 397 | return 0; | ||
| 398 | } | ||
| 399 | |||
| 400 | msleep(20); | ||
| 401 | } while (time_before(jiffies, end)); | ||
| 402 | |||
| 403 | dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n"); | ||
| 404 | return -ETIMEDOUT; | ||
| 405 | } | ||
| 406 | |||
| 407 | /** | 363 | /** |
| 408 | * clear_io_resource - set the IO resources as not active in the NIC | 364 | * clear_io_resource - set the IO resources as not active in the NIC |
| 409 | * @hwdev: the NIC HW device | 365 | * @hwdev: the NIC HW device |
| @@ -423,11 +379,8 @@ static int clear_io_resources(struct hinic_hwdev *hwdev) · 13 unmodified lines | |||
| 423 | return -EINVAL; | 379 | return -EINVAL; |
| 424 | } | 380 | } |
| 425 | 381 | ||
| 426 | err = wait_for_io_stopped(hwdev); | 382 | /* sleep 100ms to wait for firmware stopping I/O */ |
| 427 | if (err) { | 383 | msleep(100); |
| 428 | dev_err(&pdev->dev, "IO has not stopped yet\n"); | ||
| 429 | return err; | ||
| 430 | } | ||
| 431 | 384 | ||
| 432 | cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif); | 385 | cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
| 433 | 386 | ||
| @@ -188,7 +188,7 @@ static u8 eq_cons_idx_checksum_set(u32 val) · 187 unmodified lines | |||
| 188 | * eq_update_ci - update the HW cons idx of event queue | 188 | * eq_update_ci - update the HW cons idx of event queue |
| 189 | * @eq: the event queue to update the cons idx for | 189 | * @eq: the event queue to update the cons idx for |
| 190 | **/ | 190 | **/ |
| 191 | static void eq_update_ci(struct hinic_eq *eq) | 191 | static void eq_update_ci(struct hinic_eq *eq, u32 arm_state) |
| 192 | { | 192 | { |
| 193 | u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq); | 193 | u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq); |
| 194 | 194 | ||
| @@ -202,7 +202,7 @@ static void eq_update_ci(struct hinic_eq *eq) · 7 unmodified lines | |||
| 202 | 202 | ||
| 203 | val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) | | 203 | val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) | |
| 204 | HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) | | 204 | HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) | |
| 205 | HINIC_EQ_CI_SET(EQ_ARMED, INT_ARMED); | 205 | HINIC_EQ_CI_SET(arm_state, INT_ARMED); |
| 206 | 206 | ||
| 207 | val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM); | 207 | val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM); |
| 208 | 208 | ||
| @@ -235,6 +235,8 @@ static void aeq_irq_handler(struct hinic_eq *eq) · 26 unmodified lines | |||
| 235 | if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped) | 235 | if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped) |
| 236 | break; | 236 | break; |
| 237 | 237 | ||
| 238 | dma_rmb(); | ||
| 239 | |||
| 238 | event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE); | 240 | event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE); |
| 239 | if (event >= HINIC_MAX_AEQ_EVENTS) { | 241 | if (event >= HINIC_MAX_AEQ_EVENTS) { |
| 240 | dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event); | 242 | dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event); |
| @@ -347,7 +349,7 @@ static void eq_irq_handler(void *data) · 106 unmodified lines | |||
| 347 | else if (eq->type == HINIC_CEQ) | 349 | else if (eq->type == HINIC_CEQ) |
| 348 | ceq_irq_handler(eq); | 350 | ceq_irq_handler(eq); |
| 349 | 351 | ||
| 350 | eq_update_ci(eq); | 352 | eq_update_ci(eq, EQ_ARMED); |
| 351 | } | 353 | } |
| 352 | 354 | ||
| 353 | /** | 355 | /** |
| @@ -702,7 +704,7 @@ static int init_eq(struct hinic_eq *eq, struct hinic_hwif *hwif, · 348 unmodified lines | |||
| 702 | } | 704 | } |
| 703 | 705 | ||
| 704 | set_eq_ctrls(eq); | 706 | set_eq_ctrls(eq); |
| 705 | eq_update_ci(eq); | 707 | eq_update_ci(eq, EQ_ARMED); |
| 706 | 708 | ||
| 707 | err = alloc_eq_pages(eq); | 709 | err = alloc_eq_pages(eq); |
| 708 | if (err) { | 710 | if (err) { |
| @@ -752,18 +754,28 @@ err_req_irq: · 43 unmodified lines | |||
| 752 | **/ | 754 | **/ |
| 753 | static void remove_eq(struct hinic_eq *eq) | 755 | static void remove_eq(struct hinic_eq *eq) |
| 754 | { | 756 | { |
| 755 | struct msix_entry *entry = &eq->msix_entry; | 757 | hinic_set_msix_state(eq->hwif, eq->msix_entry.entry, |
| 756 | 758 | HINIC_MSIX_DISABLE); | |
| 757 | free_irq(entry->vector, eq); | 759 | free_irq(eq->msix_entry.vector, eq); |
| 758 | 760 | ||
| 759 | if (eq->type == HINIC_AEQ) { | 761 | if (eq->type == HINIC_AEQ) { |
| 760 | struct hinic_eq_work *aeq_work = &eq->aeq_work; | 762 | struct hinic_eq_work *aeq_work = &eq->aeq_work; |
| 761 | 763 | ||
| 762 | cancel_work_sync(&aeq_work->work); | 764 | cancel_work_sync(&aeq_work->work); |
| 765 | /* clear aeq_len to avoid hw access host memory */ | ||
| 766 | hinic_hwif_write_reg(eq->hwif, | ||
| 767 | HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id), 0); | ||
| 763 | } else if (eq->type == HINIC_CEQ) { | 768 | } else if (eq->type == HINIC_CEQ) { |
| 764 | tasklet_kill(&eq->ceq_tasklet); | 769 | tasklet_kill(&eq->ceq_tasklet); |
| 770 | /* clear ceq_len to avoid hw access host memory */ | ||
| 771 | hinic_hwif_write_reg(eq->hwif, | ||
| 772 | HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id), 0); | ||
| 765 | } | 773 | } |
| 766 | 774 | ||
| 775 | /* update cons_idx to avoid invalid interrupt */ | ||
| 776 | eq->cons_idx = hinic_hwif_read_reg(eq->hwif, EQ_PROD_IDX_REG_ADDR(eq)); | ||
| 777 | eq_update_ci(eq, EQ_NOT_ARMED); | ||
| 778 | |||
| 767 | free_eq_pages(eq); | 779 | free_eq_pages(eq); |
| 768 | } | 780 | } |
| 769 | 781 | ||
| @@ -43,7 +43,7 @@ · 42 unmodified lines | |||
| 43 | 43 | ||
| 44 | #define MSG_NOT_RESP 0xFFFF | 44 | #define MSG_NOT_RESP 0xFFFF |
| 45 | 45 | ||
| 46 | #define MGMT_MSG_TIMEOUT 1000 | 46 | #define MGMT_MSG_TIMEOUT 5000 |
| 47 | 47 | ||
| 48 | #define mgmt_to_pfhwdev(pf_mgmt) \ | 48 | #define mgmt_to_pfhwdev(pf_mgmt) \ |
| 49 | container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt) | 49 | container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt) |
| @@ -267,7 +267,8 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt, · 217 unmodified lines | |||
| 267 | goto unlock_sync_msg; | 267 | goto unlock_sync_msg; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | if (!wait_for_completion_timeout(recv_done, MGMT_MSG_TIMEOUT)) { | 270 | if (!wait_for_completion_timeout(recv_done, |
| 271 | msecs_to_jiffies(MGMT_MSG_TIMEOUT))) { | ||
| 271 | dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id); | 272 | dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id); |
| 272 | err = -ETIMEDOUT; | 273 | err = -ETIMEDOUT; |
| 273 | goto unlock_sync_msg; | 274 | goto unlock_sync_msg; |
| @@ -350,6 +350,9 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget) · 349 unmodified lines | |||
| 350 | if (!rq_wqe) | 350 | if (!rq_wqe) |
| 351 | break; | 351 | break; |
| 352 | 352 | ||
| 353 | /* make sure we read rx_done before packet length */ | ||
| 354 | dma_rmb(); | ||
| 355 | |||
| 353 | cqe = rq->cqe[ci]; | 356 | cqe = rq->cqe[ci]; |
| 354 | status = be32_to_cpu(cqe->status); | 357 | status = be32_to_cpu(cqe->status); |
| 355 | hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge); | 358 | hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge); |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | |||
| 45 | 45 | ||
| 46 | #define HW_CONS_IDX(sq) be16_to_cpu(*(u16 *)((sq)->hw_ci_addr)) | 46 | #define HW_CONS_IDX(sq) be16_to_cpu(*(u16 *)((sq)->hw_ci_addr)) |
| 47 | 47 | ||
| 48 | #define MIN_SKB_LEN 17 | 48 | #define MIN_SKB_LEN 32 |
| 49 | 49 | ||
| 50 | #define MAX_PAYLOAD_OFFSET 221 | 50 | #define MAX_PAYLOAD_OFFSET 221 |
| 51 | #define TRANSPORT_OFFSET(l4_hdr, skb) ((u32)((l4_hdr) - (skb)->data)) | 51 | #define TRANSPORT_OFFSET(l4_hdr, skb) ((u32)((l4_hdr) - (skb)->data)) |
| @@ -622,6 +622,8 @@ static int free_tx_poll(struct napi_struct *napi, int budget) · 570 unmodified lines | |||
| 622 | do { | 622 | do { |
| 623 | hw_ci = HW_CONS_IDX(sq) & wq->mask; | 623 | hw_ci = HW_CONS_IDX(sq) & wq->mask; |
| 624 | 624 | ||
| 625 | dma_rmb(); | ||
| 626 | |||
| 625 | /* Reading a WQEBB to get real WQE size and consumer index. */ | 627 | /* Reading a WQEBB to get real WQE size and consumer index. */ |
| 626 | sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci); | 628 | sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci); |
| 627 | if ((!sq_wqe) || | 629 | if ((!sq_wqe) || |
| @@ -364,8 +364,8 @@ static int orion_mdio_probe(struct platform_device *pdev) · 363 unmodified lines | |||
| 364 | writel(MVMDIO_ERR_INT_SMI_DONE, | 364 | writel(MVMDIO_ERR_INT_SMI_DONE, |
| 365 | dev->regs + MVMDIO_ERR_INT_MASK); | 365 | dev->regs + MVMDIO_ERR_INT_MASK); |
| 366 | 366 | ||
| 367 | } else if (dev->err_interrupt < 0) { | 367 | } else if (dev->err_interrupt == -EPROBE_DEFER) { |
| 368 | ret = dev->err_interrupt; | 368 | ret = -EPROBE_DEFER; |
| 369 | goto out_mdio; | 369 | goto out_mdio; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| @@ -3109,11 +3109,10 @@ static int mvneta_poll(struct napi_struct *napi, int budget) · 3108 unmodified lines | |||
| 3109 | /* For the case where the last mvneta_poll did not process all | 3109 | /* For the case where the last mvneta_poll did not process all |
| 3110 | * RX packets | 3110 | * RX packets |
| 3111 | */ | 3111 | */ |
| 3112 | rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); | ||
| 3113 | |||
| 3114 | cause_rx_tx |= pp->neta_armada3700 ? pp->cause_rx_tx : | 3112 | cause_rx_tx |= pp->neta_armada3700 ? pp->cause_rx_tx : |
| 3115 | port->cause_rx_tx; | 3113 | port->cause_rx_tx; |
| 3116 | 3114 | ||
| 3115 | rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); | ||
| 3117 | if (rx_queue) { | 3116 | if (rx_queue) { |
| 3118 | rx_queue = rx_queue - 1; | 3117 | rx_queue = rx_queue - 1; |
| 3119 | if (pp->bm_priv) | 3118 | if (pp->bm_priv) |
| @@ -906,59 +906,59 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, · 905 unmodified lines | |||
| 906 | int len = 0; | 906 | int len = 0; |
| 907 | 907 | ||
| 908 | mlx4_err(dev, "%s", str); | 908 | mlx4_err(dev, "%s", str); |
| 909 | len += snprintf(buf + len, BUF_SIZE - len, | 909 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 910 | "port = %d prio = 0x%x qp = 0x%x ", | 910 | "port = %d prio = 0x%x qp = 0x%x ", |
| 911 | rule->port, rule->priority, rule->qpn); | 911 | rule->port, rule->priority, rule->qpn); |
| 912 | 912 | ||
| 913 | list_for_each_entry(cur, &rule->list, list) { | 913 | list_for_each_entry(cur, &rule->list, list) { |
| 914 | switch (cur->id) { | 914 | switch (cur->id) { |
| 915 | case MLX4_NET_TRANS_RULE_ID_ETH: | 915 | case MLX4_NET_TRANS_RULE_ID_ETH: |
| 916 | len += snprintf(buf + len, BUF_SIZE - len, | 916 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 917 | "dmac = %pM ", &cur->eth.dst_mac); | 917 | "dmac = %pM ", &cur->eth.dst_mac); |
| 918 | if (cur->eth.ether_type) | 918 | if (cur->eth.ether_type) |
| 919 | len += snprintf(buf + len, BUF_SIZE - len, | 919 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 920 | "ethertype = 0x%x ", | 920 | "ethertype = 0x%x ", |
| 921 | be16_to_cpu(cur->eth.ether_type)); | 921 | be16_to_cpu(cur->eth.ether_type)); |
| 922 | if (cur->eth.vlan_id) | 922 | if (cur->eth.vlan_id) |
| 923 | len += snprintf(buf + len, BUF_SIZE - len, | 923 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 924 | "vlan-id = %d ", | 924 | "vlan-id = %d ", |
| 925 | be16_to_cpu(cur->eth.vlan_id)); | 925 | be16_to_cpu(cur->eth.vlan_id)); |
| 926 | break; | 926 | break; |
| 927 | 927 | ||
| 928 | case MLX4_NET_TRANS_RULE_ID_IPV4: | 928 | case MLX4_NET_TRANS_RULE_ID_IPV4: |
| 929 | if (cur->ipv4.src_ip) | 929 | if (cur->ipv4.src_ip) |
| 930 | len += snprintf(buf + len, BUF_SIZE - len, | 930 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 931 | "src-ip = %pI4 ", | 931 | "src-ip = %pI4 ", |
| 932 | &cur->ipv4.src_ip); | 932 | &cur->ipv4.src_ip); |
| 933 | if (cur->ipv4.dst_ip) | 933 | if (cur->ipv4.dst_ip) |
| 934 | len += snprintf(buf + len, BUF_SIZE - len, | 934 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 935 | "dst-ip = %pI4 ", | 935 | "dst-ip = %pI4 ", |
| 936 | &cur->ipv4.dst_ip); | 936 | &cur->ipv4.dst_ip); |
| 937 | break; | 937 | break; |
| 938 | 938 | ||
| 939 | case MLX4_NET_TRANS_RULE_ID_TCP: | 939 | case MLX4_NET_TRANS_RULE_ID_TCP: |
| 940 | case MLX4_NET_TRANS_RULE_ID_UDP: | 940 | case MLX4_NET_TRANS_RULE_ID_UDP: |
| 941 | if (cur->tcp_udp.src_port) | 941 | if (cur->tcp_udp.src_port) |
| 942 | len += snprintf(buf + len, BUF_SIZE - len, | 942 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 943 | "src-port = %d ", | 943 | "src-port = %d ", |
| 944 | be16_to_cpu(cur->tcp_udp.src_port)); | 944 | be16_to_cpu(cur->tcp_udp.src_port)); |
| 945 | if (cur->tcp_udp.dst_port) | 945 | if (cur->tcp_udp.dst_port) |
| 946 | len += snprintf(buf + len, BUF_SIZE - len, | 946 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 947 | "dst-port = %d ", | 947 | "dst-port = %d ", |
| 948 | be16_to_cpu(cur->tcp_udp.dst_port)); | 948 | be16_to_cpu(cur->tcp_udp.dst_port)); |
| 949 | break; | 949 | break; |
| 950 | 950 | ||
| 951 | case MLX4_NET_TRANS_RULE_ID_IB: | 951 | case MLX4_NET_TRANS_RULE_ID_IB: |
| 952 | len += snprintf(buf + len, BUF_SIZE - len, | 952 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 953 | "dst-gid = %pI6\n", cur->ib.dst_gid); | 953 | "dst-gid = %pI6\n", cur->ib.dst_gid); |
| 954 | len += snprintf(buf + len, BUF_SIZE - len, | 954 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 955 | "dst-gid-mask = %pI6\n", | 955 | "dst-gid-mask = %pI6\n", |
| 956 | cur->ib.dst_gid_msk); | 956 | cur->ib.dst_gid_msk); |
| 957 | break; | 957 | break; |
| 958 | 958 | ||
| 959 | case MLX4_NET_TRANS_RULE_ID_VXLAN: | 959 | case MLX4_NET_TRANS_RULE_ID_VXLAN: |
| 960 | len += snprintf(buf + len, BUF_SIZE - len, | 960 | len += scnprintf(buf + len, BUF_SIZE - len, |
| 961 | "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); | 961 | "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); |
| 962 | break; | 962 | break; |
| 963 | case MLX4_NET_TRANS_RULE_ID_IPV6: | 963 | case MLX4_NET_TRANS_RULE_ID_IPV6: |
| 964 | break; | 964 | break; |
| @@ -967,7 +967,7 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, · 2 unmodified lines | |||
| 967 | break; | 967 | break; |
| 968 | } | 968 | } |
| 969 | } | 969 | } |
| 970 | len += snprintf(buf + len, BUF_SIZE - len, "\n"); | 970 | len += scnprintf(buf + len, BUF_SIZE - len, "\n"); |
| 971 | mlx4_err(dev, "%s", buf); | 971 | mlx4_err(dev, "%s", buf); |
| 972 | 972 | ||
| 973 | if (len >= BUF_SIZE) | 973 | if (len >= BUF_SIZE) |
| @@ -371,6 +371,7 @@ enum { · 370 unmodified lines | |||
| 371 | 371 | ||
| 372 | struct mlx5e_sq_wqe_info { | 372 | struct mlx5e_sq_wqe_info { |
| 373 | u8 opcode; | 373 | u8 opcode; |
| 374 | u8 num_wqebbs; | ||
| 374 | 375 | ||
| 375 | /* Auxiliary data for different opcodes. */ | 376 | /* Auxiliary data for different opcodes. */ |
| 376 | union { | 377 | union { |
| @@ -1077,6 +1078,7 @@ int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_state); · 700 unmodified lines | |||
| 1077 | void mlx5e_activate_rq(struct mlx5e_rq *rq); | 1078 | void mlx5e_activate_rq(struct mlx5e_rq *rq); |
| 1078 | void mlx5e_deactivate_rq(struct mlx5e_rq *rq); | 1079 | void mlx5e_deactivate_rq(struct mlx5e_rq *rq); |
| 1079 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq); | 1080 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq); |
| 1081 | void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq); | ||
| 1080 | void mlx5e_activate_icosq(struct mlx5e_icosq *icosq); | 1082 | void mlx5e_activate_icosq(struct mlx5e_icosq *icosq); |
| 1081 | void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq); | 1083 | void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq); |
| 1082 | 1084 | ||
| @@ -11,8 +11,7 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | static inline bool cqe_syndrome_needs_recover(u8 syndrome) | 12 | static inline bool cqe_syndrome_needs_recover(u8 syndrome) |
| 13 | { | 13 | { |
| 14 | return syndrome == MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR || | 14 | return syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || |
| 15 | syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || | ||
| 16 | syndrome == MLX5_CQE_SYNDROME_LOCAL_PROT_ERR || | 15 | syndrome == MLX5_CQE_SYNDROME_LOCAL_PROT_ERR || |
| 17 | syndrome == MLX5_CQE_SYNDROME_WR_FLUSH_ERR; | 16 | syndrome == MLX5_CQE_SYNDROME_WR_FLUSH_ERR; |
| 18 | } | 17 | } |
| @@ -90,7 +90,7 @@ static int mlx5e_rx_reporter_err_icosq_cqe_recover(void *ctx) · 89 unmodified lines | |||
| 90 | goto out; | 90 | goto out; |
| 91 | 91 | ||
| 92 | mlx5e_reset_icosq_cc_pc(icosq); | 92 | mlx5e_reset_icosq_cc_pc(icosq); |
| 93 | mlx5e_free_rx_descs(rq); | 93 | mlx5e_free_rx_in_progress_descs(rq); |
| 94 | clear_bit(MLX5E_SQ_STATE_RECOVERING, &icosq->state); | 94 | clear_bit(MLX5E_SQ_STATE_RECOVERING, &icosq->state); |
| 95 | mlx5e_activate_icosq(icosq); | 95 | mlx5e_activate_icosq(icosq); |
| 96 | mlx5e_activate_rq(rq); | 96 | mlx5e_activate_rq(rq); |
| @@ -181,10 +181,12 @@ mlx5e_tx_dma_unmap(struct device *pdev, struct mlx5e_sq_dma *dma) · 180 unmodified lines | |||
| 181 | 181 | ||
| 182 | static inline void mlx5e_rqwq_reset(struct mlx5e_rq *rq) | 182 | static inline void mlx5e_rqwq_reset(struct mlx5e_rq *rq) |
| 183 | { | 183 | { |
| 184 | if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) | 184 | if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { |
| 185 | mlx5_wq_ll_reset(&rq->mpwqe.wq); | 185 | mlx5_wq_ll_reset(&rq->mpwqe.wq); |
| 186 | else | 186 | rq->mpwqe.actual_wq_head = 0; |
| 187 | } else { | ||
| 187 | mlx5_wq_cyc_reset(&rq->wqe.wq); | 188 | mlx5_wq_cyc_reset(&rq->wqe.wq); |
| 189 | } | ||
| 188 | } | 190 | } |
| 189 | 191 | ||
| 190 | /* SW parser related functions */ | 192 | /* SW parser related functions */ |
| @@ -38,8 +38,8 @@ enum { · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | enum { | 39 | enum { |
| 40 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0, | 40 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0, |
| 41 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 1, | 41 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 1, |
| 42 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 2, | 42 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 2, |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | struct mlx5e_ktls_offload_context_tx { | 45 | struct mlx5e_ktls_offload_context_tx { |
| @@ -218,7 +218,7 @@ tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, · 217 unmodified lines | |||
| 218 | * this packet was already acknowledged and its record info | 218 | * this packet was already acknowledged and its record info |
| 219 | * was released. | 219 | * was released. |
| 220 | */ | 220 | */ |
| 221 | ends_before = before(tcp_seq + datalen, tls_record_start_seq(record)); | 221 | ends_before = before(tcp_seq + datalen - 1, tls_record_start_seq(record)); |
| 222 | 222 | ||
| 223 | if (unlikely(tls_record_is_start_marker(record))) { | 223 | if (unlikely(tls_record_is_start_marker(record))) { |
| 224 | ret = ends_before ? MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL; | 224 | ret = ends_before ? MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL; |
| @@ -814,6 +814,29 @@ int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq, int wait_time) · 813 unmodified lines | |||
| 814 | return -ETIMEDOUT; | 814 | return -ETIMEDOUT; |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq) | ||
| 818 | { | ||
| 819 | struct mlx5_wq_ll *wq; | ||
| 820 | u16 head; | ||
| 821 | int i; | ||
| 822 | |||
| 823 | if (rq->wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) | ||
| 824 | return; | ||
| 825 | |||
| 826 | wq = &rq->mpwqe.wq; | ||
| 827 | head = wq->head; | ||
| 828 | |||
| 829 | /* Outstanding UMR WQEs (in progress) start at wq->head */ | ||
| 830 | for (i = 0; i < rq->mpwqe.umr_in_progress; i++) { | ||
| 831 | rq->dealloc_wqe(rq, head); | ||
| 832 | head = mlx5_wq_ll_get_wqe_next_ix(wq, head); | ||
| 833 | } | ||
| 834 | |||
| 835 | rq->mpwqe.actual_wq_head = wq->head; | ||
| 836 | rq->mpwqe.umr_in_progress = 0; | ||
| 837 | rq->mpwqe.umr_completed = 0; | ||
| 838 | } | ||
| 839 | |||
| 817 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq) | 840 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq) |
| 818 | { | 841 | { |
| 819 | __be16 wqe_ix_be; | 842 | __be16 wqe_ix_be; |
| @@ -821,14 +844,8 @@ void mlx5e_free_rx_descs(struct mlx5e_rq *rq) · 1 unmodified line | |||
| 821 | 844 | ||
| 822 | if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { | 845 | if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { |
| 823 | struct mlx5_wq_ll *wq = &rq->mpwqe.wq; | 846 | struct mlx5_wq_ll *wq = &rq->mpwqe.wq; |
| 824 | u16 head = wq->head; | ||
| 825 | int i; | ||
| 826 | 847 | ||
| 827 | /* Outstanding UMR WQEs (in progress) start at wq->head */ | 848 | mlx5e_free_rx_in_progress_descs(rq); |
| 828 | for (i = 0; i < rq->mpwqe.umr_in_progress; i++) { | ||
| 829 | rq->dealloc_wqe(rq, head); | ||
| 830 | head = mlx5_wq_ll_get_wqe_next_ix(wq, head); | ||
| 831 | } | ||
| 832 | 849 | ||
| 833 | while (!mlx5_wq_ll_is_empty(wq)) { | 850 | while (!mlx5_wq_ll_is_empty(wq)) { |
| 834 | struct mlx5e_rx_wqe_ll *wqe; | 851 | struct mlx5e_rx_wqe_ll *wqe; |
| @@ -479,6 +479,7 @@ static inline void mlx5e_fill_icosq_frag_edge(struct mlx5e_icosq *sq, · 478 unmodified lines | |||
| 479 | /* fill sq frag edge with nops to avoid wqe wrapping two pages */ | 479 | /* fill sq frag edge with nops to avoid wqe wrapping two pages */ |
| 480 | for (; wi < edge_wi; wi++) { | 480 | for (; wi < edge_wi; wi++) { |
| 481 | wi->opcode = MLX5_OPCODE_NOP; | 481 | wi->opcode = MLX5_OPCODE_NOP; |
| 482 | wi->num_wqebbs = 1; | ||
| 482 | mlx5e_post_nop(wq, sq->sqn, &sq->pc); | 483 | mlx5e_post_nop(wq, sq->sqn, &sq->pc); |
| 483 | } | 484 | } |
| 484 | } | 485 | } |
| @@ -527,6 +528,7 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix) · 42 unmodified lines | |||
| 527 | umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); | 528 | umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); |
| 528 | 529 | ||
| 529 | sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_UMR; | 530 | sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_UMR; |
| 531 | sq->db.ico_wqe[pi].num_wqebbs = MLX5E_UMR_WQEBBS; | ||
| 530 | sq->db.ico_wqe[pi].umr.rq = rq; | 532 | sq->db.ico_wqe[pi].umr.rq = rq; |
| 531 | sq->pc += MLX5E_UMR_WQEBBS; | 533 | sq->pc += MLX5E_UMR_WQEBBS; |
| 532 | 534 | ||
| @@ -623,6 +625,7 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq) · 90 unmodified lines | |||
| 623 | 625 | ||
| 624 | ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc); | 626 | ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc); |
| 625 | wi = &sq->db.ico_wqe[ci]; | 627 | wi = &sq->db.ico_wqe[ci]; |
| 628 | sqcc += wi->num_wqebbs; | ||
| 626 | 629 | ||
| 627 | if (last_wqe && unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) { | 630 | if (last_wqe && unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) { |
| 628 | netdev_WARN_ONCE(cq->channel->netdev, | 631 | netdev_WARN_ONCE(cq->channel->netdev, |
| @@ -633,16 +636,12 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq) · 4 unmodified lines | |||
| 633 | break; | 636 | break; |
| 634 | } | 637 | } |
| 635 | 638 | ||
| 636 | if (likely(wi->opcode == MLX5_OPCODE_UMR)) { | 639 | if (likely(wi->opcode == MLX5_OPCODE_UMR)) |
| 637 | sqcc += MLX5E_UMR_WQEBBS; | ||
| 638 | wi->umr.rq->mpwqe.umr_completed++; | 640 | wi->umr.rq->mpwqe.umr_completed++; |
| 639 | } else if (likely(wi->opcode == MLX5_OPCODE_NOP)) { | 641 | else if (unlikely(wi->opcode != MLX5_OPCODE_NOP)) |
| 640 | sqcc++; | ||
| 641 | } else { | ||
| 642 | netdev_WARN_ONCE(cq->channel->netdev, | 642 | netdev_WARN_ONCE(cq->channel->netdev, |
| 643 | "Bad OPCODE in ICOSQ WQE info: 0x%x\n", | 643 | "Bad OPCODE in ICOSQ WQE info: 0x%x\n", |
| 644 | wi->opcode); | 644 | wi->opcode); |
| 645 | } | ||
| 646 | 645 | ||
| 647 | } while (!last_wqe); | 646 | } while (!last_wqe); |
| 648 | 647 | ||
| @@ -2714,10 +2714,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, · 2713 unmodified lines | |||
| 2714 | continue; | 2714 | continue; |
| 2715 | 2715 | ||
| 2716 | if (f->field_bsize == 32) { | 2716 | if (f->field_bsize == 32) { |
| 2717 | mask_be32 = *(__be32 *)&mask; | 2717 | mask_be32 = (__be32)mask; |
| 2718 | mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); | 2718 | mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); |
| 2719 | } else if (f->field_bsize == 16) { | 2719 | } else if (f->field_bsize == 16) { |
| 2720 | mask_be16 = *(__be16 *)&mask; | 2720 | mask_be32 = (__be32)mask; |
| 2721 | mask_be16 = *(__be16 *)&mask_be32; | ||
| 2721 | mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); | 2722 | mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); |
| 2722 | } | 2723 | } |
| 2723 | 2724 | ||
| @@ -79,6 +79,7 @@ void mlx5e_trigger_irq(struct mlx5e_icosq *sq) · 78 unmodified lines | |||
| 79 | u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); | 79 | u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); |
| 80 | 80 | ||
| 81 | sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP; | 81 | sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP; |
| 82 | sq->db.ico_wqe[pi].num_wqebbs = 1; | ||
| 82 | nopwqe = mlx5e_post_nop(wq, sq->sqn, &sq->pc); | 83 | nopwqe = mlx5e_post_nop(wq, sq->sqn, &sq->pc); |
| 83 | mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nopwqe->ctrl); | 84 | mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nopwqe->ctrl); |
| 84 | } | 85 | } |
| @@ -615,8 +615,10 @@ void mlx5_lag_remove(struct mlx5_core_dev *dev) · 614 unmodified lines | |||
| 615 | break; | 615 | break; |
| 616 | 616 | ||
| 617 | if (i == MLX5_MAX_PORTS) { | 617 | if (i == MLX5_MAX_PORTS) { |
| 618 | if (ldev->nb.notifier_call) | 618 | if (ldev->nb.notifier_call) { |
| 619 | unregister_netdevice_notifier_net(&init_net, &ldev->nb); | 619 | unregister_netdevice_notifier_net(&init_net, &ldev->nb); |
| 620 | ldev->nb.notifier_call = NULL; | ||
| 621 | } | ||
| 620 | mlx5_lag_mp_cleanup(ldev); | 622 | mlx5_lag_mp_cleanup(ldev); |
| 621 | cancel_delayed_work_sync(&ldev->bond_work); | 623 | cancel_delayed_work_sync(&ldev->bond_work); |
| 622 | mlx5_lag_dev_free(ldev); | 624 | mlx5_lag_dev_free(ldev); |
| @@ -933,7 +933,6 @@ static int dr_actions_l2_rewrite(struct mlx5dr_domain *dmn, · 932 unmodified lines | |||
| 933 | 933 | ||
| 934 | action->rewrite.data = (void *)ops; | 934 | action->rewrite.data = (void *)ops; |
| 935 | action->rewrite.num_of_actions = i; | 935 | action->rewrite.num_of_actions = i; |
| 936 | action->rewrite.chunk->byte_size = i * sizeof(*ops); | ||
| 937 | 936 | ||
| 938 | ret = mlx5dr_send_postsend_action(dmn, action); | 937 | ret = mlx5dr_send_postsend_action(dmn, action); |
| 939 | if (ret) { | 938 | if (ret) { |
| @@ -558,7 +558,8 @@ int mlx5dr_send_postsend_action(struct mlx5dr_domain *dmn, · 557 unmodified lines | |||
| 558 | int ret; | 558 | int ret; |
| 559 | 559 | ||
| 560 | send_info.write.addr = (uintptr_t)action->rewrite.data; | 560 | send_info.write.addr = (uintptr_t)action->rewrite.data; |
| 561 | send_info.write.length = action->rewrite.chunk->byte_size; | 561 | send_info.write.length = action->rewrite.num_of_actions * |
| 562 | DR_MODIFY_ACTION_SIZE; | ||
| 562 | send_info.write.lkey = 0; | 563 | send_info.write.lkey = 0; |
| 563 | send_info.remote_addr = action->rewrite.chunk->mr_addr; | 564 | send_info.remote_addr = action->rewrite.chunk->mr_addr; |
| 564 | send_info.rkey = action->rewrite.chunk->rkey; | 565 | send_info.rkey = action->rewrite.chunk->rkey; |
| @@ -1071,6 +1071,9 @@ int mlx5_core_modify_hca_vport_context(struct mlx5_core_dev *dev, · 1070 unmodified lines | |||
| 1071 | MLX5_SET64(hca_vport_context, ctx, port_guid, req->port_guid); | 1071 | MLX5_SET64(hca_vport_context, ctx, port_guid, req->port_guid); |
| 1072 | if (req->field_select & MLX5_HCA_VPORT_SEL_NODE_GUID) | 1072 | if (req->field_select & MLX5_HCA_VPORT_SEL_NODE_GUID) |
| 1073 | MLX5_SET64(hca_vport_context, ctx, node_guid, req->node_guid); | 1073 | MLX5_SET64(hca_vport_context, ctx, node_guid, req->node_guid); |
| 1074 | MLX5_SET(hca_vport_context, ctx, cap_mask1, req->cap_mask1); | ||
| 1075 | MLX5_SET(hca_vport_context, ctx, cap_mask1_field_select, | ||
| 1076 | req->cap_mask1_perm); | ||
| 1074 | err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out)); | 1077 | err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out)); |
| 1075 | ex: | 1078 | ex: |
| 1076 | kfree(in); | 1079 | kfree(in); |
| @@ -1331,36 +1331,64 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci, · 1330 unmodified lines | |||
| 1331 | mbox->mapaddr); | 1331 | mbox->mapaddr); |
| 1332 | } | 1332 | } |
| 1333 | 1333 | ||
| 1334 | static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, | 1334 | static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci, |
| 1335 | const struct pci_device_id *id) | 1335 | const struct pci_device_id *id, |
| 1336 | u32 *p_sys_status) | ||
| 1336 | { | 1337 | { |
| 1337 | unsigned long end; | 1338 | unsigned long end; |
| 1338 | char mrsr_pl[MLXSW_REG_MRSR_LEN]; | 1339 | u32 val; |
| 1339 | int err; | ||
| 1340 | 1340 | ||
| 1341 | mlxsw_reg_mrsr_pack(mrsr_pl); | ||
| 1342 | err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl); | ||
| 1343 | if (err) | ||
| 1344 | return err; | ||
| 1345 | if (id->device == PCI_DEVICE_ID_MELLANOX_SWITCHX2) { | 1341 | if (id->device == PCI_DEVICE_ID_MELLANOX_SWITCHX2) { |
| 1346 | msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); | 1342 | msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); |
| 1347 | return 0; | 1343 | return 0; |
| 1348 | } | 1344 | } |
| 1349 | 1345 | ||
| 1350 | /* We must wait for the HW to become responsive once again. */ | 1346 | /* We must wait for the HW to become responsive. */ |
| 1351 | msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS); | 1347 | msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS); |
| 1352 | 1348 | ||
| 1353 | end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); | 1349 | end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); |
| 1354 | do { | 1350 | do { |
| 1355 | u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY); | 1351 | val = mlxsw_pci_read32(mlxsw_pci, FW_READY); |
| 1356 | |||
| 1357 | if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC) | 1352 | if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC) |
| 1358 | return 0; | 1353 | return 0; |
| 1359 | cond_resched(); | 1354 | cond_resched(); |
| 1360 | } while (time_before(jiffies, end)); | 1355 | } while (time_before(jiffies, end)); |
| 1356 | |||
| 1357 | *p_sys_status = val & MLXSW_PCI_FW_READY_MASK; | ||
| 1358 | |||
| 1361 | return -EBUSY; | 1359 | return -EBUSY; |
| 1362 | } | 1360 | } |
| 1363 | 1361 | ||
| 1362 | static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, | ||
| 1363 | const struct pci_device_id *id) | ||
| 1364 | { | ||
| 1365 | struct pci_dev *pdev = mlxsw_pci->pdev; | ||
| 1366 | char mrsr_pl[MLXSW_REG_MRSR_LEN]; | ||
| 1367 | u32 sys_status; | ||
| 1368 | int err; | ||
| 1369 | |||
| 1370 | err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status); | ||
| 1371 | if (err) { | ||
| 1372 | dev_err(&pdev->dev, "Failed to reach system ready status before reset. Status is 0x%x\n", | ||
| 1373 | sys_status); | ||
| 1374 | return err; | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | mlxsw_reg_mrsr_pack(mrsr_pl); | ||
| 1378 | err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl); | ||
| 1379 | if (err) | ||
| 1380 | return err; | ||
| 1381 | |||
| 1382 | err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status); | ||
| 1383 | if (err) { | ||
| 1384 | dev_err(&pdev->dev, "Failed to reach system ready status after reset. Status is 0x%x\n", | ||
| 1385 | sys_status); | ||
| 1386 | return err; | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | return 0; | ||
| 1390 | } | ||
| 1391 | |||
| 1364 | static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci) | 1392 | static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci) |
| 1365 | { | 1393 | { |
| 1366 | int err; | 1394 | int err; |
| @@ -3572,7 +3572,7 @@ MLXSW_ITEM32(reg, qeec, mase, 0x10, 31, 1); · 3571 unmodified lines | |||
| 3572 | * When in bytes mode, value is specified in units of 1000bps. | 3572 | * When in bytes mode, value is specified in units of 1000bps. |
| 3573 | * Access: RW | 3573 | * Access: RW |
| 3574 | */ | 3574 | */ |
| 3575 | MLXSW_ITEM32(reg, qeec, max_shaper_rate, 0x10, 0, 28); | 3575 | MLXSW_ITEM32(reg, qeec, max_shaper_rate, 0x10, 0, 31); |
| 3576 | 3576 | ||
| 3577 | /* reg_qeec_de | 3577 | /* reg_qeec_de |
| 3578 | * DWRR configuration enable. Enables configuration of the dwrr and | 3578 | * DWRR configuration enable. Enables configuration of the dwrr and |
| @@ -2045,7 +2045,7 @@ vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask); · 2044 unmodified lines | |||
| 2045 | if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \ | 2045 | if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \ |
| 2046 | (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\ | 2046 | (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\ |
| 2047 | if ((mask & VXGE_DEBUG_MASK) == mask) \ | 2047 | if ((mask & VXGE_DEBUG_MASK) == mask) \ |
| 2048 | printk(fmt "\n", __VA_ARGS__); \ | 2048 | printk(fmt "\n", ##__VA_ARGS__); \ |
| 2049 | } while (0) | 2049 | } while (0) |
| 2050 | #else | 2050 | #else |
| 2051 | #define vxge_debug_ll(level, mask, fmt, ...) | 2051 | #define vxge_debug_ll(level, mask, fmt, ...) |
| @@ -452,49 +452,49 @@ int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override); · 451 unmodified lines | |||
| 452 | 452 | ||
| 453 | #if (VXGE_DEBUG_LL_CONFIG & VXGE_DEBUG_MASK) | 453 | #if (VXGE_DEBUG_LL_CONFIG & VXGE_DEBUG_MASK) |
| 454 | #define vxge_debug_ll_config(level, fmt, ...) \ | 454 | #define vxge_debug_ll_config(level, fmt, ...) \ |
| 455 | vxge_debug_ll(level, VXGE_DEBUG_LL_CONFIG, fmt, __VA_ARGS__) | 455 | vxge_debug_ll(level, VXGE_DEBUG_LL_CONFIG, fmt, ##__VA_ARGS__) |
| 456 | #else | 456 | #else |
| 457 | #define vxge_debug_ll_config(level, fmt, ...) | 457 | #define vxge_debug_ll_config(level, fmt, ...) |
| 458 | #endif | 458 | #endif |
| 459 | 459 | ||
| 460 | #if (VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) | 460 | #if (VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) |
| 461 | #define vxge_debug_init(level, fmt, ...) \ | 461 | #define vxge_debug_init(level, fmt, ...) \ |
| 462 | vxge_debug_ll(level, VXGE_DEBUG_INIT, fmt, __VA_ARGS__) | 462 | vxge_debug_ll(level, VXGE_DEBUG_INIT, fmt, ##__VA_ARGS__) |
| 463 | #else | 463 | #else |
| 464 | #define vxge_debug_init(level, fmt, ...) | 464 | #define vxge_debug_init(level, fmt, ...) |
| 465 | #endif | 465 | #endif |
| 466 | 466 | ||
| 467 | #if (VXGE_DEBUG_TX & VXGE_DEBUG_MASK) | 467 | #if (VXGE_DEBUG_TX & VXGE_DEBUG_MASK) |
| 468 | #define vxge_debug_tx(level, fmt, ...) \ | 468 | #define vxge_debug_tx(level, fmt, ...) \ |
| 469 | vxge_debug_ll(level, VXGE_DEBUG_TX, fmt, __VA_ARGS__) | 469 | vxge_debug_ll(level, VXGE_DEBUG_TX, fmt, ##__VA_ARGS__) |
| 470 | #else | 470 | #else |
| 471 | #define vxge_debug_tx(level, fmt, ...) | 471 | #define vxge_debug_tx(level, fmt, ...) |
| 472 | #endif | 472 | #endif |
| 473 | 473 | ||
| 474 | #if (VXGE_DEBUG_RX & VXGE_DEBUG_MASK) | 474 | #if (VXGE_DEBUG_RX & VXGE_DEBUG_MASK) |
| 475 | #define vxge_debug_rx(level, fmt, ...) \ | 475 | #define vxge_debug_rx(level, fmt, ...) \ |
| 476 | vxge_debug_ll(level, VXGE_DEBUG_RX, fmt, __VA_ARGS__) | 476 | vxge_debug_ll(level, VXGE_DEBUG_RX, fmt, ##__VA_ARGS__) |
| 477 | #else | 477 | #else |
| 478 | #define vxge_debug_rx(level, fmt, ...) | 478 | #define vxge_debug_rx(level, fmt, ...) |
| 479 | #endif | 479 | #endif |
| 480 | 480 | ||
| 481 | #if (VXGE_DEBUG_MEM & VXGE_DEBUG_MASK) | 481 | #if (VXGE_DEBUG_MEM & VXGE_DEBUG_MASK) |
| 482 | #define vxge_debug_mem(level, fmt, ...) \ | 482 | #define vxge_debug_mem(level, fmt, ...) \ |
| 483 | vxge_debug_ll(level, VXGE_DEBUG_MEM, fmt, __VA_ARGS__) | 483 | vxge_debug_ll(level, VXGE_DEBUG_MEM, fmt, ##__VA_ARGS__) |
| 484 | #else | 484 | #else |
| 485 | #define vxge_debug_mem(level, fmt, ...) | 485 | #define vxge_debug_mem(level, fmt, ...) |
| 486 | #endif | 486 | #endif |
| 487 | 487 | ||
| 488 | #if (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK) | 488 | #if (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK) |
| 489 | #define vxge_debug_entryexit(level, fmt, ...) \ | 489 | #define vxge_debug_entryexit(level, fmt, ...) \ |
| 490 | vxge_debug_ll(level, VXGE_DEBUG_ENTRYEXIT, fmt, __VA_ARGS__) | 490 | vxge_debug_ll(level, VXGE_DEBUG_ENTRYEXIT, fmt, ##__VA_ARGS__) |
| 491 | #else | 491 | #else |
| 492 | #define vxge_debug_entryexit(level, fmt, ...) | 492 | #define vxge_debug_entryexit(level, fmt, ...) |
| 493 | #endif | 493 | #endif |
| 494 | 494 | ||
| 495 | #if (VXGE_DEBUG_INTR & VXGE_DEBUG_MASK) | 495 | #if (VXGE_DEBUG_INTR & VXGE_DEBUG_MASK) |
| 496 | #define vxge_debug_intr(level, fmt, ...) \ | 496 | #define vxge_debug_intr(level, fmt, ...) \ |
| 497 | vxge_debug_ll(level, VXGE_DEBUG_INTR, fmt, __VA_ARGS__) | 497 | vxge_debug_ll(level, VXGE_DEBUG_INTR, fmt, ##__VA_ARGS__) |
| 498 | #else | 498 | #else |
| 499 | #define vxge_debug_intr(level, fmt, ...) | 499 | #define vxge_debug_intr(level, fmt, ...) |
| 500 | #endif | 500 | #endif |
| @@ -616,7 +616,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) · 615 unmodified lines | |||
| 616 | if (bar->iomem) { | 616 | if (bar->iomem) { |
| 617 | int pf; | 617 | int pf; |
| 618 | 618 | ||
| 619 | msg += snprintf(msg, end - msg, "0.0: General/MSI-X SRAM, "); | 619 | msg += scnprintf(msg, end - msg, "0.0: General/MSI-X SRAM, "); |
| 620 | atomic_inc(&bar->refcnt); | 620 | atomic_inc(&bar->refcnt); |
| 621 | bars_free--; | 621 | bars_free--; |
| 622 | 622 | ||
| @@ -661,7 +661,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) · 38 unmodified lines | |||
| 661 | 661 | ||
| 662 | /* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */ | 662 | /* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */ |
| 663 | bar = &nfp->bar[1]; | 663 | bar = &nfp->bar[1]; |
| 664 | msg += snprintf(msg, end - msg, "0.1: PCIe XPB/MSI-X PBA, "); | 664 | msg += scnprintf(msg, end - msg, "0.1: PCIe XPB/MSI-X PBA, "); |
| 665 | atomic_inc(&bar->refcnt); | 665 | atomic_inc(&bar->refcnt); |
| 666 | bars_free--; | 666 | bars_free--; |
| 667 | 667 | ||
| @@ -680,8 +680,8 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) · 12 unmodified lines | |||
| 680 | bar->iomem = ioremap(nfp_bar_resource_start(bar), | 680 | bar->iomem = ioremap(nfp_bar_resource_start(bar), |
| 681 | nfp_bar_resource_len(bar)); | 681 | nfp_bar_resource_len(bar)); |
| 682 | if (bar->iomem) { | 682 | if (bar->iomem) { |
| 683 | msg += snprintf(msg, end - msg, | 683 | msg += scnprintf(msg, end - msg, |
| 684 | "0.%d: Explicit%d, ", 4 + i, i); | 684 | "0.%d: Explicit%d, ", 4 + i, i); |
| 685 | atomic_inc(&bar->refcnt); | 685 | atomic_inc(&bar->refcnt); |
| 686 | bars_free--; | 686 | bars_free--; |
| 687 | 687 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB OR BSD-2-Clause */ | 1 | /* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */ |
| 2 | /* Copyright (c) 2017-2019 Pensando Systems, Inc. All rights reserved. */ | 2 | /* Copyright (c) 2017-2019 Pensando Systems, Inc. All rights reserved. */ |
| 3 | 3 | ||
| 4 | #ifndef _IONIC_IF_H_ | 4 | #ifndef _IONIC_IF_H_ |
| @@ -953,18 +953,18 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode) · 952 unmodified lines | |||
| 953 | int i; | 953 | int i; |
| 954 | #define REMAIN(__x) (sizeof(buf) - (__x)) | 954 | #define REMAIN(__x) (sizeof(buf) - (__x)) |
| 955 | 955 | ||
| 956 | i = snprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", | 956 | i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", |
| 957 | lif->rx_mode, rx_mode); | 957 | lif->rx_mode, rx_mode); |
| 958 | if (rx_mode & IONIC_RX_MODE_F_UNICAST) | 958 | if (rx_mode & IONIC_RX_MODE_F_UNICAST) |
| 959 | i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST"); | 959 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST"); |
| 960 | if (rx_mode & IONIC_RX_MODE_F_MULTICAST) | 960 | if (rx_mode & IONIC_RX_MODE_F_MULTICAST) |
| 961 | i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST"); | 961 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST"); |
| 962 | if (rx_mode & IONIC_RX_MODE_F_BROADCAST) | 962 | if (rx_mode & IONIC_RX_MODE_F_BROADCAST) |
| 963 | i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST"); | 963 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST"); |
| 964 | if (rx_mode & IONIC_RX_MODE_F_PROMISC) | 964 | if (rx_mode & IONIC_RX_MODE_F_PROMISC) |
| 965 | i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC"); | 965 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC"); |
| 966 | if (rx_mode & IONIC_RX_MODE_F_ALLMULTI) | 966 | if (rx_mode & IONIC_RX_MODE_F_ALLMULTI) |
| 967 | i += snprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI"); | 967 | i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI"); |
| 968 | netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf); | 968 | netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf); |
| 969 | 969 | ||
| 970 | err = ionic_adminq_post_wait(lif, &ctx); | 970 | err = ionic_adminq_post_wait(lif, &ctx); |
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB OR BSD-2-Clause */ | 1 | /* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */ |
| 2 | /* Copyright (c) 2018-2019 Pensando Systems, Inc. All rights reserved. */ | 2 | /* Copyright (c) 2018-2019 Pensando Systems, Inc. All rights reserved. */ |
| 3 | 3 | ||
| 4 | #ifndef IONIC_REGS_H | 4 | #ifndef IONIC_REGS_H |
| @@ -5091,7 +5091,7 @@ static int rtl_alloc_irq(struct rtl8169_private *tp) · 5090 unmodified lines | |||
| 5091 | RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); | 5091 | RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); |
| 5092 | rtl_lock_config_regs(tp); | 5092 | rtl_lock_config_regs(tp); |
| 5093 | /* fall through */ | 5093 | /* fall through */ |
| 5094 | case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_24: | 5094 | case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_17: |
| 5095 | flags = PCI_IRQ_LEGACY; | 5095 | flags = PCI_IRQ_LEGACY; |
| 5096 | break; | 5096 | break; |
| 5097 | default: | 5097 | default: |
| @@ -212,12 +212,14 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd, · 211 unmodified lines | |||
| 212 | * progress on a NIC at any one time. So no need for locking. | 212 | * progress on a NIC at any one time. So no need for locking. |
| 213 | */ | 213 | */ |
| 214 | for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++) | 214 | for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++) |
| 215 | bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | 215 | bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, |
| 216 | " %08x", le32_to_cpu(hdr[i].u32[0])); | 216 | " %08x", |
| 217 | le32_to_cpu(hdr[i].u32[0])); | ||
| 217 | 218 | ||
| 218 | for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++) | 219 | for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++) |
| 219 | bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | 220 | bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, |
| 220 | " %08x", le32_to_cpu(inbuf[i].u32[0])); | 221 | " %08x", |
| 222 | le32_to_cpu(inbuf[i].u32[0])); | ||
| 221 | 223 | ||
| 222 | netif_info(efx, hw, efx->net_dev, "MCDI RPC REQ:%s\n", buf); | 224 | netif_info(efx, hw, efx->net_dev, "MCDI RPC REQ:%s\n", buf); |
| 223 | } | 225 | } |
| @@ -302,15 +304,15 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx) · 78 unmodified lines | |||
| 302 | */ | 304 | */ |
| 303 | for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) { | 305 | for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) { |
| 304 | efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4); | 306 | efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4); |
| 305 | bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | 307 | bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, |
| 306 | " %08x", le32_to_cpu(hdr.u32[0])); | 308 | " %08x", le32_to_cpu(hdr.u32[0])); |
| 307 | } | 309 | } |
| 308 | 310 | ||
| 309 | for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) { | 311 | for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) { |
| 310 | efx->type->mcdi_read_response(efx, &hdr, | 312 | efx->type->mcdi_read_response(efx, &hdr, |
| 311 | mcdi->resp_hdr_len + (i * 4), 4); | 313 | mcdi->resp_hdr_len + (i * 4), 4); |
| 312 | bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | 314 | bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, |
| 313 | " %08x", le32_to_cpu(hdr.u32[0])); | 315 | " %08x", le32_to_cpu(hdr.u32[0])); |
| 314 | } | 316 | } |
| 315 | 317 | ||
| 316 | netif_info(efx, hw, efx->net_dev, "MCDI RPC RESP:%s\n", buf); | 318 | netif_info(efx, hw, efx->net_dev, "MCDI RPC RESP:%s\n", buf); |
| @@ -1417,9 +1419,11 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) · 1100 unmodified lines | |||
| 1417 | } | 1419 | } |
| 1418 | 1420 | ||
| 1419 | ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); | 1421 | ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); |
| 1420 | offset = snprintf(buf, len, "%u.%u.%u.%u", | 1422 | offset = scnprintf(buf, len, "%u.%u.%u.%u", |
| 1421 | le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]), | 1423 | le16_to_cpu(ver_words[0]), |
| 1422 | le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3])); | 1424 | le16_to_cpu(ver_words[1]), |
| 1425 | le16_to_cpu(ver_words[2]), | ||
| 1426 | le16_to_cpu(ver_words[3])); | ||
| 1423 | 1427 | ||
| 1424 | /* EF10 may have multiple datapath firmware variants within a | 1428 | /* EF10 may have multiple datapath firmware variants within a |
| 1425 | * single version. Report which variants are running. | 1429 | * single version. Report which variants are running. |
| @@ -1427,9 +1431,9 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) · 1 unmodified line | |||
| 1427 | if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) { | 1431 | if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) { |
| 1428 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | 1432 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 1429 | 1433 | ||
| 1430 | offset += snprintf(buf + offset, len - offset, " rx%x tx%x", | 1434 | offset += scnprintf(buf + offset, len - offset, " rx%x tx%x", |
| 1431 | nic_data->rx_dpcpu_fw_id, | 1435 | nic_data->rx_dpcpu_fw_id, |
| 1432 | nic_data->tx_dpcpu_fw_id); | 1436 | nic_data->tx_dpcpu_fw_id); |
| 1433 | 1437 | ||
| 1434 | /* It's theoretically possible for the string to exceed 31 | 1438 | /* It's theoretically possible for the string to exceed 31 |
| 1435 | * characters, though in practice the first three version | 1439 | * characters, though in practice the first three version |
| @@ -1411,7 +1411,7 @@ static int rk_gmac_probe(struct platform_device *pdev) · 1410 unmodified lines | |||
| 1411 | 1411 | ||
| 1412 | ret = rk_gmac_clk_init(plat_dat); | 1412 | ret = rk_gmac_clk_init(plat_dat); |
| 1413 | if (ret) | 1413 | if (ret) |
| 1414 | return ret; | 1414 | goto err_remove_config_dt; |
| 1415 | 1415 | ||
| 1416 | ret = rk_gmac_powerup(plat_dat->bsp_priv); | 1416 | ret = rk_gmac_powerup(plat_dat->bsp_priv); |
| 1417 | if (ret) | 1417 | if (ret) |
| @@ -661,16 +661,22 @@ int stmmac_get_platform_resources(struct platform_device *pdev, · 660 unmodified lines | |||
| 661 | * In case the wake up interrupt is not passed from the platform | 661 | * In case the wake up interrupt is not passed from the platform |
| 662 | * so the driver will continue to use the mac irq (ndev->irq) | 662 | * so the driver will continue to use the mac irq (ndev->irq) |
| 663 | */ | 663 | */ |
| 664 | stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); | 664 | stmmac_res->wol_irq = |
| 665 | platform_get_irq_byname_optional(pdev, "eth_wake_irq"); | ||
| 665 | if (stmmac_res->wol_irq < 0) { | 666 | if (stmmac_res->wol_irq < 0) { |
| 666 | if (stmmac_res->wol_irq == -EPROBE_DEFER) | 667 | if (stmmac_res->wol_irq == -EPROBE_DEFER) |
| 667 | return -EPROBE_DEFER; | 668 | return -EPROBE_DEFER; |
| 669 | dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n"); | ||
| 668 | stmmac_res->wol_irq = stmmac_res->irq; | 670 | stmmac_res->wol_irq = stmmac_res->irq; |
| 669 | } | 671 | } |
| 670 | 672 | ||
| 671 | stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); | 673 | stmmac_res->lpi_irq = |
| 672 | if (stmmac_res->lpi_irq == -EPROBE_DEFER) | 674 | platform_get_irq_byname_optional(pdev, "eth_lpi"); |
| 673 | return -EPROBE_DEFER; | 675 | if (stmmac_res->lpi_irq < 0) { |
| 676 | if (stmmac_res->lpi_irq == -EPROBE_DEFER) | ||
| 677 | return -EPROBE_DEFER; | ||
| 678 | dev_info(&pdev->dev, "IRQ eth_lpi not found\n"); | ||
| 679 | } | ||
| 674 | 680 | ||
| 675 | stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0); | 681 | stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0); |
| 676 | 682 | ||
| @@ -1845,8 +1845,6 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head) · 1844 unmodified lines | |||
| 1845 | if (!net_eq(dev_net(geneve->dev), net)) | 1845 | if (!net_eq(dev_net(geneve->dev), net)) |
| 1846 | unregister_netdevice_queue(geneve->dev, head); | 1846 | unregister_netdevice_queue(geneve->dev, head); |
| 1847 | } | 1847 | } |
| 1848 | |||
| 1849 | WARN_ON_ONCE(!list_empty(&gn->sock_list)); | ||
| 1850 | } | 1848 | } |
| 1851 | 1849 | ||
| 1852 | static void __net_exit geneve_exit_batch_net(struct list_head *net_list) | 1850 | static void __net_exit geneve_exit_batch_net(struct list_head *net_list) |
| @@ -1861,6 +1859,12 @@ static void __net_exit geneve_exit_batch_net(struct list_head *net_list) · 8 unmodified lines | |||
| 1861 | /* unregister the devices gathered above */ | 1859 | /* unregister the devices gathered above */ |
| 1862 | unregister_netdevice_many(&list); | 1860 | unregister_netdevice_many(&list); |
| 1863 | rtnl_unlock(); | 1861 | rtnl_unlock(); |
| 1862 | |||
| 1863 | list_for_each_entry(net, net_list, exit_list) { | ||
| 1864 | const struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
| 1865 | |||
| 1866 | WARN_ON_ONCE(!list_empty(&gn->sock_list)); | ||
| 1867 | } | ||
| 1864 | } | 1868 | } |
| 1865 | 1869 | ||
| 1866 | static struct pernet_operations geneve_net_ops = { | 1870 | static struct pernet_operations geneve_net_ops = { |
| @@ -75,7 +75,7 @@ static void ifb_ri_tasklet(unsigned long _txp) · 74 unmodified lines | |||
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | while ((skb = __skb_dequeue(&txp->tq)) != NULL) { | 77 | while ((skb = __skb_dequeue(&txp->tq)) != NULL) { |
| 78 | skb->tc_redirected = 0; | 78 | skb->redirected = 0; |
| 79 | skb->tc_skip_classify = 1; | 79 | skb->tc_skip_classify = 1; |
| 80 | 80 | ||
| 81 | u64_stats_update_begin(&txp->tsync); | 81 | u64_stats_update_begin(&txp->tsync); |
| @@ -96,7 +96,7 @@ static void ifb_ri_tasklet(unsigned long _txp) · 14 unmodified lines | |||
| 96 | rcu_read_unlock(); | 96 | rcu_read_unlock(); |
| 97 | skb->skb_iif = txp->dev->ifindex; | 97 | skb->skb_iif = txp->dev->ifindex; |
| 98 | 98 | ||
| 99 | if (!skb->tc_from_ingress) { | 99 | if (!skb->from_ingress) { |
| 100 | dev_queue_xmit(skb); | 100 | dev_queue_xmit(skb); |
| 101 | } else { | 101 | } else { |
| 102 | skb_pull_rcsum(skb, skb->mac_len); | 102 | skb_pull_rcsum(skb, skb->mac_len); |
| @@ -243,7 +243,7 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) · 140 unmodified lines | |||
| 243 | txp->rx_bytes += skb->len; | 243 | txp->rx_bytes += skb->len; |
| 244 | u64_stats_update_end(&txp->rsync); | 244 | u64_stats_update_end(&txp->rsync); |
| 245 | 245 | ||
| 246 | if (!skb->tc_redirected || !skb->skb_iif) { | 246 | if (!skb->redirected || !skb->skb_iif) { |
| 247 | dev_kfree_skb(skb); | 247 | dev_kfree_skb(skb); |
| 248 | dev->stats.rx_dropped++; | 248 | dev->stats.rx_dropped++; |
| 249 | return NETDEV_TX_OK; | 249 | return NETDEV_TX_OK; |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <net/macsec.h> | 20 | #include <net/macsec.h> |
| 21 | #include <linux/phy.h> | 21 | #include <linux/phy.h> |
| 22 | #include <linux/byteorder/generic.h> | 22 | #include <linux/byteorder/generic.h> |
| 23 | #include <linux/if_arp.h> | ||
| 23 | 24 | ||
| 24 | #include <uapi/linux/if_macsec.h> | 25 | #include <uapi/linux/if_macsec.h> |
| 25 | 26 | ||
| @@ -3856,6 +3857,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev, · 3830 unmodified lines | |||
| 3856 | real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); | 3857 | real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); |
| 3857 | if (!real_dev) | 3858 | if (!real_dev) |
| 3858 | return -ENODEV; | 3859 | return -ENODEV; |
| 3860 | if (real_dev->type != ARPHRD_ETHER) | ||
| 3861 | return -EINVAL; | ||
| 3859 | 3862 | ||
| 3860 | dev->priv_flags |= IFF_MACSEC; | 3863 | dev->priv_flags |= IFF_MACSEC; |
| 3861 | 3864 | ||
| @@ -29,9 +29,9 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, · 28 unmodified lines | |||
| 29 | return -ENOMEM; | 29 | return -ENOMEM; |
| 30 | 30 | ||
| 31 | p = buf; | 31 | p = buf; |
| 32 | p += snprintf(p, bufsize - (p - buf), | 32 | p += scnprintf(p, bufsize - (p - buf), |
| 33 | "SA count=%u tx=%u\n", | 33 | "SA count=%u tx=%u\n", |
| 34 | ipsec->count, ipsec->tx); | 34 | ipsec->count, ipsec->tx); |
| 35 | 35 | ||
| 36 | for (i = 0; i < NSIM_IPSEC_MAX_SA_COUNT; i++) { | 36 | for (i = 0; i < NSIM_IPSEC_MAX_SA_COUNT; i++) { |
| 37 | struct nsim_sa *sap = &ipsec->sa[i]; | 37 | struct nsim_sa *sap = &ipsec->sa[i]; |
| @@ -39,18 +39,18 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, · 1 unmodified line | |||
| 39 | if (!sap->used) | 39 | if (!sap->used) |
| 40 | continue; | 40 | continue; |
| 41 | 41 | ||
| 42 | p += snprintf(p, bufsize - (p - buf), | 42 | p += scnprintf(p, bufsize - (p - buf), |
| 43 | "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", | 43 | "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", |
| 44 | i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], | 44 | i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], |
| 45 | sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); | 45 | sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); |
| 46 | p += snprintf(p, bufsize - (p - buf), | 46 | p += scnprintf(p, bufsize - (p - buf), |
| 47 | "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", | 47 | "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", |
| 48 | i, be32_to_cpu(sap->xs->id.spi), | 48 | i, be32_to_cpu(sap->xs->id.spi), |
| 49 | sap->xs->id.proto, sap->salt, sap->crypt); | 49 | sap->xs->id.proto, sap->salt, sap->crypt); |
| 50 | p += snprintf(p, bufsize - (p - buf), | 50 | p += scnprintf(p, bufsize - (p - buf), |
| 51 | "sa[%i] key=0x%08x %08x %08x %08x\n", | 51 | "sa[%i] key=0x%08x %08x %08x %08x\n", |
| 52 | i, sap->key[0], sap->key[1], | 52 | i, sap->key[0], sap->key[1], |
| 53 | sap->key[2], sap->key[3]); | 53 | sap->key[2], sap->key[3]); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | len = simple_read_from_buffer(buffer, count, ppos, buf, p - buf); | 56 | len = simple_read_from_buffer(buffer, count, ppos, buf, p - buf); |
| @@ -30,7 +30,8 @@ · 29 unmodified lines | |||
| 30 | #define DP83867_CTRL 0x1f | 30 | #define DP83867_CTRL 0x1f |
| 31 | 31 | ||
| 32 | /* Extended Registers */ | 32 | /* Extended Registers */ |
| 33 | #define DP83867_CFG4 0x0031 | 33 | #define DP83867_FLD_THR_CFG 0x002e |
| 34 | #define DP83867_CFG4 0x0031 | ||
| 34 | #define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6)) | 35 | #define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6)) |
| 35 | #define DP83867_CFG4_SGMII_ANEG_TIMER_11MS (3 << 5) | 36 | #define DP83867_CFG4_SGMII_ANEG_TIMER_11MS (3 << 5) |
| 36 | #define DP83867_CFG4_SGMII_ANEG_TIMER_800US (2 << 5) | 37 | #define DP83867_CFG4_SGMII_ANEG_TIMER_800US (2 << 5) |
| @@ -93,6 +94,7 @@ · 56 unmodified lines | |||
| 93 | #define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK GENMASK(2, 0) | 94 | #define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK GENMASK(2, 0) |
| 94 | #define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT 0 | 95 | #define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT 0 |
| 95 | #define DP83867_STRAP_STS2_CLK_SKEW_NONE BIT(2) | 96 | #define DP83867_STRAP_STS2_CLK_SKEW_NONE BIT(2) |
| 97 | #define DP83867_STRAP_STS2_STRAP_FLD BIT(10) | ||
| 96 | 98 | ||
| 97 | /* PHY CTRL bits */ | 99 | /* PHY CTRL bits */ |
| 98 | #define DP83867_PHYCR_TX_FIFO_DEPTH_SHIFT 14 | 100 | #define DP83867_PHYCR_TX_FIFO_DEPTH_SHIFT 14 |
| @@ -145,6 +147,9 @@ · 46 unmodified lines | |||
| 145 | /* CFG4 bits */ | 147 | /* CFG4 bits */ |
| 146 | #define DP83867_CFG4_PORT_MIRROR_EN BIT(0) | 148 | #define DP83867_CFG4_PORT_MIRROR_EN BIT(0) |
| 147 | 149 | ||
| 150 | /* FLD_THR_CFG */ | ||
| 151 | #define DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK 0x7 | ||
| 152 | |||
| 148 | enum { | 153 | enum { |
| 149 | DP83867_PORT_MIRROING_KEEP, | 154 | DP83867_PORT_MIRROING_KEEP, |
| 150 | DP83867_PORT_MIRROING_EN, | 155 | DP83867_PORT_MIRROING_EN, |
| @@ -622,6 +627,20 @@ static int dp83867_config_init(struct phy_device *phydev) · 471 unmodified lines | |||
| 622 | phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, | 627 | phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, |
| 623 | BIT(7)); | 628 | BIT(7)); |
| 624 | 629 | ||
| 630 | bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2); | ||
| 631 | if (bs & DP83867_STRAP_STS2_STRAP_FLD) { | ||
| 632 | /* When using strap to enable FLD, the ENERGY_LOST_FLD_THR will | ||
| 633 | * be set to 0x2. This may causes the PHY link to be unstable - | ||
| 634 | * the default value 0x1 need to be restored. | ||
| 635 | */ | ||
| 636 | ret = phy_modify_mmd(phydev, DP83867_DEVADDR, | ||
| 637 | DP83867_FLD_THR_CFG, | ||
| 638 | DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK, | ||
| 639 | 0x1); | ||
| 640 | if (ret) | ||
| 641 | return ret; | ||
| 642 | } | ||
| 643 | |||
| 625 | if (phy_interface_is_rgmii(phydev) || | 644 | if (phy_interface_is_rgmii(phydev) || |
| 626 | phydev->interface == PHY_INTERFACE_MODE_SGMII) { | 645 | phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
| 627 | val = phy_read(phydev, MII_DP83867_PHYCTRL); | 646 | val = phy_read(phydev, MII_DP83867_PHYCTRL); |
| @@ -242,11 +242,9 @@ static int unimac_mdio_probe(struct platform_device *pdev) · 241 unmodified lines | |||
| 242 | return -ENOMEM; | 242 | return -ENOMEM; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | priv->clk = devm_clk_get(&pdev->dev, NULL); | 245 | priv->clk = devm_clk_get_optional(&pdev->dev, NULL); |
| 246 | if (PTR_ERR(priv->clk) == -EPROBE_DEFER) | 246 | if (IS_ERR(priv->clk)) |
| 247 | return PTR_ERR(priv->clk); | 247 | return PTR_ERR(priv->clk); |
| 248 | else | ||
| 249 | priv->clk = NULL; | ||
| 250 | 248 | ||
| 251 | ret = clk_prepare_enable(priv->clk); | 249 | ret = clk_prepare_enable(priv->clk); |
| 252 | if (ret) | 250 | if (ret) |
| @@ -282,8 +282,13 @@ static int mdio_mux_iproc_suspend(struct device *dev) · 281 unmodified lines | |||
| 282 | static int mdio_mux_iproc_resume(struct device *dev) | 282 | static int mdio_mux_iproc_resume(struct device *dev) |
| 283 | { | 283 | { |
| 284 | struct iproc_mdiomux_desc *md = dev_get_drvdata(dev); | 284 | struct iproc_mdiomux_desc *md = dev_get_drvdata(dev); |
| 285 | int rc; | ||
| 285 | 286 | ||
| 286 | clk_prepare_enable(md->core_clk); | 287 | rc = clk_prepare_enable(md->core_clk); |
| 288 | if (rc) { | ||
| 289 | dev_err(md->dev, "failed to enable core clk\n"); | ||
| 290 | return rc; | ||
| 291 | } | ||
| 287 | mdio_mux_iproc_config(md); | 292 | mdio_mux_iproc_config(md); |
| 288 | 293 | ||
| 289 | return 0; | 294 | return 0; |
| @@ -572,13 +572,15 @@ static void sfp_upstream_clear(struct sfp_bus *bus) · 571 unmodified lines | |||
| 572 | * the sfp_bus structure, incrementing its reference count. This must | 572 | * the sfp_bus structure, incrementing its reference count. This must |
| 573 | * be put via sfp_bus_put() when done. | 573 | * be put via sfp_bus_put() when done. |
| 574 | * | 574 | * |
| 575 | * Returns: on success, a pointer to the sfp_bus structure, | 575 | * Returns: |
| 576 | * %NULL if no SFP is specified, | 576 | * - on success, a pointer to the sfp_bus structure, |
| 577 | * on failure, an error pointer value: | 577 | * - %NULL if no SFP is specified, |
| 578 | * corresponding to the errors detailed for | 578 | * - on failure, an error pointer value: |
| 579 | * fwnode_property_get_reference_args(). | 579 | * |
| 580 | * %-ENOMEM if we failed to allocate the bus. | 580 | * - corresponding to the errors detailed for |
| 581 | * an error from the upstream's connect_phy() method. | 581 | * fwnode_property_get_reference_args(). |
| 582 | * - %-ENOMEM if we failed to allocate the bus. | ||
| 583 | * - an error from the upstream's connect_phy() method. | ||
| 582 | */ | 584 | */ |
| 583 | struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) | 585 | struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) |
| 584 | { | 586 | { |
| @@ -612,13 +614,15 @@ EXPORT_SYMBOL_GPL(sfp_bus_find_fwnode); · 27 unmodified lines | |||
| 612 | * the SFP bus using sfp_register_upstream(). This takes a reference on the | 614 | * the SFP bus using sfp_register_upstream(). This takes a reference on the |
| 613 | * bus, so it is safe to put the bus after this call. | 615 | * bus, so it is safe to put the bus after this call. |
| 614 | * | 616 | * |
| 615 | * Returns: on success, a pointer to the sfp_bus structure, | 617 | * Returns: |
| 616 | * %NULL if no SFP is specified, | 618 | * - on success, a pointer to the sfp_bus structure, |
| 617 | * on failure, an error pointer value: | 619 | * - %NULL if no SFP is specified, |
| 618 | * corresponding to the errors detailed for | 620 | * - on failure, an error pointer value: |
| 619 | * fwnode_property_get_reference_args(). | 621 | * |
| 620 | * %-ENOMEM if we failed to allocate the bus. | 622 | * - corresponding to the errors detailed for |
| 621 | * an error from the upstream's connect_phy() method. | 623 | * fwnode_property_get_reference_args(). |
| 624 | * - %-ENOMEM if we failed to allocate the bus. | ||
| 625 | * - an error from the upstream's connect_phy() method. | ||
| 622 | */ | 626 | */ |
| 623 | int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, | 627 | int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, |
| 624 | const struct sfp_upstream_ops *ops) | 628 | const struct sfp_upstream_ops *ops) |
| @@ -1210,6 +1210,7 @@ static const struct usb_device_id products[] = { · 1209 unmodified lines | |||
| 1210 | {QMI_FIXED_INTF(0x1435, 0xd182, 5)}, /* Wistron NeWeb D18 */ | 1210 | {QMI_FIXED_INTF(0x1435, 0xd182, 5)}, /* Wistron NeWeb D18 */ |
| 1211 | {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ | 1211 | {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ |
| 1212 | {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ | 1212 | {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ |
| 1213 | {QMI_FIXED_INTF(0x1690, 0x7588, 4)}, /* ASKEY WWHC050 */ | ||
| 1213 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ | 1214 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ |
| 1214 | {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ | 1215 | {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ |
| 1215 | {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */ | 1216 | {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */ |
| @@ -2779,10 +2779,19 @@ static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan, · 2778 unmodified lines | |||
| 2779 | /* Setup stats when device is created */ | 2779 | /* Setup stats when device is created */ |
| 2780 | static int vxlan_init(struct net_device *dev) | 2780 | static int vxlan_init(struct net_device *dev) |
| 2781 | { | 2781 | { |
| 2782 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
| 2783 | int err; | ||
| 2784 | |||
| 2782 | dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); | 2785 | dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
| 2783 | if (!dev->tstats) | 2786 | if (!dev->tstats) |
| 2784 | return -ENOMEM; | 2787 | return -ENOMEM; |
| 2785 | 2788 | ||
| 2789 | err = gro_cells_init(&vxlan->gro_cells, dev); | ||
| 2790 | if (err) { | ||
| 2791 | free_percpu(dev->tstats); | ||
| 2792 | return err; | ||
| 2793 | } | ||
| 2794 | |||
| 2786 | return 0; | 2795 | return 0; |
| 2787 | } | 2796 | } |
| 2788 | 2797 | ||
| @@ -3043,8 +3052,6 @@ static void vxlan_setup(struct net_device *dev) · 254 unmodified lines | |||
| 3043 | 3052 | ||
| 3044 | vxlan->dev = dev; | 3053 | vxlan->dev = dev; |
| 3045 | 3054 | ||
| 3046 | gro_cells_init(&vxlan->gro_cells, dev); | ||
| 3047 | |||
| 3048 | for (h = 0; h < FDB_HASH_SIZE; ++h) { | 3055 | for (h = 0; h < FDB_HASH_SIZE; ++h) { |
| 3049 | spin_lock_init(&vxlan->hash_lock[h]); | 3056 | spin_lock_init(&vxlan->hash_lock[h]); |
| 3050 | INIT_HLIST_HEAD(&vxlan->fdb_head[h]); | 3057 | INIT_HLIST_HEAD(&vxlan->fdb_head[h]); |
| @@ -122,7 +122,7 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) · 121 unmodified lines | |||
| 122 | u32 mtu; | 122 | u32 mtu; |
| 123 | int ret; | 123 | int ret; |
| 124 | 124 | ||
| 125 | if (unlikely(wg_skb_examine_untrusted_ip_hdr(skb) != skb->protocol)) { | 125 | if (unlikely(!wg_check_packet_protocol(skb))) { |
| 126 | ret = -EPROTONOSUPPORT; | 126 | ret = -EPROTONOSUPPORT; |
| 127 | net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name); | 127 | net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name); |
| 128 | goto err; | 128 | goto err; |
| @@ -411,11 +411,7 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs) · 410 unmodified lines | |||
| 411 | 411 | ||
| 412 | peer = wg_peer_create(wg, public_key, preshared_key); | 412 | peer = wg_peer_create(wg, public_key, preshared_key); |
| 413 | if (IS_ERR(peer)) { | 413 | if (IS_ERR(peer)) { |
| 414 | /* Similar to the above, if the key is invalid, we skip | 414 | ret = PTR_ERR(peer); |
| 415 | * it without fanfare, so that services don't need to | ||
| 416 | * worry about doing key validation themselves. | ||
| 417 | */ | ||
| 418 | ret = PTR_ERR(peer) == -EKEYREJECTED ? 0 : PTR_ERR(peer); | ||
| 419 | peer = NULL; | 415 | peer = NULL; |
| 420 | goto out; | 416 | goto out; |
| 421 | } | 417 | } |
| @@ -569,7 +565,7 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info) · 147 unmodified lines | |||
| 569 | private_key); | 565 | private_key); |
| 570 | list_for_each_entry_safe(peer, temp, &wg->peer_list, | 566 | list_for_each_entry_safe(peer, temp, &wg->peer_list, |
| 571 | peer_list) { | 567 | peer_list) { |
| 572 | BUG_ON(!wg_noise_precompute_static_static(peer)); | 568 | wg_noise_precompute_static_static(peer); |
| 573 | wg_noise_expire_current_peer_keypairs(peer); | 569 | wg_noise_expire_current_peer_keypairs(peer); |
| 574 | } | 570 | } |
| 575 | wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); | 571 | wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); |
| @@ -44,32 +44,23 @@ void __init wg_noise_init(void) · 43 unmodified lines | |||
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /* Must hold peer->handshake.static_identity->lock */ | 46 | /* Must hold peer->handshake.static_identity->lock */ |
| 47 | bool wg_noise_precompute_static_static(struct wg_peer *peer) | 47 | void wg_noise_precompute_static_static(struct wg_peer *peer) |
| 48 | { | 48 | { |
| 49 | bool ret; | ||
| 50 | |||
| 51 | down_write(&peer->handshake.lock); | 49 | down_write(&peer->handshake.lock); |
| 52 | if (peer->handshake.static_identity->has_identity) { | 50 | if (!peer->handshake.static_identity->has_identity || |
| 53 | ret = curve25519( | 51 | !curve25519(peer->handshake.precomputed_static_static, |
| 54 | peer->handshake.precomputed_static_static, | ||
| 55 | peer->handshake.static_identity->static_private, | 52 | peer->handshake.static_identity->static_private, |
| 56 | peer->handshake.remote_static); | 53 | peer->handshake.remote_static)) |
| 57 | } else { | ||
| 58 | u8 empty[NOISE_PUBLIC_KEY_LEN] = { 0 }; | ||
| 59 | |||
| 60 | ret = curve25519(empty, empty, peer->handshake.remote_static); | ||
| 61 | memset(peer->handshake.precomputed_static_static, 0, | 54 | memset(peer->handshake.precomputed_static_static, 0, |
| 62 | NOISE_PUBLIC_KEY_LEN); | 55 | NOISE_PUBLIC_KEY_LEN); |
| 63 | } | ||
| 64 | up_write(&peer->handshake.lock); | 56 | up_write(&peer->handshake.lock); |
| 65 | return ret; | ||
| 66 | } | 57 | } |
| 67 | 58 | ||
| 68 | bool wg_noise_handshake_init(struct noise_handshake *handshake, | 59 | void wg_noise_handshake_init(struct noise_handshake *handshake, |
| 69 | struct noise_static_identity *static_identity, | 60 | struct noise_static_identity *static_identity, |
| 70 | const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], | 61 | const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], |
| 71 | const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], | 62 | const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], |
| 72 | struct wg_peer *peer) | 63 | struct wg_peer *peer) |
| 73 | { | 64 | { |
| 74 | memset(handshake, 0, sizeof(*handshake)); | 65 | memset(handshake, 0, sizeof(*handshake)); |
| 75 | init_rwsem(&handshake->lock); | 66 | init_rwsem(&handshake->lock); |
| @@ -81,7 +72,7 @@ bool wg_noise_handshake_init(struct noise_handshake *handshake, · 5 unmodified lines | |||
| 81 | NOISE_SYMMETRIC_KEY_LEN); | 72 | NOISE_SYMMETRIC_KEY_LEN); |
| 82 | handshake->static_identity = static_identity; | 73 | handshake->static_identity = static_identity; |
| 83 | handshake->state = HANDSHAKE_ZEROED; | 74 | handshake->state = HANDSHAKE_ZEROED; |
| 84 | return wg_noise_precompute_static_static(peer); | 75 | wg_noise_precompute_static_static(peer); |
| 85 | } | 76 | } |
| 86 | 77 | ||
| 87 | static void handshake_zero(struct noise_handshake *handshake) | 78 | static void handshake_zero(struct noise_handshake *handshake) |
| @@ -403,6 +394,19 @@ static bool __must_check mix_dh(u8 chaining_key[NOISE_HASH_LEN], · 315 unmodified lines | |||
| 403 | return true; | 394 | return true; |
| 404 | } | 395 | } |
| 405 | 396 | ||
| 397 | static bool __must_check mix_precomputed_dh(u8 chaining_key[NOISE_HASH_LEN], | ||
| 398 | u8 key[NOISE_SYMMETRIC_KEY_LEN], | ||
| 399 | const u8 precomputed[NOISE_PUBLIC_KEY_LEN]) | ||
| 400 | { | ||
| 401 | static u8 zero_point[NOISE_PUBLIC_KEY_LEN]; | ||
| 402 | if (unlikely(!crypto_memneq(precomputed, zero_point, NOISE_PUBLIC_KEY_LEN))) | ||
| 403 | return false; | ||
| 404 | kdf(chaining_key, key, NULL, precomputed, NOISE_HASH_LEN, | ||
| 405 | NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, | ||
| 406 | chaining_key); | ||
| 407 | return true; | ||
| 408 | } | ||
| 409 | |||
| 406 | static void mix_hash(u8 hash[NOISE_HASH_LEN], const u8 *src, size_t src_len) | 410 | static void mix_hash(u8 hash[NOISE_HASH_LEN], const u8 *src, size_t src_len) |
| 407 | { | 411 | { |
| 408 | struct blake2s_state blake; | 412 | struct blake2s_state blake; |
| @@ -531,10 +535,9 @@ wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst, · 122 unmodified lines | |||
| 531 | NOISE_PUBLIC_KEY_LEN, key, handshake->hash); | 535 | NOISE_PUBLIC_KEY_LEN, key, handshake->hash); |
| 532 | 536 | ||
| 533 | /* ss */ | 537 | /* ss */ |
| 534 | kdf(handshake->chaining_key, key, NULL, | 538 | if (!mix_precomputed_dh(handshake->chaining_key, key, |
| 535 | handshake->precomputed_static_static, NOISE_HASH_LEN, | 539 | handshake->precomputed_static_static)) |
| 536 | NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, | 540 | goto out; |
| 537 | handshake->chaining_key); | ||
| 538 | 541 | ||
| 539 | /* {t} */ | 542 | /* {t} */ |
| 540 | tai64n_now(timestamp); | 543 | tai64n_now(timestamp); |
| @@ -595,9 +598,9 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src, · 54 unmodified lines | |||
| 595 | handshake = &peer->handshake; | 598 | handshake = &peer->handshake; |
| 596 | 599 | ||
| 597 | /* ss */ | 600 | /* ss */ |
| 598 | kdf(chaining_key, key, NULL, handshake->precomputed_static_static, | 601 | if (!mix_precomputed_dh(chaining_key, key, |
| 599 | NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, | 602 | handshake->precomputed_static_static)) |
| 600 | chaining_key); | 603 | goto out; |
| 601 | 604 | ||
| 602 | /* {t} */ | 605 | /* {t} */ |
| 603 | if (!message_decrypt(t, src->encrypted_timestamp, | 606 | if (!message_decrypt(t, src->encrypted_timestamp, |
| @@ -94,11 +94,11 @@ struct noise_handshake { · 93 unmodified lines | |||
| 94 | struct wg_device; | 94 | struct wg_device; |
| 95 | 95 | ||
| 96 | void wg_noise_init(void); | 96 | void wg_noise_init(void); |
| 97 | bool wg_noise_handshake_init(struct noise_handshake *handshake, | 97 | void wg_noise_handshake_init(struct noise_handshake *handshake, |
| 98 | struct noise_static_identity *static_identity, | 98 | struct noise_static_identity *static_identity, |
| 99 | const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], | 99 | const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], |
| 100 | const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], | 100 | const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], |
| 101 | struct wg_peer *peer); | 101 | struct wg_peer *peer); |
| 102 | void wg_noise_handshake_clear(struct noise_handshake *handshake); | 102 | void wg_noise_handshake_clear(struct noise_handshake *handshake); |
| 103 | static inline void wg_noise_reset_last_sent_handshake(atomic64_t *handshake_ns) | 103 | static inline void wg_noise_reset_last_sent_handshake(atomic64_t *handshake_ns) |
| 104 | { | 104 | { |
| @@ -116,7 +116,7 @@ void wg_noise_expire_current_peer_keypairs(struct wg_peer *peer); · 11 unmodified lines | |||
| 116 | void wg_noise_set_static_identity_private_key( | 116 | void wg_noise_set_static_identity_private_key( |
| 117 | struct noise_static_identity *static_identity, | 117 | struct noise_static_identity *static_identity, |
| 118 | const u8 private_key[NOISE_PUBLIC_KEY_LEN]); | 118 | const u8 private_key[NOISE_PUBLIC_KEY_LEN]); |
| 119 | bool wg_noise_precompute_static_static(struct wg_peer *peer); | 119 | void wg_noise_precompute_static_static(struct wg_peer *peer); |
| 120 | 120 | ||
| 121 | bool | 121 | bool |
| 122 | wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst, | 122 | wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst, |
| @@ -34,11 +34,8 @@ struct wg_peer *wg_peer_create(struct wg_device *wg, · 33 unmodified lines | |||
| 34 | return ERR_PTR(ret); | 34 | return ERR_PTR(ret); |
| 35 | peer->device = wg; | 35 | peer->device = wg; |
| 36 | 36 | ||
| 37 | if (!wg_noise_handshake_init(&peer->handshake, &wg->static_identity, | 37 | wg_noise_handshake_init(&peer->handshake, &wg->static_identity, |
| 38 | public_key, preshared_key, peer)) { | 38 | public_key, preshared_key, peer); |
| 39 | ret = -EKEYREJECTED; | ||
| 40 | goto err_1; | ||
| 41 | } | ||
| 42 | if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL)) | 39 | if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL)) |
| 43 | goto err_1; | 40 | goto err_1; |
| 44 | if (wg_packet_queue_init(&peer->tx_queue, wg_packet_tx_worker, false, | 41 | if (wg_packet_queue_init(&peer->tx_queue, wg_packet_tx_worker, false, |
| @@ -66,7 +66,7 @@ struct packet_cb { · 65 unmodified lines | |||
| 66 | #define PACKET_PEER(skb) (PACKET_CB(skb)->keypair->entry.peer) | 66 | #define PACKET_PEER(skb) (PACKET_CB(skb)->keypair->entry.peer) |
| 67 | 67 | ||
| 68 | /* Returns either the correct skb->protocol value, or 0 if invalid. */ | 68 | /* Returns either the correct skb->protocol value, or 0 if invalid. */ |
| 69 | static inline __be16 wg_skb_examine_untrusted_ip_hdr(struct sk_buff *skb) | 69 | static inline __be16 wg_examine_packet_protocol(struct sk_buff *skb) |
| 70 | { | 70 | { |
| 71 | if (skb_network_header(skb) >= skb->head && | 71 | if (skb_network_header(skb) >= skb->head && |
| 72 | (skb_network_header(skb) + sizeof(struct iphdr)) <= | 72 | (skb_network_header(skb) + sizeof(struct iphdr)) <= |
| @@ -81,6 +81,12 @@ static inline __be16 wg_skb_examine_untrusted_ip_hdr(struct sk_buff *skb) · 8 unmodified lines | |||
| 81 | return 0; | 81 | return 0; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static inline bool wg_check_packet_protocol(struct sk_buff *skb) | ||
| 85 | { | ||
| 86 | __be16 real_protocol = wg_examine_packet_protocol(skb); | ||
| 87 | return real_protocol && skb->protocol == real_protocol; | ||
| 88 | } | ||
| 89 | |||
| 84 | static inline void wg_reset_packet(struct sk_buff *skb) | 90 | static inline void wg_reset_packet(struct sk_buff *skb) |
| 85 | { | 91 | { |
| 86 | skb_scrub_packet(skb, true); | 92 | skb_scrub_packet(skb, true); |
| @@ -94,8 +100,8 @@ static inline void wg_reset_packet(struct sk_buff *skb) · 7 unmodified lines | |||
| 94 | skb->dev = NULL; | 100 | skb->dev = NULL; |
| 95 | #ifdef CONFIG_NET_SCHED | 101 | #ifdef CONFIG_NET_SCHED |
| 96 | skb->tc_index = 0; | 102 | skb->tc_index = 0; |
| 97 | skb_reset_tc(skb); | ||
| 98 | #endif | 103 | #endif |
| 104 | skb_reset_redirect(skb); | ||
| 99 | skb->hdr_len = skb_headroom(skb); | 105 | skb->hdr_len = skb_headroom(skb); |
| 100 | skb_reset_mac_header(skb); | 106 | skb_reset_mac_header(skb); |
| 101 | skb_reset_network_header(skb); | 107 | skb_reset_network_header(skb); |
| @@ -56,7 +56,7 @@ static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg) · 55 unmodified lines | |||
| 56 | size_t data_offset, data_len, header_len; | 56 | size_t data_offset, data_len, header_len; |
| 57 | struct udphdr *udp; | 57 | struct udphdr *udp; |
| 58 | 58 | ||
| 59 | if (unlikely(wg_skb_examine_untrusted_ip_hdr(skb) != skb->protocol || | 59 | if (unlikely(!wg_check_packet_protocol(skb) || |
| 60 | skb_transport_header(skb) < skb->head || | 60 | skb_transport_header(skb) < skb->head || |
| 61 | (skb_transport_header(skb) + sizeof(struct udphdr)) > | 61 | (skb_transport_header(skb) + sizeof(struct udphdr)) > |
| 62 | skb_tail_pointer(skb))) | 62 | skb_tail_pointer(skb))) |
| @@ -388,7 +388,7 @@ static void wg_packet_consume_data_done(struct wg_peer *peer, · 325 unmodified lines | |||
| 388 | */ | 388 | */ |
| 389 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 389 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 390 | skb->csum_level = ~0; /* All levels */ | 390 | skb->csum_level = ~0; /* All levels */ |
| 391 | skb->protocol = wg_skb_examine_untrusted_ip_hdr(skb); | 391 | skb->protocol = wg_examine_packet_protocol(skb); |
| 392 | if (skb->protocol == htons(ETH_P_IP)) { | 392 | if (skb->protocol == htons(ETH_P_IP)) { |
| 393 | len = ntohs(ip_hdr(skb)->tot_len); | 393 | len = ntohs(ip_hdr(skb)->tot_len); |
| 394 | if (unlikely(len < sizeof(struct iphdr))) | 394 | if (unlikely(len < sizeof(struct iphdr))) |
| @@ -587,8 +587,7 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb) · 192 unmodified lines | |||
| 587 | wg_packet_consume_data(wg, skb); | 587 | wg_packet_consume_data(wg, skb); |
| 588 | break; | 588 | break; |
| 589 | default: | 589 | default: |
| 590 | net_dbg_skb_ratelimited("%s: Invalid packet from %pISpfsc\n", | 590 | WARN(1, "Non-exhaustive parsing of packet header lead to unknown packet type!\n"); |
| 591 | wg->dev->name, skb); | ||
| 592 | goto err; | 591 | goto err; |
| 593 | } | 592 | } |
| 594 | return; | 593 | return; |
| @@ -300,6 +300,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = { · 299 unmodified lines | |||
| 300 | * HT size; mac80211 would otherwise pick the HE max (256) by default. | 300 | * HT size; mac80211 would otherwise pick the HE max (256) by default. |
| 301 | */ | 301 | */ |
| 302 | .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, | 302 | .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, |
| 303 | .tx_with_siso_diversity = true, | ||
| 303 | .num_rbds = IWL_NUM_RBDS_22000_HE, | 304 | .num_rbds = IWL_NUM_RBDS_22000_HE, |
| 304 | }; | 305 | }; |
| 305 | 306 | ||
| @@ -326,6 +327,7 @@ const struct iwl_cfg iwl_ax101_cfg_quz_hr = { · 20 unmodified lines | |||
| 326 | * HT size; mac80211 would otherwise pick the HE max (256) by default. | 327 | * HT size; mac80211 would otherwise pick the HE max (256) by default. |
| 327 | */ | 328 | */ |
| 328 | .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, | 329 | .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, |
| 330 | .tx_with_siso_diversity = true, | ||
| 329 | .num_rbds = IWL_NUM_RBDS_22000_HE, | 331 | .num_rbds = IWL_NUM_RBDS_22000_HE, |
| 330 | }; | 332 | }; |
| 331 | 333 | ||
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | * Copyright (C) 2019 Intel Corporation | 9 | * Copyright (C) 2019 - 2020 Intel Corporation |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -27,7 +27,7 @@ · 14 unmodified lines | |||
| 27 | * BSD LICENSE | 27 | * BSD LICENSE |
| 28 | * | 28 | * |
| 29 | * Copyright(c) 2017 Intel Deutschland GmbH | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | * Copyright (C) 2019 Intel Corporation | 30 | * Copyright (C) 2019 - 2020 Intel Corporation |
| 31 | * All rights reserved. | 31 | * All rights reserved. |
| 32 | * | 32 | * |
| 33 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without |
| @@ -491,13 +491,13 @@ int iwl_validate_sar_geo_profile(struct iwl_fw_runtime *fwrt, · 457 unmodified lines | |||
| 491 | } | 491 | } |
| 492 | IWL_EXPORT_SYMBOL(iwl_validate_sar_geo_profile); | 492 | IWL_EXPORT_SYMBOL(iwl_validate_sar_geo_profile); |
| 493 | 493 | ||
| 494 | void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | 494 | int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, |
| 495 | struct iwl_per_chain_offset_group *table) | 495 | struct iwl_per_chain_offset_group *table) |
| 496 | { | 496 | { |
| 497 | int ret, i, j; | 497 | int ret, i, j; |
| 498 | 498 | ||
| 499 | if (!iwl_sar_geo_support(fwrt)) | 499 | if (!iwl_sar_geo_support(fwrt)) |
| 500 | return; | 500 | return -EOPNOTSUPP; |
| 501 | 501 | ||
| 502 | ret = iwl_sar_get_wgds_table(fwrt); | 502 | ret = iwl_sar_get_wgds_table(fwrt); |
| 503 | if (ret < 0) { | 503 | if (ret < 0) { |
| @@ -505,7 +505,7 @@ void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, · 1 unmodified line | |||
| 505 | "Geo SAR BIOS table invalid or unavailable. (%d)\n", | 505 | "Geo SAR BIOS table invalid or unavailable. (%d)\n", |
| 506 | ret); | 506 | ret); |
| 507 | /* we don't fail if the table is not available */ | 507 | /* we don't fail if the table is not available */ |
| 508 | return; | 508 | return -ENOENT; |
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS * | 511 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS * |
| @@ -530,5 +530,7 @@ void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, · 18 unmodified lines | |||
| 530 | i, j, value[1], value[2], value[0]); | 530 | i, j, value[1], value[2], value[0]); |
| 531 | } | 531 | } |
| 532 | } | 532 | } |
| 533 | |||
| 534 | return 0; | ||
| 533 | } | 535 | } |
| 534 | IWL_EXPORT_SYMBOL(iwl_sar_geo_init); | 536 | IWL_EXPORT_SYMBOL(iwl_sar_geo_init); |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | * Copyright(c) 2018 - 2019 Intel Corporation | 9 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -27,7 +27,7 @@ · 14 unmodified lines | |||
| 27 | * BSD LICENSE | 27 | * BSD LICENSE |
| 28 | * | 28 | * |
| 29 | * Copyright(c) 2017 Intel Deutschland GmbH | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | * Copyright(c) 2018 - 2019 Intel Corporation | 30 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 31 | * All rights reserved. | 31 | * All rights reserved. |
| 32 | * | 32 | * |
| 33 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without |
| @@ -171,8 +171,9 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt); · 137 unmodified lines | |||
| 171 | int iwl_validate_sar_geo_profile(struct iwl_fw_runtime *fwrt, | 171 | int iwl_validate_sar_geo_profile(struct iwl_fw_runtime *fwrt, |
| 172 | struct iwl_host_cmd *cmd); | 172 | struct iwl_host_cmd *cmd); |
| 173 | 173 | ||
| 174 | void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | 174 | int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, |
| 175 | struct iwl_per_chain_offset_group *table); | 175 | struct iwl_per_chain_offset_group *table); |
| 176 | |||
| 176 | #else /* CONFIG_ACPI */ | 177 | #else /* CONFIG_ACPI */ |
| 177 | 178 | ||
| 178 | static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method) | 179 | static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method) |
| @@ -243,9 +244,10 @@ static inline int iwl_validate_sar_geo_profile(struct iwl_fw_runtime *fwrt, · 64 unmodified lines | |||
| 243 | return -ENOENT; | 244 | return -ENOENT; |
| 244 | } | 245 | } |
| 245 | 246 | ||
| 246 | static inline void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | 247 | static inline int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, |
| 247 | struct iwl_per_chain_offset_group *table) | 248 | struct iwl_per_chain_offset_group *table) |
| 248 | { | 249 | { |
| 250 | return -ENOENT; | ||
| 249 | } | 251 | } |
| 250 | 252 | ||
| 251 | #endif /* CONFIG_ACPI */ | 253 | #endif /* CONFIG_ACPI */ |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 - 2019 Intel Corporation | 11 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 12 | * | 12 | * |
| 13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 14 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -31,7 +31,7 @@ · 16 unmodified lines | |||
| 31 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 31 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
| 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 33 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH | 33 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 34 | * Copyright(c) 2018 - 2019 Intel Corporation | 34 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 35 | * All rights reserved. | 35 | * All rights reserved. |
| 36 | * | 36 | * |
| 37 | * Redistribution and use in source and binary forms, with or without | 37 | * Redistribution and use in source and binary forms, with or without |
| @@ -1409,11 +1409,7 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt, · 1371 unmodified lines | |||
| 1409 | goto out; | 1409 | goto out; |
| 1410 | } | 1410 | } |
| 1411 | 1411 | ||
| 1412 | /* | 1412 | offs = rxf_data.offset; |
| 1413 | * region register have absolute value so apply rxf offset after | ||
| 1414 | * reading the registers | ||
| 1415 | */ | ||
| 1416 | offs += rxf_data.offset; | ||
| 1417 | 1413 | ||
| 1418 | /* Lock fence */ | 1414 | /* Lock fence */ |
| 1419 | iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1); | 1415 | iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1); |
| @@ -2494,10 +2490,7 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) · 1074 unmodified lines | |||
| 2494 | goto out; | 2490 | goto out; |
| 2495 | } | 2491 | } |
| 2496 | 2492 | ||
| 2497 | if (iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, true)) { | 2493 | iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, true); |
| 2498 | IWL_ERR(fwrt, "Failed to stop DBGC recording, aborting dump\n"); | ||
| 2499 | goto out; | ||
| 2500 | } | ||
| 2501 | 2494 | ||
| 2502 | IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n"); | 2495 | IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n"); |
| 2503 | if (iwl_trans_dbg_ini_valid(fwrt->trans)) | 2496 | if (iwl_trans_dbg_ini_valid(fwrt->trans)) |
| @@ -2662,14 +2655,14 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans, · 158 unmodified lines | |||
| 2662 | return 0; | 2655 | return 0; |
| 2663 | } | 2656 | } |
| 2664 | 2657 | ||
| 2665 | int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, | 2658 | void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, |
| 2666 | struct iwl_fw_dbg_params *params, | 2659 | struct iwl_fw_dbg_params *params, |
| 2667 | bool stop) | 2660 | bool stop) |
| 2668 | { | 2661 | { |
| 2669 | int ret = 0; | 2662 | int ret = 0; |
| 2670 | 2663 | ||
| 2671 | if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) | 2664 | if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) |
| 2672 | return 0; | 2665 | return; |
| 2673 | 2666 | ||
| 2674 | if (fw_has_capa(&fwrt->fw->ucode_capa, | 2667 | if (fw_has_capa(&fwrt->fw->ucode_capa, |
| 2675 | IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP)) | 2668 | IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP)) |
| @@ -2686,7 +2679,5 @@ int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, · 10 unmodified lines | |||
| 2686 | iwl_fw_set_dbg_rec_on(fwrt); | 2679 | iwl_fw_set_dbg_rec_on(fwrt); |
| 2687 | } | 2680 | } |
| 2688 | #endif | 2681 | #endif |
| 2689 | |||
| 2690 | return ret; | ||
| 2691 | } | 2682 | } |
| 2692 | IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_restart_recording); | 2683 | IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_restart_recording); |
| @@ -239,9 +239,9 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, · 238 unmodified lines | |||
| 239 | _iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \ | 239 | _iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \ |
| 240 | iwl_fw_dbg_get_trigger((fwrt)->fw,\ | 240 | iwl_fw_dbg_get_trigger((fwrt)->fw,\ |
| 241 | (trig))) | 241 | (trig))) |
| 242 | int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, | 242 | void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, |
| 243 | struct iwl_fw_dbg_params *params, | 243 | struct iwl_fw_dbg_params *params, |
| 244 | bool stop); | 244 | bool stop); |
| 245 | 245 | ||
| 246 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 246 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 247 | static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt) | 247 | static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt) |
| @@ -1467,7 +1467,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 1466 unmodified lines | |||
| 1467 | kmemdup(pieces->dbg_conf_tlv[i], | 1467 | kmemdup(pieces->dbg_conf_tlv[i], |
| 1468 | pieces->dbg_conf_tlv_len[i], | 1468 | pieces->dbg_conf_tlv_len[i], |
| 1469 | GFP_KERNEL); | 1469 | GFP_KERNEL); |
| 1470 | if (!pieces->dbg_conf_tlv_len[i]) | 1470 | if (!pieces->dbg_conf_tlv[i]) |
| 1471 | goto out_free_fw; | 1471 | goto out_free_fw; |
| 1472 | } | 1472 | } |
| 1473 | } | 1473 | } |
| @@ -762,10 +762,17 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) · 761 unmodified lines | |||
| 762 | u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT); | 762 | u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT); |
| 763 | union geo_tx_power_profiles_cmd cmd; | 763 | union geo_tx_power_profiles_cmd cmd; |
| 764 | u16 len; | 764 | u16 len; |
| 765 | int ret; | ||
| 765 | 766 | ||
| 766 | cmd.geo_cmd.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES); | 767 | cmd.geo_cmd.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES); |
| 767 | 768 | ||
| 768 | iwl_sar_geo_init(&mvm->fwrt, cmd.geo_cmd.table); | 769 | ret = iwl_sar_geo_init(&mvm->fwrt, cmd.geo_cmd.table); |
| 770 | /* | ||
| 771 | * It is a valid scenario to not support SAR, or miss wgds table, | ||
| 772 | * but in that case there is no need to send the command. | ||
| 773 | */ | ||
| 774 | if (ret) | ||
| 775 | return 0; | ||
| 769 | 776 | ||
| 770 | cmd.geo_cmd.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); | 777 | cmd.geo_cmd.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); |
| 771 | 778 | ||
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | * Copyright(c) 2018 - 2019 Intel Corporation | 9 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -27,7 +27,7 @@ · 14 unmodified lines | |||
| 27 | * BSD LICENSE | 27 | * BSD LICENSE |
| 28 | * | 28 | * |
| 29 | * Copyright(c) 2017 Intel Deutschland GmbH | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | * Copyright(c) 2018 - 2019 Intel Corporation | 30 | * Copyright(c) 2018 - 2020 Intel Corporation |
| 31 | * All rights reserved. | 31 | * All rights reserved. |
| 32 | * | 32 | * |
| 33 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without |
| @@ -147,7 +147,11 @@ static u16 rs_fw_get_config_flags(struct iwl_mvm *mvm, · 113 unmodified lines | |||
| 147 | (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) | 147 | (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) |
| 148 | flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; | 148 | flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; |
| 149 | 149 | ||
| 150 | /* consider our LDPC support in case of HE */ | 150 | /* consider LDPC support in case of HE */ |
| 151 | if (he_cap->has_he && (he_cap->he_cap_elem.phy_cap_info[1] & | ||
| 152 | IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) | ||
| 153 | flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; | ||
| 154 | |||
| 151 | if (sband->iftype_data && sband->iftype_data->he_cap.has_he && | 155 | if (sband->iftype_data && sband->iftype_data->he_cap.has_he && |
| 152 | !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & | 156 | !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & |
| 153 | IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) | 157 | IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) |
| @@ -191,11 +195,13 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, · 37 unmodified lines | |||
| 191 | { | 195 | { |
| 192 | u16 supp; | 196 | u16 supp; |
| 193 | int i, highest_mcs; | 197 | int i, highest_mcs; |
| 198 | u8 nss = sta->rx_nss; | ||
| 194 | 199 | ||
| 195 | for (i = 0; i < sta->rx_nss; i++) { | 200 | /* the station support only a single receive chain */ |
| 196 | if (i == IWL_TLC_NSS_MAX) | 201 | if (sta->smps_mode == IEEE80211_SMPS_STATIC) |
| 197 | break; | 202 | nss = 1; |
| 198 | 203 | ||
| 204 | for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { | ||
| 199 | highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); | 205 | highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); |
| 200 | if (!highest_mcs) | 206 | if (!highest_mcs) |
| 201 | continue; | 207 | continue; |
| @@ -241,8 +247,13 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, · 39 unmodified lines | |||
| 241 | u16 tx_mcs_160 = | 247 | u16 tx_mcs_160 = |
| 242 | le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); | 248 | le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); |
| 243 | int i; | 249 | int i; |
| 250 | u8 nss = sta->rx_nss; | ||
| 251 | |||
| 252 | /* the station support only a single receive chain */ | ||
| 253 | if (sta->smps_mode == IEEE80211_SMPS_STATIC) | ||
| 254 | nss = 1; | ||
| 244 | 255 | ||
| 245 | for (i = 0; i < sta->rx_nss && i < IWL_TLC_NSS_MAX; i++) { | 256 | for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { |
| 246 | u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; | 257 | u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; |
| 247 | u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; | 258 | u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; |
| 248 | u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; | 259 | u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; |
| @@ -303,8 +314,14 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, · 54 unmodified lines | |||
| 303 | cmd->mode = IWL_TLC_MNG_MODE_HT; | 314 | cmd->mode = IWL_TLC_MNG_MODE_HT; |
| 304 | cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = | 315 | cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = |
| 305 | cpu_to_le16(ht_cap->mcs.rx_mask[0]); | 316 | cpu_to_le16(ht_cap->mcs.rx_mask[0]); |
| 306 | cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = | 317 | |
| 307 | cpu_to_le16(ht_cap->mcs.rx_mask[1]); | 318 | /* the station support only a single receive chain */ |
| 319 | if (sta->smps_mode == IEEE80211_SMPS_STATIC) | ||
| 320 | cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = | ||
| 321 | 0; | ||
| 322 | else | ||
| 323 | cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = | ||
| 324 | cpu_to_le16(ht_cap->mcs.rx_mask[1]); | ||
| 308 | } | 325 | } |
| 309 | } | 326 | } |
| 310 | 327 | ||
| @@ -785,7 +785,9 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, · 784 unmodified lines | |||
| 785 | if (!le32_to_cpu(notif->status)) { | 785 | if (!le32_to_cpu(notif->status)) { |
| 786 | iwl_mvm_te_check_disconnect(mvm, vif, | 786 | iwl_mvm_te_check_disconnect(mvm, vif, |
| 787 | "Session protection failure"); | 787 | "Session protection failure"); |
| 788 | spin_lock_bh(&mvm->time_event_lock); | ||
| 788 | iwl_mvm_te_clear_data(mvm, te_data); | 789 | iwl_mvm_te_clear_data(mvm, te_data); |
| 790 | spin_unlock_bh(&mvm->time_event_lock); | ||
| 789 | } | 791 | } |
| 790 | 792 | ||
| 791 | if (le32_to_cpu(notif->start)) { | 793 | if (le32_to_cpu(notif->start)) { |
| @@ -801,7 +803,9 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, · 9 unmodified lines | |||
| 801 | */ | 803 | */ |
| 802 | iwl_mvm_te_check_disconnect(mvm, vif, | 804 | iwl_mvm_te_check_disconnect(mvm, vif, |
| 803 | "No beacon heard and the session protection is over already..."); | 805 | "No beacon heard and the session protection is over already..."); |
| 806 | spin_lock_bh(&mvm->time_event_lock); | ||
| 804 | iwl_mvm_te_clear_data(mvm, te_data); | 807 | iwl_mvm_te_clear_data(mvm, te_data); |
| 808 | spin_unlock_bh(&mvm->time_event_lock); | ||
| 805 | } | 809 | } |
| 806 | 810 | ||
| 807 | goto out_unlock; | 811 | goto out_unlock; |
| @@ -939,7 +939,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { · 938 unmodified lines | |||
| 939 | IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), | 939 | IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), |
| 940 | IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), | 940 | IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), |
| 941 | IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), | 941 | IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), |
| 942 | |||
| 943 | #endif /* CONFIG_IWLMVM */ | 942 | #endif /* CONFIG_IWLMVM */ |
| 944 | }; | 943 | }; |
| 945 | 944 | ||
| @@ -561,6 +561,7 @@ static inline void clear_pci_tx_desc_content(__le32 *__pdesc, int _size) · 560 unmodified lines | |||
| 561 | rxmcs == DESC92C_RATE11M) | 561 | rxmcs == DESC92C_RATE11M) |
| 562 | 562 | ||
| 563 | struct phy_status_rpt { | 563 | struct phy_status_rpt { |
| 564 | u8 padding[2]; | ||
| 564 | u8 ch_corr[2]; | 565 | u8 ch_corr[2]; |
| 565 | u8 cck_sig_qual_ofdm_pwdb_all; | 566 | u8 cck_sig_qual_ofdm_pwdb_all; |
| 566 | u8 cck_agc_rpt_ofdm_cfosho_a; | 567 | u8 cck_agc_rpt_ofdm_cfosho_a; |
| @@ -6274,7 +6274,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) · 6273 unmodified lines | |||
| 6274 | wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | | 6274 | wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | |
| 6275 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | 6275 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
| 6276 | WIPHY_FLAG_HAS_CHANNEL_SWITCH | | 6276 | WIPHY_FLAG_HAS_CHANNEL_SWITCH | |
| 6277 | + WIPHY_FLAG_IBSS_RSN; | 6277 | WIPHY_FLAG_IBSS_RSN; |
| 6278 | 6278 | ||
| 6279 | wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN; | 6279 | wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN; |
| 6280 | 6280 | ||
| @@ -184,7 +184,7 @@ static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type) · 183 unmodified lines | |||
| 184 | const struct firmware *fw; | 184 | const struct firmware *fw; |
| 185 | struct sk_buff *skb; | 185 | struct sk_buff *skb; |
| 186 | unsigned long len; | 186 | unsigned long len; |
| 187 | u8 max_size, payload_size; | 187 | int max_size, payload_size; |
| 188 | int rc = 0; | 188 | int rc = 0; |
| 189 | 189 | ||
| 190 | if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) || | 190 | if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) || |
| @@ -207,8 +207,7 @@ static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type) · 16 unmodified lines | |||
| 207 | 207 | ||
| 208 | while (len) { | 208 | while (len) { |
| 209 | 209 | ||
| 210 | payload_size = min_t(unsigned long, (unsigned long) max_size, | 210 | payload_size = min_t(unsigned long, max_size, len); |
| 211 | len); | ||
| 212 | 211 | ||
| 213 | skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size), | 212 | skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size), |
| 214 | GFP_KERNEL); | 213 | GFP_KERNEL); |
| @@ -850,9 +850,11 @@ out_free_tagset: · 849 unmodified lines | |||
| 850 | if (new) | 850 | if (new) |
| 851 | blk_mq_free_tag_set(ctrl->ctrl.admin_tagset); | 851 | blk_mq_free_tag_set(ctrl->ctrl.admin_tagset); |
| 852 | out_free_async_qe: | 852 | out_free_async_qe: |
| 853 | nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, | 853 | if (ctrl->async_event_sqe.data) { |
| 854 | sizeof(struct nvme_command), DMA_TO_DEVICE); | 854 | nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, |
| 855 | ctrl->async_event_sqe.data = NULL; | 855 | sizeof(struct nvme_command), DMA_TO_DEVICE); |
| 856 | ctrl->async_event_sqe.data = NULL; | ||
| 857 | } | ||
| 856 | out_free_queue: | 858 | out_free_queue: |
| 857 | nvme_rdma_free_queue(&ctrl->queues[0]); | 859 | nvme_rdma_free_queue(&ctrl->queues[0]); |
| 858 | return error; | 860 | return error; |
| @@ -515,7 +515,7 @@ static int nvmet_try_send_data_pdu(struct nvmet_tcp_cmd *cmd) · 514 unmodified lines | |||
| 515 | return 1; | 515 | return 1; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd) | 518 | static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd, bool last_in_batch) |
| 519 | { | 519 | { |
| 520 | struct nvmet_tcp_queue *queue = cmd->queue; | 520 | struct nvmet_tcp_queue *queue = cmd->queue; |
| 521 | int ret; | 521 | int ret; |
| @@ -523,9 +523,15 @@ static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd) · 1 unmodified line | |||
| 523 | while (cmd->cur_sg) { | 523 | while (cmd->cur_sg) { |
| 524 | struct page *page = sg_page(cmd->cur_sg); | 524 | struct page *page = sg_page(cmd->cur_sg); |
| 525 | u32 left = cmd->cur_sg->length - cmd->offset; | 525 | u32 left = cmd->cur_sg->length - cmd->offset; |
| 526 | int flags = MSG_DONTWAIT; | ||
| 527 | |||
| 528 | if ((!last_in_batch && cmd->queue->send_list_len) || | ||
| 529 | cmd->wbytes_done + left < cmd->req.transfer_len || | ||
| 530 | queue->data_digest || !queue->nvme_sq.sqhd_disabled) | ||
| 531 | flags |= MSG_MORE; | ||
| 526 | 532 | ||
| 527 | ret = kernel_sendpage(cmd->queue->sock, page, cmd->offset, | 533 | ret = kernel_sendpage(cmd->queue->sock, page, cmd->offset, |
| 528 | left, MSG_DONTWAIT | MSG_MORE); | 534 | left, flags); |
| 529 | if (ret <= 0) | 535 | if (ret <= 0) |
| 530 | return ret; | 536 | return ret; |
| 531 | 537 | ||
| @@ -660,7 +666,7 @@ static int nvmet_tcp_try_send_one(struct nvmet_tcp_queue *queue, · 128 unmodified lines | |||
| 660 | } | 666 | } |
| 661 | 667 | ||
| 662 | if (cmd->state == NVMET_TCP_SEND_DATA) { | 668 | if (cmd->state == NVMET_TCP_SEND_DATA) { |
| 663 | ret = nvmet_try_send_data(cmd); | 669 | ret = nvmet_try_send_data(cmd, last_in_batch); |
| 664 | if (ret <= 0) | 670 | if (ret <= 0) |
| 665 | goto done_send; | 671 | goto done_send; |
| 666 | } | 672 | } |
| @@ -327,6 +327,7 @@ config RTC_DRV_MAX6900 · 326 unmodified lines | |||
| 327 | config RTC_DRV_MAX8907 | 327 | config RTC_DRV_MAX8907 |
| 328 | tristate "Maxim MAX8907" | 328 | tristate "Maxim MAX8907" |
| 329 | depends on MFD_MAX8907 || COMPILE_TEST | 329 | depends on MFD_MAX8907 || COMPILE_TEST |
| 330 | select REGMAP_IRQ | ||
| 330 | help | 331 | help |
| 331 | If you say yes here you will get support for the | 332 | If you say yes here you will get support for the |
| 332 | RTC of Maxim MAX8907 PMIC. | 333 | RTC of Maxim MAX8907 PMIC. |
| @@ -178,6 +178,8 @@ struct dasd_block *dasd_alloc_block(void) · 177 unmodified lines | |||
| 178 | (unsigned long) block); | 178 | (unsigned long) block); |
| 179 | INIT_LIST_HEAD(&block->ccw_queue); | 179 | INIT_LIST_HEAD(&block->ccw_queue); |
| 180 | spin_lock_init(&block->queue_lock); | 180 | spin_lock_init(&block->queue_lock); |
| 181 | INIT_LIST_HEAD(&block->format_list); | ||
| 182 | spin_lock_init(&block->format_lock); | ||
| 181 | timer_setup(&block->timer, dasd_block_timeout, 0); | 183 | timer_setup(&block->timer, dasd_block_timeout, 0); |
| 182 | spin_lock_init(&block->profile.lock); | 184 | spin_lock_init(&block->profile.lock); |
| 183 | 185 | ||
| @@ -1779,20 +1781,26 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, · 1595 unmodified lines | |||
| 1779 | 1781 | ||
| 1780 | if (dasd_ese_needs_format(cqr->block, irb)) { | 1782 | if (dasd_ese_needs_format(cqr->block, irb)) { |
| 1781 | if (rq_data_dir((struct request *)cqr->callback_data) == READ) { | 1783 | if (rq_data_dir((struct request *)cqr->callback_data) == READ) { |
| 1782 | device->discipline->ese_read(cqr); | 1784 | device->discipline->ese_read(cqr, irb); |
| 1783 | cqr->status = DASD_CQR_SUCCESS; | 1785 | cqr->status = DASD_CQR_SUCCESS; |
| 1784 | cqr->stopclk = now; | 1786 | cqr->stopclk = now; |
| 1785 | dasd_device_clear_timer(device); | 1787 | dasd_device_clear_timer(device); |
| 1786 | dasd_schedule_device_bh(device); | 1788 | dasd_schedule_device_bh(device); |
| 1787 | return; | 1789 | return; |
| 1788 | } | 1790 | } |
| 1789 | fcqr = device->discipline->ese_format(device, cqr); | 1791 | fcqr = device->discipline->ese_format(device, cqr, irb); |
| 1790 | if (IS_ERR(fcqr)) { | 1792 | if (IS_ERR(fcqr)) { |
| 1793 | if (PTR_ERR(fcqr) == -EINVAL) { | ||
| 1794 | cqr->status = DASD_CQR_ERROR; | ||
| 1795 | return; | ||
| 1796 | } | ||
| 1791 | /* | 1797 | /* |
| 1792 | * If we can't format now, let the request go | 1798 | * If we can't format now, let the request go |
| 1793 | * one extra round. Maybe we can format later. | 1799 | * one extra round. Maybe we can format later. |
| 1794 | */ | 1800 | */ |
| 1795 | cqr->status = DASD_CQR_QUEUED; | 1801 | cqr->status = DASD_CQR_QUEUED; |
| 1802 | dasd_schedule_device_bh(device); | ||
| 1803 | return; | ||
| 1796 | } else { | 1804 | } else { |
| 1797 | fcqr->status = DASD_CQR_QUEUED; | 1805 | fcqr->status = DASD_CQR_QUEUED; |
| 1798 | cqr->status = DASD_CQR_QUEUED; | 1806 | cqr->status = DASD_CQR_QUEUED; |
| @@ -2748,11 +2756,13 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) · 949 unmodified lines | |||
| 2748 | { | 2756 | { |
| 2749 | struct request *req; | 2757 | struct request *req; |
| 2750 | blk_status_t error = BLK_STS_OK; | 2758 | blk_status_t error = BLK_STS_OK; |
| 2759 | unsigned int proc_bytes; | ||
| 2751 | int status; | 2760 | int status; |
| 2752 | 2761 | ||
| 2753 | req = (struct request *) cqr->callback_data; | 2762 | req = (struct request *) cqr->callback_data; |
| 2754 | dasd_profile_end(cqr->block, cqr, req); | 2763 | dasd_profile_end(cqr->block, cqr, req); |
| 2755 | 2764 | ||
| 2765 | proc_bytes = cqr->proc_bytes; | ||
| 2756 | status = cqr->block->base->discipline->free_cp(cqr, req); | 2766 | status = cqr->block->base->discipline->free_cp(cqr, req); |
| 2757 | if (status < 0) | 2767 | if (status < 0) |
| 2758 | error = errno_to_blk_status(status); | 2768 | error = errno_to_blk_status(status); |
| @@ -2783,7 +2793,18 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) · 24 unmodified lines | |||
| 2783 | blk_mq_end_request(req, error); | 2793 | blk_mq_end_request(req, error); |
| 2784 | blk_mq_run_hw_queues(req->q, true); | 2794 | blk_mq_run_hw_queues(req->q, true); |
| 2785 | } else { | 2795 | } else { |
| 2786 | blk_mq_complete_request(req); | 2796 | /* |
| 2797 | * Partial completed requests can happen with ESE devices. | ||
| 2798 | * During read we might have gotten a NRF error and have to | ||
| 2799 | * complete a request partially. | ||
| 2800 | */ | ||
| 2801 | if (proc_bytes) { | ||
| 2802 | blk_update_request(req, BLK_STS_OK, | ||
| 2803 | blk_rq_bytes(req) - proc_bytes); | ||
| 2804 | blk_mq_requeue_request(req, true); | ||
| 2805 | } else { | ||
| 2806 | blk_mq_complete_request(req); | ||
| 2807 | } | ||
| 2787 | } | 2808 | } |
| 2788 | } | 2809 | } |
| 2789 | 2810 | ||
| @@ -207,6 +207,45 @@ static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head) · 206 unmodified lines | |||
| 207 | geo->head |= head; | 207 | geo->head |= head; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | /* | ||
| 211 | * calculate failing track from sense data depending if | ||
| 212 | * it is an EAV device or not | ||
| 213 | */ | ||
| 214 | static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device, | ||
| 215 | sector_t *track) | ||
| 216 | { | ||
| 217 | struct dasd_eckd_private *private = device->private; | ||
| 218 | u8 *sense = NULL; | ||
| 219 | u32 cyl; | ||
| 220 | u8 head; | ||
| 221 | |||
| 222 | sense = dasd_get_sense(irb); | ||
| 223 | if (!sense) { | ||
| 224 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | ||
| 225 | "ESE error no sense data\n"); | ||
| 226 | return -EINVAL; | ||
| 227 | } | ||
| 228 | if (!(sense[27] & DASD_SENSE_BIT_2)) { | ||
| 229 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | ||
| 230 | "ESE error no valid track data\n"); | ||
| 231 | return -EINVAL; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (sense[27] & DASD_SENSE_BIT_3) { | ||
| 235 | /* enhanced addressing */ | ||
| 236 | cyl = sense[30] << 20; | ||
| 237 | cyl |= (sense[31] & 0xF0) << 12; | ||
| 238 | cyl |= sense[28] << 8; | ||
| 239 | cyl |= sense[29]; | ||
| 240 | } else { | ||
| 241 | cyl = sense[29] << 8; | ||
| 242 | cyl |= sense[30]; | ||
| 243 | } | ||
| 244 | head = sense[31] & 0x0F; | ||
| 245 | *track = cyl * private->rdc_data.trk_per_cyl + head; | ||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 210 | static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, | 249 | static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, |
| 211 | struct dasd_device *device) | 250 | struct dasd_device *device) |
| 212 | { | 251 | { |
| @@ -2986,6 +3025,37 @@ static int dasd_eckd_format_device(struct dasd_device *base, · 2773 unmodified lines | |||
| 2986 | 0, NULL); | 3025 | 0, NULL); |
| 2987 | } | 3026 | } |
| 2988 | 3027 | ||
| 3028 | static bool test_and_set_format_track(struct dasd_format_entry *to_format, | ||
| 3029 | struct dasd_block *block) | ||
| 3030 | { | ||
| 3031 | struct dasd_format_entry *format; | ||
| 3032 | unsigned long flags; | ||
| 3033 | bool rc = false; | ||
| 3034 | |||
| 3035 | spin_lock_irqsave(&block->format_lock, flags); | ||
| 3036 | list_for_each_entry(format, &block->format_list, list) { | ||
| 3037 | if (format->track == to_format->track) { | ||
| 3038 | rc = true; | ||
| 3039 | goto out; | ||
| 3040 | } | ||
| 3041 | } | ||
| 3042 | list_add_tail(&to_format->list, &block->format_list); | ||
| 3043 | |||
| 3044 | out: | ||
| 3045 | spin_unlock_irqrestore(&block->format_lock, flags); | ||
| 3046 | return rc; | ||
| 3047 | } | ||
| 3048 | |||
| 3049 | static void clear_format_track(struct dasd_format_entry *format, | ||
| 3050 | struct dasd_block *block) | ||
| 3051 | { | ||
| 3052 | unsigned long flags; | ||
| 3053 | |||
| 3054 | spin_lock_irqsave(&block->format_lock, flags); | ||
| 3055 | list_del_init(&format->list); | ||
| 3056 | spin_unlock_irqrestore(&block->format_lock, flags); | ||
| 3057 | } | ||
| 3058 | |||
| 2989 | /* | 3059 | /* |
| 2990 | * Callback function to free ESE format requests. | 3060 | * Callback function to free ESE format requests. |
| 2991 | */ | 3061 | */ |
| @@ -2993,15 +3063,19 @@ static void dasd_eckd_ese_format_cb(struct dasd_ccw_req *cqr, void *data) · 1 unmodified line | |||
| 2993 | { | 3063 | { |
| 2994 | struct dasd_device *device = cqr->startdev; | 3064 | struct dasd_device *device = cqr->startdev; |
| 2995 | struct dasd_eckd_private *private = device->private; | 3065 | struct dasd_eckd_private *private = device->private; |
| 3066 | struct dasd_format_entry *format = data; | ||
| 2996 | 3067 | ||
| 3068 | clear_format_track(format, cqr->basedev->block); | ||
| 2997 | private->count--; | 3069 | private->count--; |
| 2998 | dasd_ffree_request(cqr, device); | 3070 | dasd_ffree_request(cqr, device); |
| 2999 | } | 3071 | } |
| 3000 | 3072 | ||
| 3001 | static struct dasd_ccw_req * | 3073 | static struct dasd_ccw_req * |
| 3002 | dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) | 3074 | dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, |
| 3075 | struct irb *irb) | ||
| 3003 | { | 3076 | { |
| 3004 | struct dasd_eckd_private *private; | 3077 | struct dasd_eckd_private *private; |
| 3078 | struct dasd_format_entry *format; | ||
| 3005 | struct format_data_t fdata; | 3079 | struct format_data_t fdata; |
| 3006 | unsigned int recs_per_trk; | 3080 | unsigned int recs_per_trk; |
| 3007 | struct dasd_ccw_req *fcqr; | 3081 | struct dasd_ccw_req *fcqr; |
| @@ -3011,23 +3085,39 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) · 3 unmodified lines | |||
| 3011 | struct request *req; | 3085 | struct request *req; |
| 3012 | sector_t first_trk; | 3086 | sector_t first_trk; |
| 3013 | sector_t last_trk; | 3087 | sector_t last_trk; |
| 3088 | sector_t curr_trk; | ||
| 3014 | int rc; | 3089 | int rc; |
| 3015 | 3090 | ||
| 3016 | req = cqr->callback_data; | 3091 | req = cqr->callback_data; |
| 3017 | base = cqr->block->base; | 3092 | block = cqr->block; |
| 3093 | base = block->base; | ||
| 3018 | private = base->private; | 3094 | private = base->private; |
| 3019 | block = base->block; | ||
| 3020 | blksize = block->bp_block; | 3095 | blksize = block->bp_block; |
| 3021 | recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | 3096 | recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
| 3097 | format = &startdev->format_entry; | ||
| 3022 | 3098 | ||
| 3023 | first_trk = blk_rq_pos(req) >> block->s2b_shift; | 3099 | first_trk = blk_rq_pos(req) >> block->s2b_shift; |
| 3024 | sector_div(first_trk, recs_per_trk); | 3100 | sector_div(first_trk, recs_per_trk); |
| 3025 | last_trk = | 3101 | last_trk = |
| 3026 | (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; | 3102 | (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; |
| 3027 | sector_div(last_trk, recs_per_trk); | 3103 | sector_div(last_trk, recs_per_trk); |
| 3104 | rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); | ||
| 3105 | if (rc) | ||
| 3106 | return ERR_PTR(rc); | ||
| 3028 | 3107 | ||
| 3029 | fdata.start_unit = first_trk; | 3108 | if (curr_trk < first_trk || curr_trk > last_trk) { |
| 3030 | fdata.stop_unit = last_trk; | 3109 | DBF_DEV_EVENT(DBF_WARNING, startdev, |
| 3110 | "ESE error track %llu not within range %llu - %llu\n", | ||
| 3111 | curr_trk, first_trk, last_trk); | ||
| 3112 | return ERR_PTR(-EINVAL); | ||
| 3113 | } | ||
| 3114 | format->track = curr_trk; | ||
| 3115 | /* test if track is already in formatting by another thread */ | ||
| 3116 | if (test_and_set_format_track(format, block)) | ||
| 3117 | return ERR_PTR(-EEXIST); | ||
| 3118 | |||
| 3119 | fdata.start_unit = curr_trk; | ||
| 3120 | fdata.stop_unit = curr_trk; | ||
| 3031 | fdata.blksize = blksize; | 3121 | fdata.blksize = blksize; |
| 3032 | fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0; | 3122 | fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0; |
| 3033 | 3123 | ||
| @@ -3044,6 +3134,7 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) · 10 unmodified lines | |||
| 3044 | return fcqr; | 3134 | return fcqr; |
| 3045 | 3135 | ||
| 3046 | fcqr->callback = dasd_eckd_ese_format_cb; | 3136 | fcqr->callback = dasd_eckd_ese_format_cb; |
| 3137 | fcqr->callback_data = (void *) format; | ||
| 3047 | 3138 | ||
| 3048 | return fcqr; | 3139 | return fcqr; |
| 3049 | } | 3140 | } |
| @@ -3051,29 +3142,87 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) · 1 unmodified line | |||
| 3051 | /* | 3142 | /* |
| 3052 | * When data is read from an unformatted area of an ESE volume, this function | 3143 | * When data is read from an unformatted area of an ESE volume, this function |
| 3053 | * returns zeroed data and thereby mimics a read of zero data. | 3144 | * returns zeroed data and thereby mimics a read of zero data. |
| 3145 | * | ||
| 3146 | * The first unformatted track is the one that got the NRF error, the address is | ||
| 3147 | * encoded in the sense data. | ||
| 3148 | * | ||
| 3149 | * All tracks before have returned valid data and should not be touched. | ||
| 3150 | * All tracks after the unformatted track might be formatted or not. This is | ||
| 3151 | * currently not known, remember the processed data and return the remainder of | ||
| 3152 | * the request to the blocklayer in __dasd_cleanup_cqr(). | ||
| 3054 | */ | 3153 | */ |
| 3055 | static void dasd_eckd_ese_read(struct dasd_ccw_req *cqr) | 3154 | static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb) |
| 3056 | { | 3155 | { |
| 3156 | struct dasd_eckd_private *private; | ||
| 3157 | sector_t first_trk, last_trk; | ||
| 3158 | sector_t first_blk, last_blk; | ||
| 3057 | unsigned int blksize, off; | 3159 | unsigned int blksize, off; |
| 3160 | unsigned int recs_per_trk; | ||
| 3058 | struct dasd_device *base; | 3161 | struct dasd_device *base; |
| 3059 | struct req_iterator iter; | 3162 | struct req_iterator iter; |
| 3163 | struct dasd_block *block; | ||
| 3164 | unsigned int skip_block; | ||
| 3165 | unsigned int blk_count; | ||
| 3060 | struct request *req; | 3166 | struct request *req; |
| 3061 | struct bio_vec bv; | 3167 | struct bio_vec bv; |
| 3168 | sector_t curr_trk; | ||
| 3169 | sector_t end_blk; | ||
| 3062 | char *dst; | 3170 | char *dst; |
| 3171 | int rc; | ||
| 3063 | 3172 | ||
| 3064 | req = (struct request *) cqr->callback_data; | 3173 | req = (struct request *) cqr->callback_data; |
| 3065 | base = cqr->block->base; | 3174 | base = cqr->block->base; |
| 3066 | blksize = base->block->bp_block; | 3175 | blksize = base->block->bp_block; |
| 3176 | block = cqr->block; | ||
| 3177 | private = base->private; | ||
| 3178 | skip_block = 0; | ||
| 3179 | blk_count = 0; | ||
| 3180 | |||
| 3181 | recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | ||
| 3182 | first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift; | ||
| 3183 | sector_div(first_trk, recs_per_trk); | ||
| 3184 | last_trk = last_blk = | ||
| 3185 | (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; | ||
| 3186 | sector_div(last_trk, recs_per_trk); | ||
| 3187 | rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); | ||
| 3188 | if (rc) | ||
| 3189 | return rc; | ||
| 3190 | |||
| 3191 | /* sanity check if the current track from sense data is valid */ | ||
| 3192 | if (curr_trk < first_trk || curr_trk > last_trk) { | ||
| 3193 | DBF_DEV_EVENT(DBF_WARNING, base, | ||
| 3194 | "ESE error track %llu not within range %llu - %llu\n", | ||
| 3195 | curr_trk, first_trk, last_trk); | ||
| 3196 | return -EINVAL; | ||
| 3197 | } | ||
| 3198 | |||
| 3199 | /* | ||
| 3200 | * if not the first track got the NRF error we have to skip over valid | ||
| 3201 | * blocks | ||
| 3202 | */ | ||
| 3203 | if (curr_trk != first_trk) | ||
| 3204 | skip_block = curr_trk * recs_per_trk - first_blk; | ||
| 3205 | |||
| 3206 | /* we have no information beyond the current track */ | ||
| 3207 | end_blk = (curr_trk + 1) * recs_per_trk; | ||
| 3067 | 3208 | ||
| 3068 | rq_for_each_segment(bv, req, iter) { | 3209 | rq_for_each_segment(bv, req, iter) { |
| 3069 | dst = page_address(bv.bv_page) + bv.bv_offset; | 3210 | dst = page_address(bv.bv_page) + bv.bv_offset; |
| 3070 | for (off = 0; off < bv.bv_len; off += blksize) { | 3211 | for (off = 0; off < bv.bv_len; off += blksize) { |
| 3071 | if (dst && rq_data_dir(req) == READ) { | 3212 | if (first_blk + blk_count >= end_blk) { |
| 3213 | cqr->proc_bytes = blk_count * blksize; | ||
| 3214 | return 0; | ||
| 3215 | } | ||
| 3216 | if (dst && !skip_block) { | ||
| 3072 | dst += off; | 3217 | dst += off; |
| 3073 | memset(dst, 0, blksize); | 3218 | memset(dst, 0, blksize); |
| 3219 | } else { | ||
| 3220 | skip_block--; | ||
| 3074 | } | 3221 | } |
| 3222 | blk_count++; | ||
| 3075 | } | 3223 | } |
| 3076 | } | 3224 | } |
| 3225 | return 0; | ||
| 3077 | } | 3226 | } |
| 3078 | 3227 | ||
| 3079 | /* | 3228 | /* |
| @@ -187,6 +187,7 @@ struct dasd_ccw_req { · 186 unmodified lines | |||
| 187 | 187 | ||
| 188 | void (*callback)(struct dasd_ccw_req *, void *data); | 188 | void (*callback)(struct dasd_ccw_req *, void *data); |
| 189 | void *callback_data; | 189 | void *callback_data; |
| 190 | unsigned int proc_bytes; /* bytes for partial completion */ | ||
| 190 | }; | 191 | }; |
| 191 | 192 | ||
| 192 | /* | 193 | /* |
| @@ -387,8 +388,9 @@ struct dasd_discipline { · 194 unmodified lines | |||
| 387 | int (*ext_pool_warn_thrshld)(struct dasd_device *); | 388 | int (*ext_pool_warn_thrshld)(struct dasd_device *); |
| 388 | int (*ext_pool_oos)(struct dasd_device *); | 389 | int (*ext_pool_oos)(struct dasd_device *); |
| 389 | int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); | 390 | int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); |
| 390 | struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *); | 391 | struct dasd_ccw_req *(*ese_format)(struct dasd_device *, |
| 391 | void (*ese_read)(struct dasd_ccw_req *); | 392 | struct dasd_ccw_req *, struct irb *); |
| 393 | int (*ese_read)(struct dasd_ccw_req *, struct irb *); | ||
| 392 | }; | 394 | }; |
| 393 | 395 | ||
| 394 | extern struct dasd_discipline *dasd_diag_discipline_pointer; | 396 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
| @@ -474,6 +476,11 @@ struct dasd_profile { · 79 unmodified lines | |||
| 474 | spinlock_t lock; | 476 | spinlock_t lock; |
| 475 | }; | 477 | }; |
| 476 | 478 | ||
| 479 | struct dasd_format_entry { | ||
| 480 | struct list_head list; | ||
| 481 | sector_t track; | ||
| 482 | }; | ||
| 483 | |||
| 477 | struct dasd_device { | 484 | struct dasd_device { |
| 478 | /* Block device stuff. */ | 485 | /* Block device stuff. */ |
| 479 | struct dasd_block *block; | 486 | struct dasd_block *block; |
| @@ -539,6 +546,7 @@ struct dasd_device { · 59 unmodified lines | |||
| 539 | struct dentry *debugfs_dentry; | 546 | struct dentry *debugfs_dentry; |
| 540 | struct dentry *hosts_dentry; | 547 | struct dentry *hosts_dentry; |
| 541 | struct dasd_profile profile; | 548 | struct dasd_profile profile; |
| 549 | struct dasd_format_entry format_entry; | ||
| 542 | }; | 550 | }; |
| 543 | 551 | ||
| 544 | struct dasd_block { | 552 | struct dasd_block { |
| @@ -564,6 +572,9 @@ struct dasd_block { · 19 unmodified lines | |||
| 564 | 572 | ||
| 565 | struct dentry *debugfs_dentry; | 573 | struct dentry *debugfs_dentry; |
| 566 | struct dasd_profile profile; | 574 | struct dasd_profile profile; |
| 575 | |||
| 576 | struct list_head format_list; | ||
| 577 | spinlock_t format_lock; | ||
| 567 | }; | 578 | }; |
| 568 | 579 | ||
| 569 | struct dasd_attention_data { | 580 | struct dasd_attention_data { |
| @@ -9950,6 +9950,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, · 9949 unmodified lines | |||
| 9950 | ioa_cfg->max_devs_supported = ipr_max_devs; | 9950 | ioa_cfg->max_devs_supported = ipr_max_devs; |
| 9951 | 9951 | ||
| 9952 | if (ioa_cfg->sis64) { | 9952 | if (ioa_cfg->sis64) { |
| 9953 | host->max_channel = IPR_MAX_SIS64_BUSES; | ||
| 9953 | host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; | 9954 | host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; |
| 9954 | host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; | 9955 | host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; |
| 9955 | if (ipr_max_devs > IPR_MAX_SIS64_DEVS) | 9956 | if (ipr_max_devs > IPR_MAX_SIS64_DEVS) |
| @@ -9958,6 +9959,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, · 2 unmodified lines | |||
| 9958 | + ((sizeof(struct ipr_config_table_entry64) | 9959 | + ((sizeof(struct ipr_config_table_entry64) |
| 9959 | * ioa_cfg->max_devs_supported))); | 9960 | * ioa_cfg->max_devs_supported))); |
| 9960 | } else { | 9961 | } else { |
| 9962 | host->max_channel = IPR_VSET_BUS; | ||
| 9961 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; | 9963 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; |
| 9962 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; | 9964 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; |
| 9963 | if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) | 9965 | if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) |
| @@ -9967,7 +9969,6 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, · 3 unmodified lines | |||
| 9967 | * ioa_cfg->max_devs_supported))); | 9969 | * ioa_cfg->max_devs_supported))); |
| 9968 | } | 9970 | } |
| 9969 | 9971 | ||
| 9970 | host->max_channel = IPR_VSET_BUS; | ||
| 9971 | host->unique_id = host->host_no; | 9972 | host->unique_id = host->host_no; |
| 9972 | host->max_cmd_len = IPR_MAX_CDB_LEN; | 9973 | host->max_cmd_len = IPR_MAX_CDB_LEN; |
| 9973 | host->can_queue = ioa_cfg->max_cmds; | 9974 | host->can_queue = ioa_cfg->max_cmds; |
| @@ -1300,6 +1300,7 @@ struct ipr_resource_entry { · 1299 unmodified lines | |||
| 1300 | #define IPR_ARRAY_VIRTUAL_BUS 0x1 | 1300 | #define IPR_ARRAY_VIRTUAL_BUS 0x1 |
| 1301 | #define IPR_VSET_VIRTUAL_BUS 0x2 | 1301 | #define IPR_VSET_VIRTUAL_BUS 0x2 |
| 1302 | #define IPR_IOAFP_VIRTUAL_BUS 0x3 | 1302 | #define IPR_IOAFP_VIRTUAL_BUS 0x3 |
| 1303 | #define IPR_MAX_SIS64_BUSES 0x4 | ||
| 1303 | 1304 | ||
| 1304 | #define IPR_GET_RES_PHYS_LOC(res) \ | 1305 | #define IPR_GET_RES_PHYS_LOC(res) \ |
| 1305 | (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) | 1306 | (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) |
| @@ -3884,18 +3884,25 @@ EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_exit); · 3883 unmodified lines | |||
| 3884 | void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) | 3884 | void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) |
| 3885 | { | 3885 | { |
| 3886 | unsigned long flags; | 3886 | unsigned long flags; |
| 3887 | bool update = false; | ||
| 3887 | 3888 | ||
| 3888 | if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) | 3889 | if (!ufshcd_is_auto_hibern8_supported(hba)) |
| 3889 | return; | 3890 | return; |
| 3890 | 3891 | ||
| 3891 | spin_lock_irqsave(hba->host->host_lock, flags); | 3892 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 3892 | if (hba->ahit == ahit) | 3893 | if (hba->ahit != ahit) { |
| 3893 | goto out_unlock; | 3894 | hba->ahit = ahit; |
| 3894 | hba->ahit = ahit; | 3895 | update = true; |
| 3895 | if (!pm_runtime_suspended(hba->dev)) | 3896 | } |
| 3896 | ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); | ||
| 3897 | out_unlock: | ||
| 3898 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 3897 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 3898 | |||
| 3899 | if (update && !pm_runtime_suspended(hba->dev)) { | ||
| 3900 | pm_runtime_get_sync(hba->dev); | ||
| 3901 | ufshcd_hold(hba, false); | ||
| 3902 | ufshcd_auto_hibern8_enable(hba); | ||
| 3903 | ufshcd_release(hba); | ||
| 3904 | pm_runtime_put(hba->dev); | ||
| 3905 | } | ||
| 3899 | } | 3906 | } |
| 3900 | EXPORT_SYMBOL_GPL(ufshcd_auto_hibern8_update); | 3907 | EXPORT_SYMBOL_GPL(ufshcd_auto_hibern8_update); |
| 3901 | 3908 | ||
| @@ -1320,6 +1320,9 @@ static const struct of_device_id qcom_slim_ngd_dt_match[] = { · 1319 unmodified lines | |||
| 1320 | { | 1320 | { |
| 1321 | .compatible = "qcom,slim-ngd-v1.5.0", | 1321 | .compatible = "qcom,slim-ngd-v1.5.0", |
| 1322 | .data = &ngd_v1_5_offset_info, | 1322 | .data = &ngd_v1_5_offset_info, |
| 1323 | },{ | ||
| 1324 | .compatible = "qcom,slim-ngd-v2.1.0", | ||
| 1325 | .data = &ngd_v1_5_offset_info, | ||
| 1323 | }, | 1326 | }, |
| 1324 | {} | 1327 | {} |
| 1325 | }; | 1328 | }; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <signal.h> | 19 | #include <signal.h> |
| 20 | 20 | ||
| 21 | #define MAX_NUM_DEVICES 10 | 21 | #define MAX_NUM_DEVICES 10 |
| 22 | #define MAX_SYSFS_PREFIX 0x80 | ||
| 22 | #define MAX_SYSFS_PATH 0x200 | 23 | #define MAX_SYSFS_PATH 0x200 |
| 23 | #define CSV_MAX_LINE 0x1000 | 24 | #define CSV_MAX_LINE 0x1000 |
| 24 | #define SYSFS_MAX_INT 0x20 | 25 | #define SYSFS_MAX_INT 0x20 |
| @@ -67,7 +68,7 @@ struct loopback_results { · 42 unmodified lines | |||
| 67 | }; | 68 | }; |
| 68 | 69 | ||
| 69 | struct loopback_device { | 70 | struct loopback_device { |
| 70 | char name[MAX_SYSFS_PATH]; | 71 | char name[MAX_STR_LEN]; |
| 71 | char sysfs_entry[MAX_SYSFS_PATH]; | 72 | char sysfs_entry[MAX_SYSFS_PATH]; |
| 72 | char debugfs_entry[MAX_SYSFS_PATH]; | 73 | char debugfs_entry[MAX_SYSFS_PATH]; |
| 73 | struct loopback_results results; | 74 | struct loopback_results results; |
| @@ -93,8 +94,8 @@ struct loopback_test { · 19 unmodified lines | |||
| 93 | int stop_all; | 94 | int stop_all; |
| 94 | int poll_count; | 95 | int poll_count; |
| 95 | char test_name[MAX_STR_LEN]; | 96 | char test_name[MAX_STR_LEN]; |
| 96 | char sysfs_prefix[MAX_SYSFS_PATH]; | 97 | char sysfs_prefix[MAX_SYSFS_PREFIX]; |
| 97 | char debugfs_prefix[MAX_SYSFS_PATH]; | 98 | char debugfs_prefix[MAX_SYSFS_PREFIX]; |
| 98 | struct timespec poll_timeout; | 99 | struct timespec poll_timeout; |
| 99 | struct loopback_device devices[MAX_NUM_DEVICES]; | 100 | struct loopback_device devices[MAX_NUM_DEVICES]; |
| 100 | struct loopback_results aggregate_results; | 101 | struct loopback_results aggregate_results; |
| @@ -637,7 +638,7 @@ baddir: · 536 unmodified lines | |||
| 637 | static int open_poll_files(struct loopback_test *t) | 638 | static int open_poll_files(struct loopback_test *t) |
| 638 | { | 639 | { |
| 639 | struct loopback_device *dev; | 640 | struct loopback_device *dev; |
| 640 | char buf[MAX_STR_LEN]; | 641 | char buf[MAX_SYSFS_PATH + MAX_STR_LEN]; |
| 641 | char dummy; | 642 | char dummy; |
| 642 | int fds_idx = 0; | 643 | int fds_idx = 0; |
| 643 | int i; | 644 | int i; |
| @@ -655,7 +656,7 @@ static int open_poll_files(struct loopback_test *t) · 11 unmodified lines | |||
| 655 | goto err; | 656 | goto err; |
| 656 | } | 657 | } |
| 657 | read(t->fds[fds_idx].fd, &dummy, 1); | 658 | read(t->fds[fds_idx].fd, &dummy, 1); |
| 658 | t->fds[fds_idx].events = EPOLLERR|EPOLLPRI; | 659 | t->fds[fds_idx].events = POLLERR | POLLPRI; |
| 659 | t->fds[fds_idx].revents = 0; | 660 | t->fds[fds_idx].revents = 0; |
| 660 | fds_idx++; | 661 | fds_idx++; |
| 661 | } | 662 | } |
| @@ -748,7 +749,7 @@ static int wait_for_complete(struct loopback_test *t) · 86 unmodified lines | |||
| 748 | } | 749 | } |
| 749 | 750 | ||
| 750 | for (i = 0; i < t->poll_count; i++) { | 751 | for (i = 0; i < t->poll_count; i++) { |
| 751 | if (t->fds[i].revents & EPOLLPRI) { | 752 | if (t->fds[i].revents & POLLPRI) { |
| 752 | /* Dummy read to clear the event */ | 753 | /* Dummy read to clear the event */ |
| 753 | read(t->fds[i].fd, &dummy, 1); | 754 | read(t->fds[i].fd, &dummy, 1); |
| 754 | number_of_events++; | 755 | number_of_events++; |
| @@ -907,10 +908,10 @@ int main(int argc, char *argv[]) · 152 unmodified lines | |||
| 907 | t.iteration_max = atoi(optarg); | 908 | t.iteration_max = atoi(optarg); |
| 908 | break; | 909 | break; |
| 909 | case 'S': | 910 | case 'S': |
| 910 | snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", optarg); | 911 | snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg); |
| 911 | break; | 912 | break; |
| 912 | case 'D': | 913 | case 'D': |
| 913 | snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", optarg); | 914 | snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg); |
| 914 | break; | 915 | break; |
| 915 | case 'm': | 916 | case 'm': |
| 916 | t.mask = atol(optarg); | 917 | t.mask = atol(optarg); |
| @@ -961,10 +962,10 @@ int main(int argc, char *argv[]) · 44 unmodified lines | |||
| 961 | } | 962 | } |
| 962 | 963 | ||
| 963 | if (!strcmp(t.sysfs_prefix, "")) | 964 | if (!strcmp(t.sysfs_prefix, "")) |
| 964 | snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", sysfs_prefix); | 965 | snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", sysfs_prefix); |
| 965 | 966 | ||
| 966 | if (!strcmp(t.debugfs_prefix, "")) | 967 | if (!strcmp(t.debugfs_prefix, "")) |
| 967 | snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", debugfs_prefix); | 968 | snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", debugfs_prefix); |
| 968 | 969 | ||
| 969 | ret = find_loopback_devices(&t); | 970 | ret = find_loopback_devices(&t); |
| 970 | if (ret) | 971 | if (ret) |
| @@ -38,6 +38,7 @@ static const struct usb_device_id rtw_usb_id_tbl[] = { · 37 unmodified lines | |||
| 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ | 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ |
| 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ | 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ |
| 40 | {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ | 40 | {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ |
| 41 | {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */ | ||
| 41 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ | 42 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ |
| 42 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ | 43 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ |
| 43 | {} /* Terminating entry */ | 44 | {} /* Terminating entry */ |
| @@ -561,7 +561,7 @@ static u_long get_word(struct vc_data *vc) · 560 unmodified lines | |||
| 561 | return 0; | 561 | return 0; |
| 562 | } else if (tmpx < vc->vc_cols - 2 && | 562 | } else if (tmpx < vc->vc_cols - 2 && |
| 563 | (ch == SPACE || ch == 0 || (ch < 0x100 && IS_WDLM(ch))) && | 563 | (ch == SPACE || ch == 0 || (ch < 0x100 && IS_WDLM(ch))) && |
| 564 | get_char(vc, (u_short *)&tmp_pos + 1, &temp) > SPACE) { | 564 | get_char(vc, (u_short *)tmp_pos + 1, &temp) > SPACE) { |
| 565 | tmp_pos += 2; | 565 | tmp_pos += 2; |
| 566 | tmpx++; | 566 | tmpx++; |
| 567 | } else { | 567 | } else { |
| @@ -140,6 +140,7 @@ int hif_shutdown(struct wfx_dev *wdev) · 139 unmodified lines | |||
| 140 | else | 140 | else |
| 141 | control_reg_write(wdev, 0); | 141 | control_reg_write(wdev, 0); |
| 142 | mutex_unlock(&wdev->hif_cmd.lock); | 142 | mutex_unlock(&wdev->hif_cmd.lock); |
| 143 | mutex_unlock(&wdev->hif_cmd.key_renew_lock); | ||
| 143 | kfree(hif); | 144 | kfree(hif); |
| 144 | return ret; | 145 | return ret; |
| 145 | } | 146 | } |
| @@ -289,7 +290,7 @@ int hif_stop_scan(struct wfx_vif *wvif) · 143 unmodified lines | |||
| 289 | } | 290 | } |
| 290 | 291 | ||
| 291 | int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, | 292 | int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, |
| 292 | const struct ieee80211_channel *channel, const u8 *ssidie) | 293 | struct ieee80211_channel *channel, const u8 *ssid, int ssidlen) |
| 293 | { | 294 | { |
| 294 | int ret; | 295 | int ret; |
| 295 | struct hif_msg *hif; | 296 | struct hif_msg *hif; |
| @@ -307,9 +308,9 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, · 11 unmodified lines | |||
| 307 | body->basic_rate_set = | 308 | body->basic_rate_set = |
| 308 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); | 309 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); |
| 309 | memcpy(body->bssid, conf->bssid, sizeof(body->bssid)); | 310 | memcpy(body->bssid, conf->bssid, sizeof(body->bssid)); |
| 310 | if (!conf->ibss_joined && ssidie) { | 311 | if (!conf->ibss_joined && ssid) { |
| 311 | body->ssid_length = cpu_to_le32(ssidie[1]); | 312 | body->ssid_length = cpu_to_le32(ssidlen); |
| 312 | memcpy(body->ssid, &ssidie[2], ssidie[1]); | 313 | memcpy(body->ssid, ssid, ssidlen); |
| 313 | } | 314 | } |
| 314 | wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body)); | 315 | wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body)); |
| 315 | ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); | 316 | ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); |
| @@ -427,9 +428,9 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, · 111 unmodified lines | |||
| 427 | struct hif_msg *hif; | 428 | struct hif_msg *hif; |
| 428 | struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif); | 429 | struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif); |
| 429 | 430 | ||
| 430 | body->dtim_period = conf->dtim_period, | 431 | body->dtim_period = conf->dtim_period; |
| 431 | body->short_preamble = conf->use_short_preamble, | 432 | body->short_preamble = conf->use_short_preamble; |
| 432 | body->channel_number = cpu_to_le16(channel->hw_value), | 433 | body->channel_number = cpu_to_le16(channel->hw_value); |
| 433 | body->beacon_interval = cpu_to_le32(conf->beacon_int); | 434 | body->beacon_interval = cpu_to_le32(conf->beacon_int); |
| 434 | body->basic_rate_set = | 435 | body->basic_rate_set = |
| 435 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); | 436 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); |
| @@ -46,7 +46,7 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211, · 45 unmodified lines | |||
| 46 | int chan_start, int chan_num); | 46 | int chan_start, int chan_num); |
| 47 | int hif_stop_scan(struct wfx_vif *wvif); | 47 | int hif_stop_scan(struct wfx_vif *wvif); |
| 48 | int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, | 48 | int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, |
| 49 | const struct ieee80211_channel *channel, const u8 *ssidie); | 49 | struct ieee80211_channel *channel, const u8 *ssid, int ssidlen); |
| 50 | int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); | 50 | int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); |
| 51 | int hif_set_bss_params(struct wfx_vif *wvif, | 51 | int hif_set_bss_params(struct wfx_vif *wvif, |
| 52 | const struct hif_req_set_bss_params *arg); | 52 | const struct hif_req_set_bss_params *arg); |
| @@ -191,10 +191,10 @@ static inline int hif_set_block_ack_policy(struct wfx_vif *wvif, · 190 unmodified lines | |||
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static inline int hif_set_association_mode(struct wfx_vif *wvif, | 193 | static inline int hif_set_association_mode(struct wfx_vif *wvif, |
| 194 | struct ieee80211_bss_conf *info, | 194 | struct ieee80211_bss_conf *info) |
| 195 | struct ieee80211_sta_ht_cap *ht_cap) | ||
| 196 | { | 195 | { |
| 197 | int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates); | 196 | int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates); |
| 197 | struct ieee80211_sta *sta = NULL; | ||
| 198 | struct hif_mib_set_association_mode val = { | 198 | struct hif_mib_set_association_mode val = { |
| 199 | .preambtype_use = 1, | 199 | .preambtype_use = 1, |
| 200 | .mode = 1, | 200 | .mode = 1, |
| @@ -204,12 +204,17 @@ static inline int hif_set_association_mode(struct wfx_vif *wvif, · 3 unmodified lines | |||
| 204 | .basic_rate_set = cpu_to_le32(basic_rates) | 204 | .basic_rate_set = cpu_to_le32(basic_rates) |
| 205 | }; | 205 | }; |
| 206 | 206 | ||
| 207 | rcu_read_lock(); // protect sta | ||
| 208 | if (info->bssid && !info->ibss_joined) | ||
| 209 | sta = ieee80211_find_sta(wvif->vif, info->bssid); | ||
| 210 | |||
| 207 | // FIXME: it is strange to not retrieve all information from bss_info | 211 | // FIXME: it is strange to not retrieve all information from bss_info |
| 208 | if (ht_cap && ht_cap->ht_supported) { | 212 | if (sta && sta->ht_cap.ht_supported) { |
| 209 | val.mpdu_start_spacing = ht_cap->ampdu_density; | 213 | val.mpdu_start_spacing = sta->ht_cap.ampdu_density; |
| 210 | if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) | 214 | if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) |
| 211 | val.greenfield = !!(ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD); | 215 | val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); |
| 212 | } | 216 | } |
| 217 | rcu_read_unlock(); | ||
| 213 | 218 | ||
| 214 | return hif_write_mib(wvif->wdev, wvif->id, | 219 | return hif_write_mib(wvif->wdev, wvif->id, |
| 215 | HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val)); | 220 | HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val)); |
| @@ -491,9 +491,11 @@ static void wfx_set_mfp(struct wfx_vif *wvif, · 490 unmodified lines | |||
| 491 | static void wfx_do_join(struct wfx_vif *wvif) | 491 | static void wfx_do_join(struct wfx_vif *wvif) |
| 492 | { | 492 | { |
| 493 | int ret; | 493 | int ret; |
| 494 | const u8 *ssidie; | ||
| 495 | struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; | 494 | struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; |
| 496 | struct cfg80211_bss *bss = NULL; | 495 | struct cfg80211_bss *bss = NULL; |
| 496 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
| 497 | const u8 *ssidie = NULL; | ||
| 498 | int ssidlen = 0; | ||
| 497 | 499 | ||
| 498 | wfx_tx_lock_flush(wvif->wdev); | 500 | wfx_tx_lock_flush(wvif->wdev); |
| 499 | 501 | ||
| @@ -514,11 +516,14 @@ static void wfx_do_join(struct wfx_vif *wvif) · 14 unmodified lines | |||
| 514 | if (!wvif->beacon_int) | 516 | if (!wvif->beacon_int) |
| 515 | wvif->beacon_int = 1; | 517 | wvif->beacon_int = 1; |
| 516 | 518 | ||
| 517 | rcu_read_lock(); | 519 | rcu_read_lock(); // protect ssidie |
| 518 | if (!conf->ibss_joined) | 520 | if (!conf->ibss_joined) |
| 519 | ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); | 521 | ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); |
| 520 | else | 522 | if (ssidie) { |
| 521 | ssidie = NULL; | 523 | ssidlen = ssidie[1]; |
| 524 | memcpy(ssid, &ssidie[2], ssidie[1]); | ||
| 525 | } | ||
| 526 | rcu_read_unlock(); | ||
| 522 | 527 | ||
| 523 | wfx_tx_flush(wvif->wdev); | 528 | wfx_tx_flush(wvif->wdev); |
| 524 | 529 | ||
| @@ -527,10 +532,8 @@ static void wfx_do_join(struct wfx_vif *wvif) · 2 unmodified lines | |||
| 527 | 532 | ||
| 528 | wfx_set_mfp(wvif, bss); | 533 | wfx_set_mfp(wvif, bss); |
| 529 | 534 | ||
| 530 | /* Perform actual join */ | ||
| 531 | wvif->wdev->tx_burst_idx = -1; | 535 | wvif->wdev->tx_burst_idx = -1; |
| 532 | ret = hif_join(wvif, conf, wvif->channel, ssidie); | 536 | ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); |
| 533 | rcu_read_unlock(); | ||
| 534 | if (ret) { | 537 | if (ret) { |
| 535 | ieee80211_connection_loss(wvif->vif); | 538 | ieee80211_connection_loss(wvif->vif); |
| 536 | wvif->join_complete_status = -1; | 539 | wvif->join_complete_status = -1; |
| @@ -605,7 +608,9 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 68 unmodified lines | |||
| 605 | int i; | 608 | int i; |
| 606 | 609 | ||
| 607 | for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++) | 610 | for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++) |
| 608 | WARN(sta_priv->buffered[i], "release station while Tx is in progress"); | 611 | if (sta_priv->buffered[i]) |
| 612 | dev_warn(wvif->wdev->dev, "release station while %d pending frame on queue %d", | ||
| 613 | sta_priv->buffered[i], i); | ||
| 609 | // FIXME: see note in wfx_sta_add() | 614 | // FIXME: see note in wfx_sta_add() |
| 610 | if (vif->type == NL80211_IFTYPE_STATION) | 615 | if (vif->type == NL80211_IFTYPE_STATION) |
| 611 | return 0; | 616 | return 0; |
| @@ -689,6 +694,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, · 77 unmodified lines | |||
| 689 | wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]); | 694 | wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]); |
| 690 | else | 695 | else |
| 691 | wvif->bss_params.operational_rate_set = -1; | 696 | wvif->bss_params.operational_rate_set = -1; |
| 697 | rcu_read_unlock(); | ||
| 692 | if (sta && | 698 | if (sta && |
| 693 | info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) | 699 | info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) |
| 694 | hif_dual_cts_protection(wvif, true); | 700 | hif_dual_cts_protection(wvif, true); |
| @@ -701,8 +707,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, · 6 unmodified lines | |||
| 701 | wvif->bss_params.beacon_lost_count = 20; | 707 | wvif->bss_params.beacon_lost_count = 20; |
| 702 | wvif->bss_params.aid = info->aid; | 708 | wvif->bss_params.aid = info->aid; |
| 703 | 709 | ||
| 704 | hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL); | 710 | hif_set_association_mode(wvif, info); |
| 705 | rcu_read_unlock(); | ||
| 706 | 711 | ||
| 707 | if (!info->ibss_joined) { | 712 | if (!info->ibss_joined) { |
| 708 | hif_keep_alive_period(wvif, 30 /* sec */); | 713 | hif_keep_alive_period(wvif, 30 /* sec */); |
| @@ -954,7 +954,7 @@ static bool tb_port_is_width_supported(struct tb_port *port, int width) · 953 unmodified lines | |||
| 954 | ret = tb_port_read(port, &phy, TB_CFG_PORT, | 954 | ret = tb_port_read(port, &phy, TB_CFG_PORT, |
| 955 | port->cap_phy + LANE_ADP_CS_0, 1); | 955 | port->cap_phy + LANE_ADP_CS_0, 1); |
| 956 | if (ret) | 956 | if (ret) |
| 957 | return ret; | 957 | return false; |
| 958 | 958 | ||
| 959 | widths = (phy & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> | 959 | widths = (phy & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> |
| 960 | LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT; | 960 | LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT; |
| @@ -1589,9 +1589,7 @@ void tty_kclose(struct tty_struct *tty) · 1588 unmodified lines | |||
| 1589 | tty_debug_hangup(tty, "freeing structure\n"); | 1589 | tty_debug_hangup(tty, "freeing structure\n"); |
| 1590 | /* | 1590 | /* |
| 1591 | * The release_tty function takes care of the details of clearing | 1591 | * The release_tty function takes care of the details of clearing |
| 1592 | * the slots and preserving the termios structure. The tty_unlock_pair | 1592 | * the slots and preserving the termios structure. |
| 1593 | * should be safe as we keep a kref while the tty is locked (so the | ||
| 1594 | * unlock never unlocks a freed tty). | ||
| 1595 | */ | 1593 | */ |
| 1596 | mutex_lock(&tty_mutex); | 1594 | mutex_lock(&tty_mutex); |
| 1597 | tty_port_set_kopened(tty->port, 0); | 1595 | tty_port_set_kopened(tty->port, 0); |
| @@ -1621,9 +1619,7 @@ void tty_release_struct(struct tty_struct *tty, int idx) · 23 unmodified lines | |||
| 1621 | tty_debug_hangup(tty, "freeing structure\n"); | 1619 | tty_debug_hangup(tty, "freeing structure\n"); |
| 1622 | /* | 1620 | /* |
| 1623 | * The release_tty function takes care of the details of clearing | 1621 | * The release_tty function takes care of the details of clearing |
| 1624 | * the slots and preserving the termios structure. The tty_unlock_pair | 1622 | * the slots and preserving the termios structure. |
| 1625 | * should be safe as we keep a kref while the tty is locked (so the | ||
| 1626 | * unlock never unlocks a freed tty). | ||
| 1627 | */ | 1623 | */ |
| 1628 | mutex_lock(&tty_mutex); | 1624 | mutex_lock(&tty_mutex); |
| 1629 | release_tty(tty, idx); | 1625 | release_tty(tty, idx); |
| @@ -2734,9 +2730,11 @@ static int compat_tty_tiocgserial(struct tty_struct *tty, · 1104 unmodified lines | |||
| 2734 | struct serial_struct32 v32; | 2730 | struct serial_struct32 v32; |
| 2735 | struct serial_struct v; | 2731 | struct serial_struct v; |
| 2736 | int err; | 2732 | int err; |
| 2737 | memset(&v, 0, sizeof(struct serial_struct)); | ||
| 2738 | 2733 | ||
| 2739 | if (!tty->ops->set_serial) | 2734 | memset(&v, 0, sizeof(v)); |
| 2735 | memset(&v32, 0, sizeof(v32)); | ||
| 2736 | |||
| 2737 | if (!tty->ops->get_serial) | ||
| 2740 | return -ENOTTY; | 2738 | return -ENOTTY; |
| 2741 | err = tty->ops->get_serial(tty, &v); | 2739 | err = tty->ops->get_serial(tty, &v); |
| 2742 | if (!err) { | 2740 | if (!err) { |
| @@ -1530,18 +1530,19 @@ static const struct usb_ep_ops usb_ep_ops = { · 1529 unmodified lines | |||
| 1530 | static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) | 1530 | static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) |
| 1531 | { | 1531 | { |
| 1532 | struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); | 1532 | struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); |
| 1533 | unsigned long flags; | ||
| 1534 | 1533 | ||
| 1535 | if (is_active) { | 1534 | if (is_active) { |
| 1536 | pm_runtime_get_sync(&_gadget->dev); | 1535 | pm_runtime_get_sync(&_gadget->dev); |
| 1537 | hw_device_reset(ci); | 1536 | hw_device_reset(ci); |
| 1538 | spin_lock_irqsave(&ci->lock, flags); | 1537 | spin_lock_irq(&ci->lock); |
| 1539 | if (ci->driver) { | 1538 | if (ci->driver) { |
| 1540 | hw_device_state(ci, ci->ep0out->qh.dma); | 1539 | hw_device_state(ci, ci->ep0out->qh.dma); |
| 1541 | usb_gadget_set_state(_gadget, USB_STATE_POWERED); | 1540 | usb_gadget_set_state(_gadget, USB_STATE_POWERED); |
| 1541 | spin_unlock_irq(&ci->lock); | ||
| 1542 | usb_udc_vbus_handler(_gadget, true); | 1542 | usb_udc_vbus_handler(_gadget, true); |
| 1543 | } else { | ||
| 1544 | spin_unlock_irq(&ci->lock); | ||
| 1543 | } | 1545 | } |
| 1544 | spin_unlock_irqrestore(&ci->lock, flags); | ||
| 1545 | } else { | 1546 | } else { |
| 1546 | usb_udc_vbus_handler(_gadget, false); | 1547 | usb_udc_vbus_handler(_gadget, false); |
| 1547 | if (ci->driver) | 1548 | if (ci->driver) |
| @@ -896,10 +896,10 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) · 895 unmodified lines | |||
| 896 | 896 | ||
| 897 | ss->xmit_fifo_size = acm->writesize; | 897 | ss->xmit_fifo_size = acm->writesize; |
| 898 | ss->baud_base = le32_to_cpu(acm->line.dwDTERate); | 898 | ss->baud_base = le32_to_cpu(acm->line.dwDTERate); |
| 899 | ss->close_delay = acm->port.close_delay / 10; | 899 | ss->close_delay = jiffies_to_msecs(acm->port.close_delay) / 10; |
| 900 | ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 900 | ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
| 901 | ASYNC_CLOSING_WAIT_NONE : | 901 | ASYNC_CLOSING_WAIT_NONE : |
| 902 | acm->port.closing_wait / 10; | 902 | jiffies_to_msecs(acm->port.closing_wait) / 10; |
| 903 | return 0; | 903 | return 0; |
| 904 | } | 904 | } |
| 905 | 905 | ||
| @@ -907,24 +907,32 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) · 1 unmodified line | |||
| 907 | { | 907 | { |
| 908 | struct acm *acm = tty->driver_data; | 908 | struct acm *acm = tty->driver_data; |
| 909 | unsigned int closing_wait, close_delay; | 909 | unsigned int closing_wait, close_delay; |
| 910 | unsigned int old_closing_wait, old_close_delay; | ||
| 910 | int retval = 0; | 911 | int retval = 0; |
| 911 | 912 | ||
| 912 | close_delay = ss->close_delay * 10; | 913 | close_delay = msecs_to_jiffies(ss->close_delay * 10); |
| 913 | closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 914 | closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
| 914 | ASYNC_CLOSING_WAIT_NONE : ss->closing_wait * 10; | 915 | ASYNC_CLOSING_WAIT_NONE : |
| 916 | msecs_to_jiffies(ss->closing_wait * 10); | ||
| 917 | |||
| 918 | /* we must redo the rounding here, so that the values match */ | ||
| 919 | old_close_delay = jiffies_to_msecs(acm->port.close_delay) / 10; | ||
| 920 | old_closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | ||
| 921 | ASYNC_CLOSING_WAIT_NONE : | ||
| 922 | jiffies_to_msecs(acm->port.closing_wait) / 10; | ||
| 915 | 923 | ||
| 916 | mutex_lock(&acm->port.mutex); | 924 | mutex_lock(&acm->port.mutex); |
| 917 | 925 | ||
| 918 | if (!capable(CAP_SYS_ADMIN)) { | 926 | if ((ss->close_delay != old_close_delay) || |
| 919 | if ((close_delay != acm->port.close_delay) || | 927 | (ss->closing_wait != old_closing_wait)) { |
| 920 | (closing_wait != acm->port.closing_wait)) | 928 | if (!capable(CAP_SYS_ADMIN)) |
| 921 | retval = -EPERM; | 929 | retval = -EPERM; |
| 922 | else | 930 | else { |
| 923 | retval = -EOPNOTSUPP; | 931 | acm->port.close_delay = close_delay; |
| 924 | } else { | 932 | acm->port.closing_wait = closing_wait; |
| 925 | acm->port.close_delay = close_delay; | 933 | } |
| 926 | acm->port.closing_wait = closing_wait; | 934 | } else |
| 927 | } | 935 | retval = -EOPNOTSUPP; |
| 928 | 936 | ||
| 929 | mutex_unlock(&acm->port.mutex); | 937 | mutex_unlock(&acm->port.mutex); |
| 930 | return retval; | 938 | return retval; |
| @@ -378,6 +378,12 @@ static const struct usb_device_id usb_quirk_list[] = { · 377 unmodified lines | |||
| 378 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = | 378 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = |
| 379 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, | 379 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, |
| 380 | 380 | ||
| 381 | /* Realtek hub in Dell WD19 (Type-C) */ | ||
| 382 | { USB_DEVICE(0x0bda, 0x0487), .driver_info = USB_QUIRK_NO_LPM }, | ||
| 383 | |||
| 384 | /* Generic RTL8153 based ethernet adapters */ | ||
| 385 | { USB_DEVICE(0x0bda, 0x8153), .driver_info = USB_QUIRK_NO_LPM }, | ||
| 386 | |||
| 381 | /* Action Semiconductor flash disk */ | 387 | /* Action Semiconductor flash disk */ |
| 382 | { USB_DEVICE(0x10d6, 0x2200), .driver_info = | 388 | { USB_DEVICE(0x10d6, 0x2200), .driver_info = |
| 383 | USB_QUIRK_STRING_FETCH_255 }, | 389 | USB_QUIRK_STRING_FETCH_255 }, |
| @@ -136,7 +136,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 135 unmodified lines | |||
| 136 | xhci->quirks |= XHCI_AMD_PLL_FIX; | 136 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
| 137 | 137 | ||
| 138 | if (pdev->vendor == PCI_VENDOR_ID_AMD && | 138 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
| 139 | (pdev->device == 0x15e0 || | 139 | (pdev->device == 0x145c || |
| 140 | pdev->device == 0x15e0 || | ||
| 140 | pdev->device == 0x15e1 || | 141 | pdev->device == 0x15e1 || |
| 141 | pdev->device == 0x43bb)) | 142 | pdev->device == 0x43bb)) |
| 142 | xhci->quirks |= XHCI_SUSPEND_DELAY; | 143 | xhci->quirks |= XHCI_SUSPEND_DELAY; |
| @@ -445,6 +445,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); · 444 unmodified lines | |||
| 445 | static struct platform_driver usb_xhci_driver = { | 445 | static struct platform_driver usb_xhci_driver = { |
| 446 | .probe = xhci_plat_probe, | 446 | .probe = xhci_plat_probe, |
| 447 | .remove = xhci_plat_remove, | 447 | .remove = xhci_plat_remove, |
| 448 | .shutdown = usb_hcd_platform_shutdown, | ||
| 448 | .driver = { | 449 | .driver = { |
| 449 | .name = "xhci-hcd", | 450 | .name = "xhci-hcd", |
| 450 | .pm = &xhci_plat_pm_ops, | 451 | .pm = &xhci_plat_pm_ops, |
| @@ -289,23 +289,12 @@ DECLARE_EVENT_CLASS(xhci_log_urb, · 288 unmodified lines | |||
| 289 | ), | 289 | ), |
| 290 | TP_printk("ep%d%s-%s: urb %p pipe %u slot %d length %d/%d sgs %d/%d stream %d flags %08x", | 290 | TP_printk("ep%d%s-%s: urb %p pipe %u slot %d length %d/%d sgs %d/%d stream %d flags %08x", |
| 291 | __entry->epnum, __entry->dir_in ? "in" : "out", | 291 | __entry->epnum, __entry->dir_in ? "in" : "out", |
| 292 | ({ char *s; | 292 | __print_symbolic(__entry->type, |
| 293 | switch (__entry->type) { | 293 | { USB_ENDPOINT_XFER_INT, "intr" }, |
| 294 | case USB_ENDPOINT_XFER_INT: | 294 | { USB_ENDPOINT_XFER_CONTROL, "control" }, |
| 295 | s = "intr"; | 295 | { USB_ENDPOINT_XFER_BULK, "bulk" }, |
| 296 | break; | 296 | { USB_ENDPOINT_XFER_ISOC, "isoc" }), |
| 297 | case USB_ENDPOINT_XFER_CONTROL: | 297 | __entry->urb, __entry->pipe, __entry->slot_id, |
| 298 | s = "control"; | ||
| 299 | break; | ||
| 300 | case USB_ENDPOINT_XFER_BULK: | ||
| 301 | s = "bulk"; | ||
| 302 | break; | ||
| 303 | case USB_ENDPOINT_XFER_ISOC: | ||
| 304 | s = "isoc"; | ||
| 305 | break; | ||
| 306 | default: | ||
| 307 | s = "UNKNOWN"; | ||
| 308 | } s; }), __entry->urb, __entry->pipe, __entry->slot_id, | ||
| 309 | __entry->actual, __entry->length, __entry->num_mapped_sgs, | 298 | __entry->actual, __entry->length, __entry->num_mapped_sgs, |
| 310 | __entry->num_sgs, __entry->stream, __entry->flags | 299 | __entry->num_sgs, __entry->stream, __entry->flags |
| 311 | ) | 300 | ) |
| @@ -1183,6 +1183,8 @@ static const struct usb_device_id option_ids[] = { · 1182 unmodified lines | |||
| 1183 | .driver_info = NCTRL(0) }, | 1183 | .driver_info = NCTRL(0) }, |
| 1184 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff), /* Telit ME910G1 */ | 1184 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff), /* Telit ME910G1 */ |
| 1185 | .driver_info = NCTRL(0) | RSVD(3) }, | 1185 | .driver_info = NCTRL(0) | RSVD(3) }, |
| 1186 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110b, 0xff), /* Telit ME910G1 (ECM) */ | ||
| 1187 | .driver_info = NCTRL(0) }, | ||
| 1186 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), | 1188 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), |
| 1187 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | 1189 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1188 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), | 1190 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), |
| @@ -99,6 +99,7 @@ static const struct usb_device_id id_table[] = { · 98 unmodified lines | |||
| 99 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 99 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
| 100 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 100 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
| 101 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) }, | 101 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) }, |
| 102 | { USB_DEVICE(HP_VENDOR_ID, HP_LD381_PRODUCT_ID) }, | ||
| 102 | { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, | 103 | { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, |
| 103 | { USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) }, | 104 | { USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) }, |
| 104 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, | 105 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, |
| @@ -130,6 +130,7 @@ · 129 unmodified lines | |||
| 130 | #define HP_LM920_PRODUCT_ID 0x026b | 130 | #define HP_LM920_PRODUCT_ID 0x026b |
| 131 | #define HP_TD620_PRODUCT_ID 0x0956 | 131 | #define HP_TD620_PRODUCT_ID 0x0956 |
| 132 | #define HP_LD960_PRODUCT_ID 0x0b39 | 132 | #define HP_LD960_PRODUCT_ID 0x0b39 |
| 133 | #define HP_LD381_PRODUCT_ID 0x0f7f | ||
| 133 | #define HP_LCM220_PRODUCT_ID 0x3139 | 134 | #define HP_LCM220_PRODUCT_ID 0x3139 |
| 134 | #define HP_LCM960_PRODUCT_ID 0x3239 | 135 | #define HP_LCM960_PRODUCT_ID 0x3239 |
| 135 | #define HP_LD220_PRODUCT_ID 0x3524 | 136 | #define HP_LD220_PRODUCT_ID 0x3524 |
| @@ -271,6 +271,9 @@ void ucsi_displayport_remove_partner(struct typec_altmode *alt) · 270 unmodified lines | |||
| 271 | return; | 271 | return; |
| 272 | 272 | ||
| 273 | dp = typec_altmode_get_drvdata(alt); | 273 | dp = typec_altmode_get_drvdata(alt); |
| 274 | if (!dp) | ||
| 275 | return; | ||
| 276 | |||
| 274 | dp->data.conf = 0; | 277 | dp->data.conf = 0; |
| 275 | dp->data.status = 0; | 278 | dp->data.status = 0; |
| 276 | dp->initialized = false; | 279 | dp->initialized = false; |
| @@ -285,6 +288,8 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, · 8 unmodified lines | |||
| 285 | struct typec_altmode *alt; | 288 | struct typec_altmode *alt; |
| 286 | struct ucsi_dp *dp; | 289 | struct ucsi_dp *dp; |
| 287 | 290 | ||
| 291 | mutex_lock(&con->lock); | ||
| 292 | |||
| 288 | /* We can't rely on the firmware with the capabilities. */ | 293 | /* We can't rely on the firmware with the capabilities. */ |
| 289 | desc->vdo |= DP_CAP_DP_SIGNALING | DP_CAP_RECEPTACLE; | 294 | desc->vdo |= DP_CAP_DP_SIGNALING | DP_CAP_RECEPTACLE; |
| 290 | 295 | ||
| @@ -293,12 +298,15 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, · 2 unmodified lines | |||
| 293 | desc->vdo |= all_assignments << 16; | 298 | desc->vdo |= all_assignments << 16; |
| 294 | 299 | ||
| 295 | alt = typec_port_register_altmode(con->port, desc); | 300 | alt = typec_port_register_altmode(con->port, desc); |
| 296 | if (IS_ERR(alt)) | 301 | if (IS_ERR(alt)) { |
| 302 | mutex_unlock(&con->lock); | ||
| 297 | return alt; | 303 | return alt; |
| 304 | } | ||
| 298 | 305 | ||
| 299 | dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL); | 306 | dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL); |
| 300 | if (!dp) { | 307 | if (!dp) { |
| 301 | typec_unregister_altmode(alt); | 308 | typec_unregister_altmode(alt); |
| 309 | mutex_unlock(&con->lock); | ||
| 302 | return ERR_PTR(-ENOMEM); | 310 | return ERR_PTR(-ENOMEM); |
| 303 | } | 311 | } |
| 304 | 312 | ||
| @@ -311,5 +319,7 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, · 6 unmodified lines | |||
| 311 | alt->ops = &ucsi_displayport_ops; | 319 | alt->ops = &ucsi_displayport_ops; |
| 312 | typec_altmode_set_drvdata(alt, dp); | 320 | typec_altmode_set_drvdata(alt, dp); |
| 313 | 321 | ||
| 322 | mutex_unlock(&con->lock); | ||
| 323 | |||
| 314 | return alt; | 324 | return alt; |
| 315 | } | 325 | } |
| @@ -1,10 +1,12 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* iTCO Vendor Specific Support hooks */ | 2 | /* iTCO Vendor Specific Support hooks */ |
| 3 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | 3 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT |
| 4 | extern int iTCO_vendorsupport; | ||
| 4 | extern void iTCO_vendor_pre_start(struct resource *, unsigned int); | 5 | extern void iTCO_vendor_pre_start(struct resource *, unsigned int); |
| 5 | extern void iTCO_vendor_pre_stop(struct resource *); | 6 | extern void iTCO_vendor_pre_stop(struct resource *); |
| 6 | extern int iTCO_vendor_check_noreboot_on(void); | 7 | extern int iTCO_vendor_check_noreboot_on(void); |
| 7 | #else | 8 | #else |
| 9 | #define iTCO_vendorsupport 0 | ||
| 8 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} | 10 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} |
| 9 | #define iTCO_vendor_pre_stop(acpibase) {} | 11 | #define iTCO_vendor_pre_stop(acpibase) {} |
| 10 | #define iTCO_vendor_check_noreboot_on() 1 | 12 | #define iTCO_vendor_check_noreboot_on() 1 |
| @@ -39,8 +39,10 @@ · 38 unmodified lines | |||
| 39 | /* Broken BIOS */ | 39 | /* Broken BIOS */ |
| 40 | #define BROKEN_BIOS 911 | 40 | #define BROKEN_BIOS 911 |
| 41 | 41 | ||
| 42 | static int vendorsupport; | 42 | int iTCO_vendorsupport; |
| 43 | module_param(vendorsupport, int, 0); | 43 | EXPORT_SYMBOL(iTCO_vendorsupport); |
| 44 | |||
| 45 | module_param_named(vendorsupport, iTCO_vendorsupport, int, 0); | ||
| 44 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" | 46 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" |
| 45 | "0 (none), 1=SuperMicro Pent3, 911=Broken SMI BIOS"); | 47 | "0 (none), 1=SuperMicro Pent3, 911=Broken SMI BIOS"); |
| 46 | 48 | ||
| @@ -152,7 +154,7 @@ static void broken_bios_stop(struct resource *smires) · 105 unmodified lines | |||
| 152 | void iTCO_vendor_pre_start(struct resource *smires, | 154 | void iTCO_vendor_pre_start(struct resource *smires, |
| 153 | unsigned int heartbeat) | 155 | unsigned int heartbeat) |
| 154 | { | 156 | { |
| 155 | switch (vendorsupport) { | 157 | switch (iTCO_vendorsupport) { |
| 156 | case SUPERMICRO_OLD_BOARD: | 158 | case SUPERMICRO_OLD_BOARD: |
| 157 | supermicro_old_pre_start(smires); | 159 | supermicro_old_pre_start(smires); |
| 158 | break; | 160 | break; |
| @@ -165,7 +167,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_start); · 6 unmodified lines | |||
| 165 | 167 | ||
| 166 | void iTCO_vendor_pre_stop(struct resource *smires) | 168 | void iTCO_vendor_pre_stop(struct resource *smires) |
| 167 | { | 169 | { |
| 168 | switch (vendorsupport) { | 170 | switch (iTCO_vendorsupport) { |
| 169 | case SUPERMICRO_OLD_BOARD: | 171 | case SUPERMICRO_OLD_BOARD: |
| 170 | supermicro_old_pre_stop(smires); | 172 | supermicro_old_pre_stop(smires); |
| 171 | break; | 173 | break; |
| @@ -178,7 +180,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_stop); · 6 unmodified lines | |||
| 178 | 180 | ||
| 179 | int iTCO_vendor_check_noreboot_on(void) | 181 | int iTCO_vendor_check_noreboot_on(void) |
| 180 | { | 182 | { |
| 181 | switch (vendorsupport) { | 183 | switch (iTCO_vendorsupport) { |
| 182 | case SUPERMICRO_OLD_BOARD: | 184 | case SUPERMICRO_OLD_BOARD: |
| 183 | return 0; | 185 | return 0; |
| 184 | default: | 186 | default: |
| @@ -189,13 +191,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); · 4 unmodified lines | |||
| 189 | 191 | ||
| 190 | static int __init iTCO_vendor_init_module(void) | 192 | static int __init iTCO_vendor_init_module(void) |
| 191 | { | 193 | { |
| 192 | if (vendorsupport == SUPERMICRO_NEW_BOARD) { | 194 | if (iTCO_vendorsupport == SUPERMICRO_NEW_BOARD) { |
| 193 | pr_warn("Option vendorsupport=%d is no longer supported, " | 195 | pr_warn("Option vendorsupport=%d is no longer supported, " |
| 194 | "please use the w83627hf_wdt driver instead\n", | 196 | "please use the w83627hf_wdt driver instead\n", |
| 195 | SUPERMICRO_NEW_BOARD); | 197 | SUPERMICRO_NEW_BOARD); |
| 196 | return -EINVAL; | 198 | return -EINVAL; |
| 197 | } | 199 | } |
| 198 | pr_info("vendor-support=%d\n", vendorsupport); | 200 | pr_info("vendor-support=%d\n", iTCO_vendorsupport); |
| 199 | return 0; | 201 | return 0; |
| 200 | } | 202 | } |
| 201 | 203 | ||
| @@ -459,13 +459,25 @@ static int iTCO_wdt_probe(struct platform_device *pdev) · 458 unmodified lines | |||
| 459 | if (!p->tco_res) | 459 | if (!p->tco_res) |
| 460 | return -ENODEV; | 460 | return -ENODEV; |
| 461 | 461 | ||
| 462 | p->smi_res = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_IO_SMI); | ||
| 463 | if (!p->smi_res) | ||
| 464 | return -ENODEV; | ||
| 465 | |||
| 466 | p->iTCO_version = pdata->version; | 462 | p->iTCO_version = pdata->version; |
| 467 | p->pci_dev = to_pci_dev(dev->parent); | 463 | p->pci_dev = to_pci_dev(dev->parent); |
| 468 | 464 | ||
| 465 | p->smi_res = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_IO_SMI); | ||
| 466 | if (p->smi_res) { | ||
| 467 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ | ||
| 468 | if (!devm_request_region(dev, p->smi_res->start, | ||
| 469 | resource_size(p->smi_res), | ||
| 470 | pdev->name)) { | ||
| 471 | pr_err("I/O address 0x%04llx already in use, device disabled\n", | ||
| 472 | (u64)SMI_EN(p)); | ||
| 473 | return -EBUSY; | ||
| 474 | } | ||
| 475 | } else if (iTCO_vendorsupport || | ||
| 476 | turn_SMI_watchdog_clear_off >= p->iTCO_version) { | ||
| 477 | pr_err("SMI I/O resource is missing\n"); | ||
| 478 | return -ENODEV; | ||
| 479 | } | ||
| 480 | |||
| 469 | iTCO_wdt_no_reboot_bit_setup(p, pdata); | 481 | iTCO_wdt_no_reboot_bit_setup(p, pdata); |
| 470 | 482 | ||
| 471 | /* | 483 | /* |
| @@ -492,14 +504,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev) · 20 unmodified lines | |||
| 492 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | 504 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ |
| 493 | p->update_no_reboot_bit(p->no_reboot_priv, true); | 505 | p->update_no_reboot_bit(p->no_reboot_priv, true); |
| 494 | 506 | ||
| 495 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ | ||
| 496 | if (!devm_request_region(dev, p->smi_res->start, | ||
| 497 | resource_size(p->smi_res), | ||
| 498 | pdev->name)) { | ||
| 499 | pr_err("I/O address 0x%04llx already in use, device disabled\n", | ||
| 500 | (u64)SMI_EN(p)); | ||
| 501 | return -EBUSY; | ||
| 502 | } | ||
| 503 | if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { | 507 | if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { |
| 504 | /* | 508 | /* |
| 505 | * Bit 13: TCO_EN -> 0 | 509 | * Bit 13: TCO_EN -> 0 |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 19 | void afs_put_addrlist(struct afs_addr_list *alist) | 19 | void afs_put_addrlist(struct afs_addr_list *alist) |
| 20 | { | 20 | { |
| 21 | if (alist && refcount_dec_and_test(&alist->usage)) | 21 | if (alist && refcount_dec_and_test(&alist->usage)) |
| 22 | call_rcu(&alist->rcu, (rcu_callback_t)kfree); | 22 | kfree_rcu(alist, rcu); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| @@ -243,6 +243,17 @@ static void afs_cm_destructor(struct afs_call *call) · 242 unmodified lines | |||
| 243 | call->buffer = NULL; | 243 | call->buffer = NULL; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | /* | ||
| 247 | * Abort a service call from within an action function. | ||
| 248 | */ | ||
| 249 | static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error, | ||
| 250 | const char *why) | ||
| 251 | { | ||
| 252 | rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | ||
| 253 | abort_code, error, why); | ||
| 254 | afs_set_call_complete(call, error, 0); | ||
| 255 | } | ||
| 256 | |||
| 246 | /* | 257 | /* |
| 247 | * The server supplied a list of callbacks that it wanted to break. | 258 | * The server supplied a list of callbacks that it wanted to break. |
| 248 | */ | 259 | */ |
| @@ -510,8 +521,7 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work) · 261 unmodified lines | |||
| 510 | if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) | 521 | if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) |
| 511 | afs_send_empty_reply(call); | 522 | afs_send_empty_reply(call); |
| 512 | else | 523 | else |
| 513 | rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | 524 | afs_abort_service_call(call, 1, 1, "K-1"); |
| 514 | 1, 1, "K-1"); | ||
| 515 | 525 | ||
| 516 | afs_put_call(call); | 526 | afs_put_call(call); |
| 517 | _leave(""); | 527 | _leave(""); |
| @@ -81,7 +81,7 @@ enum afs_call_state { · 80 unmodified lines | |||
| 81 | * List of server addresses. | 81 | * List of server addresses. |
| 82 | */ | 82 | */ |
| 83 | struct afs_addr_list { | 83 | struct afs_addr_list { |
| 84 | struct rcu_head rcu; /* Must be first */ | 84 | struct rcu_head rcu; |
| 85 | refcount_t usage; | 85 | refcount_t usage; |
| 86 | u32 version; /* Version */ | 86 | u32 version; /* Version */ |
| 87 | unsigned char max_addrs; | 87 | unsigned char max_addrs; |
| @@ -154,7 +154,7 @@ struct afs_call { · 66 unmodified lines | |||
| 154 | }; | 154 | }; |
| 155 | unsigned char unmarshall; /* unmarshalling phase */ | 155 | unsigned char unmarshall; /* unmarshalling phase */ |
| 156 | unsigned char addr_ix; /* Address in ->alist */ | 156 | unsigned char addr_ix; /* Address in ->alist */ |
| 157 | bool incoming; /* T if incoming call */ | 157 | bool drop_ref; /* T if need to drop ref for incoming call */ |
| 158 | bool send_pages; /* T if data from mapping should be sent */ | 158 | bool send_pages; /* T if data from mapping should be sent */ |
| 159 | bool need_attention; /* T if RxRPC poked us */ | 159 | bool need_attention; /* T if RxRPC poked us */ |
| 160 | bool async; /* T if asynchronous */ | 160 | bool async; /* T if asynchronous */ |
| @@ -1209,8 +1209,16 @@ static inline void afs_set_call_complete(struct afs_call *call, · 1048 unmodified lines | |||
| 1209 | ok = true; | 1209 | ok = true; |
| 1210 | } | 1210 | } |
| 1211 | spin_unlock_bh(&call->state_lock); | 1211 | spin_unlock_bh(&call->state_lock); |
| 1212 | if (ok) | 1212 | if (ok) { |
| 1213 | trace_afs_call_done(call); | 1213 | trace_afs_call_done(call); |
| 1214 | |||
| 1215 | /* Asynchronous calls have two refs to release - one from the alloc and | ||
| 1216 | * one queued with the work item - and we can't just deallocate the | ||
| 1217 | * call because the work item may be queued again. | ||
| 1218 | */ | ||
| 1219 | if (call->drop_ref) | ||
| 1220 | afs_put_call(call); | ||
| 1221 | } | ||
| 1214 | } | 1222 | } |
| 1215 | 1223 | ||
| 1216 | /* | 1224 | /* |
| @@ -18,7 +18,6 @@ struct workqueue_struct *afs_async_calls; · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); | 19 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); |
| 20 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); | 20 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); |
| 21 | static void afs_delete_async_call(struct work_struct *); | ||
| 22 | static void afs_process_async_call(struct work_struct *); | 21 | static void afs_process_async_call(struct work_struct *); |
| 23 | static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long); | 22 | static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long); |
| 24 | static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long); | 23 | static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long); |
| @@ -169,7 +168,7 @@ void afs_put_call(struct afs_call *call) · 144 unmodified lines | |||
| 169 | int n = atomic_dec_return(&call->usage); | 168 | int n = atomic_dec_return(&call->usage); |
| 170 | int o = atomic_read(&net->nr_outstanding_calls); | 169 | int o = atomic_read(&net->nr_outstanding_calls); |
| 171 | 170 | ||
| 172 | trace_afs_call(call, afs_call_trace_put, n + 1, o, | 171 | trace_afs_call(call, afs_call_trace_put, n, o, |
| 173 | __builtin_return_address(0)); | 172 | __builtin_return_address(0)); |
| 174 | 173 | ||
| 175 | ASSERTCMP(n, >=, 0); | 174 | ASSERTCMP(n, >=, 0); |
| @@ -402,8 +401,10 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) · 226 unmodified lines | |||
| 402 | /* If the call is going to be asynchronous, we need an extra ref for | 401 | /* If the call is going to be asynchronous, we need an extra ref for |
| 403 | * the call to hold itself so the caller need not hang on to its ref. | 402 | * the call to hold itself so the caller need not hang on to its ref. |
| 404 | */ | 403 | */ |
| 405 | if (call->async) | 404 | if (call->async) { |
| 406 | afs_get_call(call, afs_call_trace_get); | 405 | afs_get_call(call, afs_call_trace_get); |
| 406 | call->drop_ref = true; | ||
| 407 | } | ||
| 407 | 408 | ||
| 408 | /* create a call */ | 409 | /* create a call */ |
| 409 | rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key, | 410 | rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key, |
| @@ -413,7 +414,8 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) · 3 unmodified lines | |||
| 413 | afs_wake_up_async_call : | 414 | afs_wake_up_async_call : |
| 414 | afs_wake_up_call_waiter), | 415 | afs_wake_up_call_waiter), |
| 415 | call->upgrade, | 416 | call->upgrade, |
| 416 | call->intr, | 417 | (call->intr ? RXRPC_PREINTERRUPTIBLE : |
| 418 | RXRPC_UNINTERRUPTIBLE), | ||
| 417 | call->debug_id); | 419 | call->debug_id); |
| 418 | if (IS_ERR(rxcall)) { | 420 | if (IS_ERR(rxcall)) { |
| 419 | ret = PTR_ERR(rxcall); | 421 | ret = PTR_ERR(rxcall); |
| @@ -584,8 +586,6 @@ static void afs_deliver_to_call(struct afs_call *call) · 164 unmodified lines | |||
| 584 | done: | 586 | done: |
| 585 | if (call->type->done) | 587 | if (call->type->done) |
| 586 | call->type->done(call); | 588 | call->type->done(call); |
| 587 | if (state == AFS_CALL_COMPLETE && call->incoming) | ||
| 588 | afs_put_call(call); | ||
| 589 | out: | 589 | out: |
| 590 | _leave(""); | 590 | _leave(""); |
| 591 | return; | 591 | return; |
| @@ -604,11 +604,7 @@ call_complete: · 12 unmodified lines | |||
| 604 | long afs_wait_for_call_to_complete(struct afs_call *call, | 604 | long afs_wait_for_call_to_complete(struct afs_call *call, |
| 605 | struct afs_addr_cursor *ac) | 605 | struct afs_addr_cursor *ac) |
| 606 | { | 606 | { |
| 607 | signed long rtt2, timeout; | ||
| 608 | long ret; | 607 | long ret; |
| 609 | bool stalled = false; | ||
| 610 | u64 rtt; | ||
| 611 | u32 life, last_life; | ||
| 612 | bool rxrpc_complete = false; | 608 | bool rxrpc_complete = false; |
| 613 | 609 | ||
| 614 | DECLARE_WAITQUEUE(myself, current); | 610 | DECLARE_WAITQUEUE(myself, current); |
| @@ -619,14 +615,6 @@ long afs_wait_for_call_to_complete(struct afs_call *call, · 4 unmodified lines | |||
| 619 | if (ret < 0) | 615 | if (ret < 0) |
| 620 | goto out; | 616 | goto out; |
| 621 | 617 | ||
| 622 | rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); | ||
| 623 | rtt2 = nsecs_to_jiffies64(rtt) * 2; | ||
| 624 | if (rtt2 < 2) | ||
| 625 | rtt2 = 2; | ||
| 626 | |||
| 627 | timeout = rtt2; | ||
| 628 | rxrpc_kernel_check_life(call->net->socket, call->rxcall, &last_life); | ||
| 629 | |||
| 630 | add_wait_queue(&call->waitq, &myself); | 618 | add_wait_queue(&call->waitq, &myself); |
| 631 | for (;;) { | 619 | for (;;) { |
| 632 | set_current_state(TASK_UNINTERRUPTIBLE); | 620 | set_current_state(TASK_UNINTERRUPTIBLE); |
| @@ -637,37 +625,19 @@ long afs_wait_for_call_to_complete(struct afs_call *call, · 4 unmodified lines | |||
| 637 | call->need_attention = false; | 625 | call->need_attention = false; |
| 638 | __set_current_state(TASK_RUNNING); | 626 | __set_current_state(TASK_RUNNING); |
| 639 | afs_deliver_to_call(call); | 627 | afs_deliver_to_call(call); |
| 640 | timeout = rtt2; | ||
| 641 | continue; | 628 | continue; |
| 642 | } | 629 | } |
| 643 | 630 | ||
| 644 | if (afs_check_call_state(call, AFS_CALL_COMPLETE)) | 631 | if (afs_check_call_state(call, AFS_CALL_COMPLETE)) |
| 645 | break; | 632 | break; |
| 646 | 633 | ||
| 647 | if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall, &life)) { | 634 | if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall)) { |
| 648 | /* rxrpc terminated the call. */ | 635 | /* rxrpc terminated the call. */ |
| 649 | rxrpc_complete = true; | 636 | rxrpc_complete = true; |
| 650 | break; | 637 | break; |
| 651 | } | 638 | } |
| 652 | 639 | ||
| 653 | if (call->intr && timeout == 0 && | 640 | schedule(); |
| 654 | life == last_life && signal_pending(current)) { | ||
| 655 | if (stalled) | ||
| 656 | break; | ||
| 657 | __set_current_state(TASK_RUNNING); | ||
| 658 | rxrpc_kernel_probe_life(call->net->socket, call->rxcall); | ||
| 659 | timeout = rtt2; | ||
| 660 | stalled = true; | ||
| 661 | continue; | ||
| 662 | } | ||
| 663 | |||
| 664 | if (life != last_life) { | ||
| 665 | timeout = rtt2; | ||
| 666 | last_life = life; | ||
| 667 | stalled = false; | ||
| 668 | } | ||
| 669 | |||
| 670 | timeout = schedule_timeout(timeout); | ||
| 671 | } | 641 | } |
| 672 | 642 | ||
| 673 | remove_wait_queue(&call->waitq, &myself); | 643 | remove_wait_queue(&call->waitq, &myself); |
| @@ -735,7 +705,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, · 61 unmodified lines | |||
| 735 | 705 | ||
| 736 | u = atomic_fetch_add_unless(&call->usage, 1, 0); | 706 | u = atomic_fetch_add_unless(&call->usage, 1, 0); |
| 737 | if (u != 0) { | 707 | if (u != 0) { |
| 738 | trace_afs_call(call, afs_call_trace_wake, u, | 708 | trace_afs_call(call, afs_call_trace_wake, u + 1, |
| 739 | atomic_read(&call->net->nr_outstanding_calls), | 709 | atomic_read(&call->net->nr_outstanding_calls), |
| 740 | __builtin_return_address(0)); | 710 | __builtin_return_address(0)); |
| 741 | 711 | ||
| @@ -744,21 +714,6 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, · 2 unmodified lines | |||
| 744 | } | 714 | } |
| 745 | } | 715 | } |
| 746 | 716 | ||
| 747 | /* | ||
| 748 | * Delete an asynchronous call. The work item carries a ref to the call struct | ||
| 749 | * that we need to release. | ||
| 750 | */ | ||
| 751 | static void afs_delete_async_call(struct work_struct *work) | ||
| 752 | { | ||
| 753 | struct afs_call *call = container_of(work, struct afs_call, async_work); | ||
| 754 | |||
| 755 | _enter(""); | ||
| 756 | |||
| 757 | afs_put_call(call); | ||
| 758 | |||
| 759 | _leave(""); | ||
| 760 | } | ||
| 761 | |||
| 762 | /* | 717 | /* |
| 763 | * Perform I/O processing on an asynchronous call. The work item carries a ref | 718 | * Perform I/O processing on an asynchronous call. The work item carries a ref |
| 764 | * to the call struct that we either need to release or to pass on. | 719 | * to the call struct that we either need to release or to pass on. |
| @@ -774,16 +729,6 @@ static void afs_process_async_call(struct work_struct *work) · 9 unmodified lines | |||
| 774 | afs_deliver_to_call(call); | 729 | afs_deliver_to_call(call); |
| 775 | } | 730 | } |
| 776 | 731 | ||
| 777 | if (call->state == AFS_CALL_COMPLETE) { | ||
| 778 | /* We have two refs to release - one from the alloc and one | ||
| 779 | * queued with the work item - and we can't just deallocate the | ||
| 780 | * call because the work item may be queued again. | ||
| 781 | */ | ||
| 782 | call->async_work.func = afs_delete_async_call; | ||
| 783 | if (!queue_work(afs_async_calls, &call->async_work)) | ||
| 784 | afs_put_call(call); | ||
| 785 | } | ||
| 786 | |||
| 787 | afs_put_call(call); | 732 | afs_put_call(call); |
| 788 | _leave(""); | 733 | _leave(""); |
| 789 | } | 734 | } |
| @@ -810,6 +755,7 @@ void afs_charge_preallocation(struct work_struct *work) · 20 unmodified lines | |||
| 810 | if (!call) | 755 | if (!call) |
| 811 | break; | 756 | break; |
| 812 | 757 | ||
| 758 | call->drop_ref = true; | ||
| 813 | call->async = true; | 759 | call->async = true; |
| 814 | call->state = AFS_CALL_SV_AWAIT_OP_ID; | 760 | call->state = AFS_CALL_SV_AWAIT_OP_ID; |
| 815 | init_waitqueue_head(&call->waitq); | 761 | init_waitqueue_head(&call->waitq); |
| @@ -856,9 +856,9 @@ static void clear_incompat_bg_bits(struct btrfs_fs_info *fs_info, u64 flags) · 855 unmodified lines | |||
| 856 | found_raid1c34 = true; | 856 | found_raid1c34 = true; |
| 857 | up_read(&sinfo->groups_sem); | 857 | up_read(&sinfo->groups_sem); |
| 858 | } | 858 | } |
| 859 | if (found_raid56) | 859 | if (!found_raid56) |
| 860 | btrfs_clear_fs_incompat(fs_info, RAID56); | 860 | btrfs_clear_fs_incompat(fs_info, RAID56); |
| 861 | if (found_raid1c34) | 861 | if (!found_raid1c34) |
| 862 | btrfs_clear_fs_incompat(fs_info, RAID1C34); | 862 | btrfs_clear_fs_incompat(fs_info, RAID1C34); |
| 863 | } | 863 | } |
| 864 | } | 864 | } |
| @@ -9496,6 +9496,10 @@ out_fail: · 9495 unmodified lines | |||
| 9496 | ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root, &ctx); | 9496 | ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root, &ctx); |
| 9497 | if (ret) | 9497 | if (ret) |
| 9498 | commit_transaction = true; | 9498 | commit_transaction = true; |
| 9499 | } else if (sync_log) { | ||
| 9500 | mutex_lock(&root->log_mutex); | ||
| 9501 | list_del(&ctx.list); | ||
| 9502 | mutex_unlock(&root->log_mutex); | ||
| 9499 | } | 9503 | } |
| 9500 | if (commit_transaction) { | 9504 | if (commit_transaction) { |
| 9501 | ret = btrfs_commit_transaction(trans); | 9505 | ret = btrfs_commit_transaction(trans); |
| @@ -1169,7 +1169,8 @@ try_again: · 1168 unmodified lines | |||
| 1169 | rc = posix_lock_file(file, flock, NULL); | 1169 | rc = posix_lock_file(file, flock, NULL); |
| 1170 | up_write(&cinode->lock_sem); | 1170 | up_write(&cinode->lock_sem); |
| 1171 | if (rc == FILE_LOCK_DEFERRED) { | 1171 | if (rc == FILE_LOCK_DEFERRED) { |
| 1172 | rc = wait_event_interruptible(flock->fl_wait, !flock->fl_blocker); | 1172 | rc = wait_event_interruptible(flock->fl_wait, |
| 1173 | list_empty(&flock->fl_blocked_member)); | ||
| 1173 | if (!rc) | 1174 | if (!rc) |
| 1174 | goto try_again; | 1175 | goto try_again; |
| 1175 | locks_delete_block(flock); | 1176 | locks_delete_block(flock); |
| @@ -2191,7 +2191,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat, · 2190 unmodified lines | |||
| 2191 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) | 2191 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) |
| 2192 | stat->gid = current_fsgid(); | 2192 | stat->gid = current_fsgid(); |
| 2193 | } | 2193 | } |
| 2194 | return rc; | 2194 | return 0; |
| 2195 | } | 2195 | } |
| 2196 | 2196 | ||
| 2197 | int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, | 2197 | int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, |
| @@ -2222,6 +2222,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, · 2221 unmodified lines | |||
| 2222 | goto qdf_free; | 2222 | goto qdf_free; |
| 2223 | } | 2223 | } |
| 2224 | 2224 | ||
| 2225 | atomic_inc(&tcon->num_remote_opens); | ||
| 2226 | |||
| 2225 | qd_rsp = (struct smb2_query_directory_rsp *)rsp_iov[1].iov_base; | 2227 | qd_rsp = (struct smb2_query_directory_rsp *)rsp_iov[1].iov_base; |
| 2226 | if (qd_rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { | 2228 | if (qd_rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { |
| 2227 | trace_smb3_query_dir_done(xid, fid->persistent_fid, | 2229 | trace_smb3_query_dir_done(xid, fid->persistent_fid, |
| @@ -3417,7 +3419,7 @@ static int smb3_fiemap(struct cifs_tcon *tcon, · 1189 unmodified lines | |||
| 3417 | if (rc) | 3419 | if (rc) |
| 3418 | goto out; | 3420 | goto out; |
| 3419 | 3421 | ||
| 3420 | if (out_data_len < sizeof(struct file_allocated_range_buffer)) { | 3422 | if (out_data_len && out_data_len < sizeof(struct file_allocated_range_buffer)) { |
| 3421 | rc = -EINVAL; | 3423 | rc = -EINVAL; |
| 3422 | goto out; | 3424 | goto out; |
| 3423 | } | 3425 | } |
| @@ -1854,9 +1854,9 @@ fetch_events: · 1853 unmodified lines | |||
| 1854 | waiter = true; | 1854 | waiter = true; |
| 1855 | init_waitqueue_entry(&wait, current); | 1855 | init_waitqueue_entry(&wait, current); |
| 1856 | 1856 | ||
| 1857 | spin_lock_irq(&ep->wq.lock); | 1857 | write_lock_irq(&ep->lock); |
| 1858 | __add_wait_queue_exclusive(&ep->wq, &wait); | 1858 | __add_wait_queue_exclusive(&ep->wq, &wait); |
| 1859 | spin_unlock_irq(&ep->wq.lock); | 1859 | write_unlock_irq(&ep->lock); |
| 1860 | } | 1860 | } |
| 1861 | 1861 | ||
| 1862 | for (;;) { | 1862 | for (;;) { |
| @@ -1904,9 +1904,9 @@ send_events: · 41 unmodified lines | |||
| 1904 | goto fetch_events; | 1904 | goto fetch_events; |
| 1905 | 1905 | ||
| 1906 | if (waiter) { | 1906 | if (waiter) { |
| 1907 | spin_lock_irq(&ep->wq.lock); | 1907 | write_lock_irq(&ep->lock); |
| 1908 | __remove_wait_queue(&ep->wq, &wait); | 1908 | __remove_wait_queue(&ep->wq, &wait); |
| 1909 | spin_unlock_irq(&ep->wq.lock); | 1909 | write_unlock_irq(&ep->lock); |
| 1910 | } | 1910 | } |
| 1911 | 1911 | ||
| 1912 | return res; | 1912 | return res; |
| @@ -540,9 +540,14 @@ static int alloc_fd(unsigned start, unsigned flags) · 539 unmodified lines | |||
| 540 | return __alloc_fd(current->files, start, rlimit(RLIMIT_NOFILE), flags); | 540 | return __alloc_fd(current->files, start, rlimit(RLIMIT_NOFILE), flags); |
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | int __get_unused_fd_flags(unsigned flags, unsigned long nofile) | ||
| 544 | { | ||
| 545 | return __alloc_fd(current->files, 0, nofile, flags); | ||
| 546 | } | ||
| 547 | |||
| 543 | int get_unused_fd_flags(unsigned flags) | 548 | int get_unused_fd_flags(unsigned flags) |
| 544 | { | 549 | { |
| 545 | return __alloc_fd(current->files, 0, rlimit(RLIMIT_NOFILE), flags); | 550 | return __get_unused_fd_flags(flags, rlimit(RLIMIT_NOFILE)); |
| 546 | } | 551 | } |
| 547 | EXPORT_SYMBOL(get_unused_fd_flags); | 552 | EXPORT_SYMBOL(get_unused_fd_flags); |
| 548 | 553 | ||
| @@ -276,12 +276,10 @@ static void flush_bg_queue(struct fuse_conn *fc) · 275 unmodified lines | |||
| 276 | void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) | 276 | void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) |
| 277 | { | 277 | { |
| 278 | struct fuse_iqueue *fiq = &fc->iq; | 278 | struct fuse_iqueue *fiq = &fc->iq; |
| 279 | bool async; | ||
| 280 | 279 | ||
| 281 | if (test_and_set_bit(FR_FINISHED, &req->flags)) | 280 | if (test_and_set_bit(FR_FINISHED, &req->flags)) |
| 282 | goto put_request; | 281 | goto put_request; |
| 283 | 282 | ||
| 284 | async = req->args->end; | ||
| 285 | /* | 283 | /* |
| 286 | * test_and_set_bit() implies smp_mb() between bit | 284 | * test_and_set_bit() implies smp_mb() between bit |
| 287 | * changing and below intr_entry check. Pairs with | 285 | * changing and below intr_entry check. Pairs with |
| @@ -324,7 +322,7 @@ void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) · 36 unmodified lines | |||
| 324 | wake_up(&req->waitq); | 322 | wake_up(&req->waitq); |
| 325 | } | 323 | } |
| 326 | 324 | ||
| 327 | if (async) | 325 | if (test_bit(FR_ASYNC, &req->flags)) |
| 328 | req->args->end(fc, req->args, req->out.h.error); | 326 | req->args->end(fc, req->args, req->out.h.error); |
| 329 | put_request: | 327 | put_request: |
| 330 | fuse_put_request(fc, req); | 328 | fuse_put_request(fc, req); |
| @@ -471,6 +469,8 @@ static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args) · 140 unmodified lines | |||
| 471 | req->in.h.opcode = args->opcode; | 469 | req->in.h.opcode = args->opcode; |
| 472 | req->in.h.nodeid = args->nodeid; | 470 | req->in.h.nodeid = args->nodeid; |
| 473 | req->args = args; | 471 | req->args = args; |
| 472 | if (args->end) | ||
| 473 | __set_bit(FR_ASYNC, &req->flags); | ||
| 474 | } | 474 | } |
| 475 | 475 | ||
| 476 | ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) | 476 | ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) |
| @@ -301,6 +301,7 @@ struct fuse_io_priv { · 300 unmodified lines | |||
| 301 | * FR_SENT: request is in userspace, waiting for an answer | 301 | * FR_SENT: request is in userspace, waiting for an answer |
| 302 | * FR_FINISHED: request is finished | 302 | * FR_FINISHED: request is finished |
| 303 | * FR_PRIVATE: request is on private list | 303 | * FR_PRIVATE: request is on private list |
| 304 | * FR_ASYNC: request is asynchronous | ||
| 304 | */ | 305 | */ |
| 305 | enum fuse_req_flag { | 306 | enum fuse_req_flag { |
| 306 | FR_ISREPLY, | 307 | FR_ISREPLY, |
| @@ -314,6 +315,7 @@ enum fuse_req_flag { · 7 unmodified lines | |||
| 314 | FR_SENT, | 315 | FR_SENT, |
| 315 | FR_FINISHED, | 316 | FR_FINISHED, |
| 316 | FR_PRIVATE, | 317 | FR_PRIVATE, |
| 318 | FR_ASYNC, | ||
| 317 | }; | 319 | }; |
| 318 | 320 | ||
| 319 | /** | 321 | /** |
| @@ -138,6 +138,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode) · 137 unmodified lines | |||
| 138 | inode->i_sb = sb; | 138 | inode->i_sb = sb; |
| 139 | inode->i_blkbits = sb->s_blocksize_bits; | 139 | inode->i_blkbits = sb->s_blocksize_bits; |
| 140 | inode->i_flags = 0; | 140 | inode->i_flags = 0; |
| 141 | atomic64_set(&inode->i_sequence, 0); | ||
| 141 | atomic_set(&inode->i_count, 1); | 142 | atomic_set(&inode->i_count, 1); |
| 142 | inode->i_op = &empty_iops; | 143 | inode->i_op = &empty_iops; |
| 143 | inode->i_fop = &no_open_fops; | 144 | inode->i_fop = &no_open_fops; |
| @@ -191,7 +191,6 @@ struct fixed_file_data { · 190 unmodified lines | |||
| 191 | struct llist_head put_llist; | 191 | struct llist_head put_llist; |
| 192 | struct work_struct ref_work; | 192 | struct work_struct ref_work; |
| 193 | struct completion done; | 193 | struct completion done; |
| 194 | struct rcu_head rcu; | ||
| 195 | }; | 194 | }; |
| 196 | 195 | ||
| 197 | struct io_ring_ctx { | 196 | struct io_ring_ctx { |
| @@ -344,6 +343,7 @@ struct io_accept { · 146 unmodified lines | |||
| 344 | struct sockaddr __user *addr; | 343 | struct sockaddr __user *addr; |
| 345 | int __user *addr_len; | 344 | int __user *addr_len; |
| 346 | int flags; | 345 | int flags; |
| 346 | unsigned long nofile; | ||
| 347 | }; | 347 | }; |
| 348 | 348 | ||
| 349 | struct io_sync { | 349 | struct io_sync { |
| @@ -398,6 +398,7 @@ struct io_open { · 48 unmodified lines | |||
| 398 | struct filename *filename; | 398 | struct filename *filename; |
| 399 | struct statx __user *buffer; | 399 | struct statx __user *buffer; |
| 400 | struct open_how how; | 400 | struct open_how how; |
| 401 | unsigned long nofile; | ||
| 401 | }; | 402 | }; |
| 402 | 403 | ||
| 403 | struct io_files_update { | 404 | struct io_files_update { |
| @@ -2578,6 +2579,7 @@ static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 2174 unmodified lines | |||
| 2578 | return ret; | 2579 | return ret; |
| 2579 | } | 2580 | } |
| 2580 | 2581 | ||
| 2582 | req->open.nofile = rlimit(RLIMIT_NOFILE); | ||
| 2581 | req->flags |= REQ_F_NEED_CLEANUP; | 2583 | req->flags |= REQ_F_NEED_CLEANUP; |
| 2582 | return 0; | 2584 | return 0; |
| 2583 | } | 2585 | } |
| @@ -2619,6 +2621,7 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 35 unmodified lines | |||
| 2619 | return ret; | 2621 | return ret; |
| 2620 | } | 2622 | } |
| 2621 | 2623 | ||
| 2624 | req->open.nofile = rlimit(RLIMIT_NOFILE); | ||
| 2622 | req->flags |= REQ_F_NEED_CLEANUP; | 2625 | req->flags |= REQ_F_NEED_CLEANUP; |
| 2623 | return 0; | 2626 | return 0; |
| 2624 | } | 2627 | } |
| @@ -2637,7 +2640,7 @@ static int io_openat2(struct io_kiocb *req, struct io_kiocb **nxt, · 12 unmodified lines | |||
| 2637 | if (ret) | 2640 | if (ret) |
| 2638 | goto err; | 2641 | goto err; |
| 2639 | 2642 | ||
| 2640 | ret = get_unused_fd_flags(req->open.how.flags); | 2643 | ret = __get_unused_fd_flags(req->open.how.flags, req->open.nofile); |
| 2641 | if (ret < 0) | 2644 | if (ret < 0) |
| 2642 | goto err; | 2645 | goto err; |
| 2643 | 2646 | ||
| @@ -3322,6 +3325,7 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 678 unmodified lines | |||
| 3322 | accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); | 3325 | accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); |
| 3323 | accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); | 3326 | accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); |
| 3324 | accept->flags = READ_ONCE(sqe->accept_flags); | 3327 | accept->flags = READ_ONCE(sqe->accept_flags); |
| 3328 | accept->nofile = rlimit(RLIMIT_NOFILE); | ||
| 3325 | return 0; | 3329 | return 0; |
| 3326 | #else | 3330 | #else |
| 3327 | return -EOPNOTSUPP; | 3331 | return -EOPNOTSUPP; |
| @@ -3338,7 +3342,8 @@ static int __io_accept(struct io_kiocb *req, struct io_kiocb **nxt, · 10 unmodified lines | |||
| 3338 | 3342 | ||
| 3339 | file_flags = force_nonblock ? O_NONBLOCK : 0; | 3343 | file_flags = force_nonblock ? O_NONBLOCK : 0; |
| 3340 | ret = __sys_accept4_file(req->file, file_flags, accept->addr, | 3344 | ret = __sys_accept4_file(req->file, file_flags, accept->addr, |
| 3341 | accept->addr_len, accept->flags); | 3345 | accept->addr_len, accept->flags, |
| 3346 | accept->nofile); | ||
| 3342 | if (ret == -EAGAIN && force_nonblock) | 3347 | if (ret == -EAGAIN && force_nonblock) |
| 3343 | return -EAGAIN; | 3348 | return -EAGAIN; |
| 3344 | if (ret == -ERESTARTSYS) | 3349 | if (ret == -ERESTARTSYS) |
| @@ -4132,6 +4137,9 @@ static int io_req_defer_prep(struct io_kiocb *req, · 787 unmodified lines | |||
| 4132 | { | 4137 | { |
| 4133 | ssize_t ret = 0; | 4138 | ssize_t ret = 0; |
| 4134 | 4139 | ||
| 4140 | if (!sqe) | ||
| 4141 | return 0; | ||
| 4142 | |||
| 4135 | if (io_op_defs[req->opcode].file_table) { | 4143 | if (io_op_defs[req->opcode].file_table) { |
| 4136 | ret = io_grab_files(req); | 4144 | ret = io_grab_files(req); |
| 4137 | if (unlikely(ret)) | 4145 | if (unlikely(ret)) |
| @@ -4908,6 +4916,11 @@ err_req: · 770 unmodified lines | |||
| 4908 | if (sqe_flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) { | 4916 | if (sqe_flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) { |
| 4909 | req->flags |= REQ_F_LINK; | 4917 | req->flags |= REQ_F_LINK; |
| 4910 | INIT_LIST_HEAD(&req->link_list); | 4918 | INIT_LIST_HEAD(&req->link_list); |
| 4919 | |||
| 4920 | if (io_alloc_async_ctx(req)) { | ||
| 4921 | ret = -EAGAIN; | ||
| 4922 | goto err_req; | ||
| 4923 | } | ||
| 4911 | ret = io_req_defer_prep(req, sqe); | 4924 | ret = io_req_defer_prep(req, sqe); |
| 4912 | if (ret) | 4925 | if (ret) |
| 4913 | req->flags |= REQ_F_FAIL_LINK; | 4926 | req->flags |= REQ_F_FAIL_LINK; |
| @@ -5331,24 +5344,21 @@ static void io_file_ref_kill(struct percpu_ref *ref) · 417 unmodified lines | |||
| 5331 | complete(&data->done); | 5344 | complete(&data->done); |
| 5332 | } | 5345 | } |
| 5333 | 5346 | ||
| 5334 | static void __io_file_ref_exit_and_free(struct rcu_head *rcu) | 5347 | static void io_file_ref_exit_and_free(struct work_struct *work) |
| 5335 | { | 5348 | { |
| 5336 | struct fixed_file_data *data = container_of(rcu, struct fixed_file_data, | 5349 | struct fixed_file_data *data; |
| 5337 | rcu); | 5350 | |
| 5338 | percpu_ref_exit(&data->refs); | 5351 | data = container_of(work, struct fixed_file_data, ref_work); |
| 5339 | kfree(data); | ||
| 5340 | } | ||
| 5341 | 5352 | ||
| 5342 | static void io_file_ref_exit_and_free(struct rcu_head *rcu) | ||
| 5343 | { | ||
| 5344 | /* | 5353 | /* |
| 5345 | * We need to order our exit+free call against the potentially | 5354 | * Ensure any percpu-ref atomic switch callback has run, it could have |
| 5346 | * existing call_rcu() for switching to atomic. One way to do that | 5355 | * been in progress when the files were being unregistered. Once |
| 5347 | * is to have this rcu callback queue the final put and free, as we | 5356 | * that's done, we can safely exit and free the ref and containing |
| 5348 | * could otherwise have a pre-existing atomic switch complete _after_ | 5357 | * data structure. |
| 5349 | * the free callback we queued. | ||
| 5350 | */ | 5358 | */ |
| 5351 | call_rcu(rcu, __io_file_ref_exit_and_free); | 5359 | rcu_barrier(); |
| 5360 | percpu_ref_exit(&data->refs); | ||
| 5361 | kfree(data); | ||
| 5352 | } | 5362 | } |
| 5353 | 5363 | ||
| 5354 | static int io_sqe_files_unregister(struct io_ring_ctx *ctx) | 5364 | static int io_sqe_files_unregister(struct io_ring_ctx *ctx) |
| @@ -5369,7 +5379,8 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx) · 14 unmodified lines | |||
| 5369 | for (i = 0; i < nr_tables; i++) | 5379 | for (i = 0; i < nr_tables; i++) |
| 5370 | kfree(data->table[i].files); | 5380 | kfree(data->table[i].files); |
| 5371 | kfree(data->table); | 5381 | kfree(data->table); |
| 5372 | call_rcu(&data->rcu, io_file_ref_exit_and_free); | 5382 | INIT_WORK(&data->ref_work, io_file_ref_exit_and_free); |
| 5383 | queue_work(system_wq, &data->ref_work); | ||
| 5373 | ctx->file_data = NULL; | 5384 | ctx->file_data = NULL; |
| 5374 | ctx->nr_user_files = 0; | 5385 | ctx->nr_user_files = 0; |
| 5375 | return 0; | 5386 | return 0; |
| @@ -725,7 +725,6 @@ static void __locks_delete_block(struct file_lock *waiter) · 724 unmodified lines | |||
| 725 | { | 725 | { |
| 726 | locks_delete_global_blocked(waiter); | 726 | locks_delete_global_blocked(waiter); |
| 727 | list_del_init(&waiter->fl_blocked_member); | 727 | list_del_init(&waiter->fl_blocked_member); |
| 728 | waiter->fl_blocker = NULL; | ||
| 729 | } | 728 | } |
| 730 | 729 | ||
| 731 | static void __locks_wake_up_blocks(struct file_lock *blocker) | 730 | static void __locks_wake_up_blocks(struct file_lock *blocker) |
| @@ -740,6 +739,13 @@ static void __locks_wake_up_blocks(struct file_lock *blocker) · 8 unmodified lines | |||
| 740 | waiter->fl_lmops->lm_notify(waiter); | 739 | waiter->fl_lmops->lm_notify(waiter); |
| 741 | else | 740 | else |
| 742 | wake_up(&waiter->fl_wait); | 741 | wake_up(&waiter->fl_wait); |
| 742 | |||
| 743 | /* | ||
| 744 | * The setting of fl_blocker to NULL marks the "done" | ||
| 745 | * point in deleting a block. Paired with acquire at the top | ||
| 746 | * of locks_delete_block(). | ||
| 747 | */ | ||
| 748 | smp_store_release(&waiter->fl_blocker, NULL); | ||
| 743 | } | 749 | } |
| 744 | } | 750 | } |
| 745 | 751 | ||
| @@ -753,11 +759,42 @@ int locks_delete_block(struct file_lock *waiter) · 7 unmodified lines | |||
| 753 | { | 759 | { |
| 754 | int status = -ENOENT; | 760 | int status = -ENOENT; |
| 755 | 761 | ||
| 762 | /* | ||
| 763 | * If fl_blocker is NULL, it won't be set again as this thread "owns" | ||
| 764 | * the lock and is the only one that might try to claim the lock. | ||
| 765 | * | ||
| 766 | * We use acquire/release to manage fl_blocker so that we can | ||
| 767 | * optimize away taking the blocked_lock_lock in many cases. | ||
| 768 | * | ||
| 769 | * The smp_load_acquire guarantees two things: | ||
| 770 | * | ||
| 771 | * 1/ that fl_blocked_requests can be tested locklessly. If something | ||
| 772 | * was recently added to that list it must have been in a locked region | ||
| 773 | * *before* the locked region when fl_blocker was set to NULL. | ||
| 774 | * | ||
| 775 | * 2/ that no other thread is accessing 'waiter', so it is safe to free | ||
| 776 | * it. __locks_wake_up_blocks is careful not to touch waiter after | ||
| 777 | * fl_blocker is released. | ||
| 778 | * | ||
| 779 | * If a lockless check of fl_blocker shows it to be NULL, we know that | ||
| 780 | * no new locks can be inserted into its fl_blocked_requests list, and | ||
| 781 | * can avoid doing anything further if the list is empty. | ||
| 782 | */ | ||
| 783 | if (!smp_load_acquire(&waiter->fl_blocker) && | ||
| 784 | list_empty(&waiter->fl_blocked_requests)) | ||
| 785 | return status; | ||
| 786 | |||
| 756 | spin_lock(&blocked_lock_lock); | 787 | spin_lock(&blocked_lock_lock); |
| 757 | if (waiter->fl_blocker) | 788 | if (waiter->fl_blocker) |
| 758 | status = 0; | 789 | status = 0; |
| 759 | __locks_wake_up_blocks(waiter); | 790 | __locks_wake_up_blocks(waiter); |
| 760 | __locks_delete_block(waiter); | 791 | __locks_delete_block(waiter); |
| 792 | |||
| 793 | /* | ||
| 794 | * The setting of fl_blocker to NULL marks the "done" point in deleting | ||
| 795 | * a block. Paired with acquire at the top of this function. | ||
| 796 | */ | ||
| 797 | smp_store_release(&waiter->fl_blocker, NULL); | ||
| 761 | spin_unlock(&blocked_lock_lock); | 798 | spin_unlock(&blocked_lock_lock); |
| 762 | return status; | 799 | return status; |
| 763 | } | 800 | } |
| @@ -1350,7 +1387,8 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) · 586 unmodified lines | |||
| 1350 | error = posix_lock_inode(inode, fl, NULL); | 1387 | error = posix_lock_inode(inode, fl, NULL); |
| 1351 | if (error != FILE_LOCK_DEFERRED) | 1388 | if (error != FILE_LOCK_DEFERRED) |
| 1352 | break; | 1389 | break; |
| 1353 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_blocker); | 1390 | error = wait_event_interruptible(fl->fl_wait, |
| 1391 | list_empty(&fl->fl_blocked_member)); | ||
| 1354 | if (error) | 1392 | if (error) |
| 1355 | break; | 1393 | break; |
| 1356 | } | 1394 | } |
| @@ -1435,7 +1473,8 @@ int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start, · 78 unmodified lines | |||
| 1435 | error = posix_lock_inode(inode, &fl, NULL); | 1473 | error = posix_lock_inode(inode, &fl, NULL); |
| 1436 | if (error != FILE_LOCK_DEFERRED) | 1474 | if (error != FILE_LOCK_DEFERRED) |
| 1437 | break; | 1475 | break; |
| 1438 | error = wait_event_interruptible(fl.fl_wait, !fl.fl_blocker); | 1476 | error = wait_event_interruptible(fl.fl_wait, |
| 1477 | list_empty(&fl.fl_blocked_member)); | ||
| 1439 | if (!error) { | 1478 | if (!error) { |
| 1440 | /* | 1479 | /* |
| 1441 | * If we've been sleeping someone might have | 1480 | * If we've been sleeping someone might have |
| @@ -1638,7 +1677,8 @@ restart: · 196 unmodified lines | |||
| 1638 | 1677 | ||
| 1639 | locks_dispose_list(&dispose); | 1678 | locks_dispose_list(&dispose); |
| 1640 | error = wait_event_interruptible_timeout(new_fl->fl_wait, | 1679 | error = wait_event_interruptible_timeout(new_fl->fl_wait, |
| 1641 | !new_fl->fl_blocker, break_time); | 1680 | list_empty(&new_fl->fl_blocked_member), |
| 1681 | break_time); | ||
| 1642 | 1682 | ||
| 1643 | percpu_down_read(&file_rwsem); | 1683 | percpu_down_read(&file_rwsem); |
| 1644 | spin_lock(&ctx->flc_lock); | 1684 | spin_lock(&ctx->flc_lock); |
| @@ -2122,7 +2162,8 @@ static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) · 477 unmodified lines | |||
| 2122 | error = flock_lock_inode(inode, fl); | 2162 | error = flock_lock_inode(inode, fl); |
| 2123 | if (error != FILE_LOCK_DEFERRED) | 2163 | if (error != FILE_LOCK_DEFERRED) |
| 2124 | break; | 2164 | break; |
| 2125 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_blocker); | 2165 | error = wait_event_interruptible(fl->fl_wait, |
| 2166 | list_empty(&fl->fl_blocked_member)); | ||
| 2126 | if (error) | 2167 | if (error) |
| 2127 | break; | 2168 | break; |
| 2128 | } | 2169 | } |
| @@ -2399,7 +2440,8 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd, · 270 unmodified lines | |||
| 2399 | error = vfs_lock_file(filp, cmd, fl, NULL); | 2440 | error = vfs_lock_file(filp, cmd, fl, NULL); |
| 2400 | if (error != FILE_LOCK_DEFERRED) | 2441 | if (error != FILE_LOCK_DEFERRED) |
| 2401 | break; | 2442 | break; |
| 2402 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_blocker); | 2443 | error = wait_event_interruptible(fl->fl_wait, |
| 2444 | list_empty(&fl->fl_blocked_member)); | ||
| 2403 | if (error) | 2445 | if (error) |
| 2404 | break; | 2446 | break; |
| 2405 | } | 2447 | } |
| @@ -153,6 +153,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) · 152 unmodified lines | |||
| 153 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) | 153 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) |
| 154 | goto error_0; | 154 | goto error_0; |
| 155 | 155 | ||
| 156 | clp->cl_minorversion = cl_init->minorversion; | ||
| 156 | clp->cl_nfs_mod = cl_init->nfs_mod; | 157 | clp->cl_nfs_mod = cl_init->nfs_mod; |
| 157 | if (!try_module_get(clp->cl_nfs_mod->owner)) | 158 | if (!try_module_get(clp->cl_nfs_mod->owner)) |
| 158 | goto error_dealloc; | 159 | goto error_dealloc; |
| @@ -832,6 +832,8 @@ static int nfs_parse_source(struct fs_context *fc, · 831 unmodified lines | |||
| 832 | if (len > maxnamlen) | 832 | if (len > maxnamlen) |
| 833 | goto out_hostname; | 833 | goto out_hostname; |
| 834 | 834 | ||
| 835 | kfree(ctx->nfs_server.hostname); | ||
| 836 | |||
| 835 | /* N.B. caller will free nfs_server.hostname in all cases */ | 837 | /* N.B. caller will free nfs_server.hostname in all cases */ |
| 836 | ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL); | 838 | ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL); |
| 837 | if (!ctx->nfs_server.hostname) | 839 | if (!ctx->nfs_server.hostname) |
| @@ -1240,6 +1242,13 @@ static int nfs_fs_context_validate(struct fs_context *fc) · 402 unmodified lines | |||
| 1240 | } | 1242 | } |
| 1241 | ctx->nfs_mod = nfs_mod; | 1243 | ctx->nfs_mod = nfs_mod; |
| 1242 | } | 1244 | } |
| 1245 | |||
| 1246 | /* Ensure the filesystem context has the correct fs_type */ | ||
| 1247 | if (fc->fs_type != ctx->nfs_mod->nfs_fs) { | ||
| 1248 | module_put(fc->fs_type->owner); | ||
| 1249 | __module_get(ctx->nfs_mod->nfs_fs->owner); | ||
| 1250 | fc->fs_type = ctx->nfs_mod->nfs_fs; | ||
| 1251 | } | ||
| 1243 | return 0; | 1252 | return 0; |
| 1244 | 1253 | ||
| 1245 | out_no_device_name: | 1254 | out_no_device_name: |
| @@ -31,6 +31,7 @@ static DEFINE_SPINLOCK(nfs_fscache_keys_lock); · 30 unmodified lines | |||
| 31 | struct nfs_server_key { | 31 | struct nfs_server_key { |
| 32 | struct { | 32 | struct { |
| 33 | uint16_t nfsversion; /* NFS protocol version */ | 33 | uint16_t nfsversion; /* NFS protocol version */ |
| 34 | uint32_t minorversion; /* NFSv4 minor version */ | ||
| 34 | uint16_t family; /* address family */ | 35 | uint16_t family; /* address family */ |
| 35 | __be16 port; /* IP port */ | 36 | __be16 port; /* IP port */ |
| 36 | } hdr; | 37 | } hdr; |
| @@ -55,6 +56,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp) · 18 unmodified lines | |||
| 55 | 56 | ||
| 56 | memset(&key, 0, sizeof(key)); | 57 | memset(&key, 0, sizeof(key)); |
| 57 | key.hdr.nfsversion = clp->rpc_ops->version; | 58 | key.hdr.nfsversion = clp->rpc_ops->version; |
| 59 | key.hdr.minorversion = clp->cl_minorversion; | ||
| 58 | key.hdr.family = clp->cl_addr.ss_family; | 60 | key.hdr.family = clp->cl_addr.ss_family; |
| 59 | 61 | ||
| 60 | switch (clp->cl_addr.ss_family) { | 62 | switch (clp->cl_addr.ss_family) { |
| @@ -153,7 +153,7 @@ struct vfsmount *nfs_d_automount(struct path *path) · 152 unmodified lines | |||
| 153 | /* Open a new filesystem context, transferring parameters from the | 153 | /* Open a new filesystem context, transferring parameters from the |
| 154 | * parent superblock, including the network namespace. | 154 | * parent superblock, including the network namespace. |
| 155 | */ | 155 | */ |
| 156 | fc = fs_context_for_submount(&nfs_fs_type, path->dentry); | 156 | fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry); |
| 157 | if (IS_ERR(fc)) | 157 | if (IS_ERR(fc)) |
| 158 | return ERR_CAST(fc); | 158 | return ERR_CAST(fc); |
| 159 | 159 | ||
| @@ -216,7 +216,6 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) · 215 unmodified lines | |||
| 216 | INIT_LIST_HEAD(&clp->cl_ds_clients); | 216 | INIT_LIST_HEAD(&clp->cl_ds_clients); |
| 217 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); | 217 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); |
| 218 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | 218 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; |
| 219 | clp->cl_minorversion = cl_init->minorversion; | ||
| 220 | clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; | 219 | clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; |
| 221 | clp->cl_mig_gen = 1; | 220 | clp->cl_mig_gen = 1; |
| 222 | #if IS_ENABLED(CONFIG_NFS_V4_1) | 221 | #if IS_ENABLED(CONFIG_NFS_V4_1) |
| @@ -93,6 +93,7 @@ config OVERLAY_FS_XINO_AUTO · 92 unmodified lines | |||
| 93 | bool "Overlayfs: auto enable inode number mapping" | 93 | bool "Overlayfs: auto enable inode number mapping" |
| 94 | default n | 94 | default n |
| 95 | depends on OVERLAY_FS | 95 | depends on OVERLAY_FS |
| 96 | depends on 64BIT | ||
| 96 | help | 97 | help |
| 97 | If this config option is enabled then overlay filesystems will use | 98 | If this config option is enabled then overlay filesystems will use |
| 98 | unused high bits in undelying filesystem inode numbers to map all | 99 | unused high bits in undelying filesystem inode numbers to map all |
| @@ -244,6 +244,9 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req) · 243 unmodified lines | |||
| 244 | if (iocb->ki_flags & IOCB_WRITE) { | 244 | if (iocb->ki_flags & IOCB_WRITE) { |
| 245 | struct inode *inode = file_inode(orig_iocb->ki_filp); | 245 | struct inode *inode = file_inode(orig_iocb->ki_filp); |
| 246 | 246 | ||
| 247 | /* Actually acquired in ovl_write_iter() */ | ||
| 248 | __sb_writers_acquired(file_inode(iocb->ki_filp)->i_sb, | ||
| 249 | SB_FREEZE_WRITE); | ||
| 247 | file_end_write(iocb->ki_filp); | 250 | file_end_write(iocb->ki_filp); |
| 248 | ovl_copyattr(ovl_inode_real(inode), inode); | 251 | ovl_copyattr(ovl_inode_real(inode), inode); |
| 249 | } | 252 | } |
| @@ -346,6 +349,9 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) · 96 unmodified lines | |||
| 346 | goto out; | 349 | goto out; |
| 347 | 350 | ||
| 348 | file_start_write(real.file); | 351 | file_start_write(real.file); |
| 352 | /* Pacify lockdep, same trick as done in aio_write() */ | ||
| 353 | __sb_writers_release(file_inode(real.file)->i_sb, | ||
| 354 | SB_FREEZE_WRITE); | ||
| 349 | aio_req->fd = real; | 355 | aio_req->fd = real; |
| 350 | real.flags = 0; | 356 | real.flags = 0; |
| 351 | aio_req->orig_iocb = iocb; | 357 | aio_req->orig_iocb = iocb; |
| @@ -318,7 +318,12 @@ static inline unsigned int ovl_xino_bits(struct super_block *sb) · 317 unmodified lines | |||
| 318 | return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0; | 318 | return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | static inline int ovl_inode_lock(struct inode *inode) | 321 | static inline void ovl_inode_lock(struct inode *inode) |
| 322 | { | ||
| 323 | mutex_lock(&OVL_I(inode)->lock); | ||
| 324 | } | ||
| 325 | |||
| 326 | static inline int ovl_inode_lock_interruptible(struct inode *inode) | ||
| 322 | { | 327 | { |
| 323 | return mutex_lock_interruptible(&OVL_I(inode)->lock); | 328 | return mutex_lock_interruptible(&OVL_I(inode)->lock); |
| 324 | } | 329 | } |
| @@ -1411,6 +1411,8 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, · 1410 unmodified lines | |||
| 1411 | if (ofs->config.xino == OVL_XINO_ON) | 1411 | if (ofs->config.xino == OVL_XINO_ON) |
| 1412 | pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n"); | 1412 | pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n"); |
| 1413 | ofs->xino_mode = 0; | 1413 | ofs->xino_mode = 0; |
| 1414 | } else if (ofs->config.xino == OVL_XINO_OFF) { | ||
| 1415 | ofs->xino_mode = -1; | ||
| 1414 | } else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) { | 1416 | } else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) { |
| 1415 | /* | 1417 | /* |
| 1416 | * This is a roundup of number of bits needed for encoding | 1418 | * This is a roundup of number of bits needed for encoding |
| @@ -1623,8 +1625,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) · 206 unmodified lines | |||
| 1623 | sb->s_stack_depth = 0; | 1625 | sb->s_stack_depth = 0; |
| 1624 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 1626 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
| 1625 | /* Assume underlaying fs uses 32bit inodes unless proven otherwise */ | 1627 | /* Assume underlaying fs uses 32bit inodes unless proven otherwise */ |
| 1626 | if (ofs->config.xino != OVL_XINO_OFF) | 1628 | if (ofs->config.xino != OVL_XINO_OFF) { |
| 1627 | ofs->xino_mode = BITS_PER_LONG - 32; | 1629 | ofs->xino_mode = BITS_PER_LONG - 32; |
| 1630 | if (!ofs->xino_mode) { | ||
| 1631 | pr_warn("xino not supported on 32bit kernel, falling back to xino=off.\n"); | ||
| 1632 | ofs->config.xino = OVL_XINO_OFF; | ||
| 1633 | } | ||
| 1634 | } | ||
| 1628 | 1635 | ||
| 1629 | /* alloc/destroy_inode needed for setting up traps in inode cache */ | 1636 | /* alloc/destroy_inode needed for setting up traps in inode cache */ |
| 1630 | sb->s_op = &ovl_super_operations; | 1637 | sb->s_op = &ovl_super_operations; |
| @@ -509,7 +509,7 @@ int ovl_copy_up_start(struct dentry *dentry, int flags) · 508 unmodified lines | |||
| 509 | struct inode *inode = d_inode(dentry); | 509 | struct inode *inode = d_inode(dentry); |
| 510 | int err; | 510 | int err; |
| 511 | 511 | ||
| 512 | err = ovl_inode_lock(inode); | 512 | err = ovl_inode_lock_interruptible(inode); |
| 513 | if (!err && ovl_already_copied_up_locked(dentry, flags)) { | 513 | if (!err && ovl_already_copied_up_locked(dentry, flags)) { |
| 514 | err = 1; /* Already copied up */ | 514 | err = 1; /* Already copied up */ |
| 515 | ovl_inode_unlock(inode); | 515 | ovl_inode_unlock(inode); |
| @@ -764,7 +764,7 @@ int ovl_nlink_start(struct dentry *dentry) · 248 unmodified lines | |||
| 764 | return err; | 764 | return err; |
| 765 | } | 765 | } |
| 766 | 766 | ||
| 767 | err = ovl_inode_lock(inode); | 767 | err = ovl_inode_lock_interruptible(inode); |
| 768 | if (err) | 768 | if (err) |
| 769 | return err; | 769 | return err; |
| 770 | 770 | ||
| @@ -178,7 +178,8 @@ static void zonefs_update_stats(struct inode *inode, loff_t new_isize) · 177 unmodified lines | |||
| 178 | * amount of readable data in the zone. | 178 | * amount of readable data in the zone. |
| 179 | */ | 179 | */ |
| 180 | static loff_t zonefs_check_zone_condition(struct inode *inode, | 180 | static loff_t zonefs_check_zone_condition(struct inode *inode, |
| 181 | struct blk_zone *zone, bool warn) | 181 | struct blk_zone *zone, bool warn, |
| 182 | bool mount) | ||
| 182 | { | 183 | { |
| 183 | struct zonefs_inode_info *zi = ZONEFS_I(inode); | 184 | struct zonefs_inode_info *zi = ZONEFS_I(inode); |
| 184 | 185 | ||
| @@ -196,13 +197,26 @@ static loff_t zonefs_check_zone_condition(struct inode *inode, · 11 unmodified lines | |||
| 196 | zone->wp = zone->start; | 197 | zone->wp = zone->start; |
| 197 | return 0; | 198 | return 0; |
| 198 | case BLK_ZONE_COND_READONLY: | 199 | case BLK_ZONE_COND_READONLY: |
| 199 | /* Do not allow writes in read-only zones */ | 200 | /* |
| 201 | * The write pointer of read-only zones is invalid. If such a | ||
| 202 | * zone is found during mount, the file size cannot be retrieved | ||
| 203 | * so we treat the zone as offline (mount == true case). | ||
| 204 | * Otherwise, keep the file size as it was when last updated | ||
| 205 | * so that the user can recover data. In both cases, writes are | ||
| 206 | * always disabled for the zone. | ||
| 207 | */ | ||
| 200 | if (warn) | 208 | if (warn) |
| 201 | zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n", | 209 | zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n", |
| 202 | inode->i_ino); | 210 | inode->i_ino); |
| 203 | inode->i_flags |= S_IMMUTABLE; | 211 | inode->i_flags |= S_IMMUTABLE; |
| 212 | if (mount) { | ||
| 213 | zone->cond = BLK_ZONE_COND_OFFLINE; | ||
| 214 | inode->i_mode &= ~0777; | ||
| 215 | zone->wp = zone->start; | ||
| 216 | return 0; | ||
| 217 | } | ||
| 204 | inode->i_mode &= ~0222; | 218 | inode->i_mode &= ~0222; |
| 205 | /* fallthrough */ | 219 | return i_size_read(inode); |
| 206 | default: | 220 | default: |
| 207 | if (zi->i_ztype == ZONEFS_ZTYPE_CNV) | 221 | if (zi->i_ztype == ZONEFS_ZTYPE_CNV) |
| 208 | return zi->i_max_size; | 222 | return zi->i_max_size; |
| @@ -231,7 +245,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, · 22 unmodified lines | |||
| 231 | * as there is no inconsistency between the inode size and the amount of | 245 | * as there is no inconsistency between the inode size and the amount of |
| 232 | * data writen in the zone (data_size). | 246 | * data writen in the zone (data_size). |
| 233 | */ | 247 | */ |
| 234 | data_size = zonefs_check_zone_condition(inode, zone, true); | 248 | data_size = zonefs_check_zone_condition(inode, zone, true, false); |
| 235 | isize = i_size_read(inode); | 249 | isize = i_size_read(inode); |
| 236 | if (zone->cond != BLK_ZONE_COND_OFFLINE && | 250 | if (zone->cond != BLK_ZONE_COND_OFFLINE && |
| 237 | zone->cond != BLK_ZONE_COND_READONLY && | 251 | zone->cond != BLK_ZONE_COND_READONLY && |
| @@ -274,7 +288,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, · 36 unmodified lines | |||
| 274 | if (zone->cond != BLK_ZONE_COND_OFFLINE) { | 288 | if (zone->cond != BLK_ZONE_COND_OFFLINE) { |
| 275 | zone->cond = BLK_ZONE_COND_OFFLINE; | 289 | zone->cond = BLK_ZONE_COND_OFFLINE; |
| 276 | data_size = zonefs_check_zone_condition(inode, zone, | 290 | data_size = zonefs_check_zone_condition(inode, zone, |
| 277 | false); | 291 | false, false); |
| 278 | } | 292 | } |
| 279 | } else if (zone->cond == BLK_ZONE_COND_READONLY || | 293 | } else if (zone->cond == BLK_ZONE_COND_READONLY || |
| 280 | sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_ZRO) { | 294 | sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_ZRO) { |
| @@ -283,7 +297,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, · 2 unmodified lines | |||
| 283 | if (zone->cond != BLK_ZONE_COND_READONLY) { | 297 | if (zone->cond != BLK_ZONE_COND_READONLY) { |
| 284 | zone->cond = BLK_ZONE_COND_READONLY; | 298 | zone->cond = BLK_ZONE_COND_READONLY; |
| 285 | data_size = zonefs_check_zone_condition(inode, zone, | 299 | data_size = zonefs_check_zone_condition(inode, zone, |
| 286 | false); | 300 | false, false); |
| 287 | } | 301 | } |
| 288 | } | 302 | } |
| 289 | 303 | ||
| @@ -975,7 +989,7 @@ static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone, · 685 unmodified lines | |||
| 975 | zi->i_zsector = zone->start; | 989 | zi->i_zsector = zone->start; |
| 976 | zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE, | 990 | zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE, |
| 977 | zone->len << SECTOR_SHIFT); | 991 | zone->len << SECTOR_SHIFT); |
| 978 | zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true); | 992 | zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true, true); |
| 979 | 993 | ||
| 980 | inode->i_uid = sbi->s_uid; | 994 | inode->i_uid = sbi->s_uid; |
| 981 | inode->i_gid = sbi->s_gid; | 995 | inode->i_gid = sbi->s_gid; |
| @@ -122,8 +122,8 @@ · 121 unmodified lines | |||
| 122 | #define IMX8MN_CLK_I2C1 105 | 122 | #define IMX8MN_CLK_I2C1 105 |
| 123 | #define IMX8MN_CLK_I2C2 106 | 123 | #define IMX8MN_CLK_I2C2 106 |
| 124 | #define IMX8MN_CLK_I2C3 107 | 124 | #define IMX8MN_CLK_I2C3 107 |
| 125 | #define IMX8MN_CLK_I2C4 118 | 125 | #define IMX8MN_CLK_I2C4 108 |
| 126 | #define IMX8MN_CLK_UART1 119 | 126 | #define IMX8MN_CLK_UART1 109 |
| 127 | #define IMX8MN_CLK_UART2 110 | 127 | #define IMX8MN_CLK_UART2 110 |
| 128 | #define IMX8MN_CLK_UART3 111 | 128 | #define IMX8MN_CLK_UART3 111 |
| 129 | #define IMX8MN_CLK_UART4 112 | 129 | #define IMX8MN_CLK_UART4 112 |
| @@ -69,19 +69,23 @@ struct dmar_pci_notify_info { · 68 unmodified lines | |||
| 69 | extern struct rw_semaphore dmar_global_lock; | 69 | extern struct rw_semaphore dmar_global_lock; |
| 70 | extern struct list_head dmar_drhd_units; | 70 | extern struct list_head dmar_drhd_units; |
| 71 | 71 | ||
| 72 | #define for_each_drhd_unit(drhd) \ | 72 | #define for_each_drhd_unit(drhd) \ |
| 73 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) | 73 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ |
| 74 | dmar_rcu_check()) | ||
| 74 | 75 | ||
| 75 | #define for_each_active_drhd_unit(drhd) \ | 76 | #define for_each_active_drhd_unit(drhd) \ |
| 76 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ | 77 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ |
| 78 | dmar_rcu_check()) \ | ||
| 77 | if (drhd->ignored) {} else | 79 | if (drhd->ignored) {} else |
| 78 | 80 | ||
| 79 | #define for_each_active_iommu(i, drhd) \ | 81 | #define for_each_active_iommu(i, drhd) \ |
| 80 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ | 82 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ |
| 83 | dmar_rcu_check()) \ | ||
| 81 | if (i=drhd->iommu, drhd->ignored) {} else | 84 | if (i=drhd->iommu, drhd->ignored) {} else |
| 82 | 85 | ||
| 83 | #define for_each_iommu(i, drhd) \ | 86 | #define for_each_iommu(i, drhd) \ |
| 84 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ | 87 | list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ |
| 88 | dmar_rcu_check()) \ | ||
| 85 | if (i=drhd->iommu, 0) {} else | 89 | if (i=drhd->iommu, 0) {} else |
| 86 | 90 | ||
| 87 | static inline bool dmar_rcu_check(void) | 91 | static inline bool dmar_rcu_check(void) |
| @@ -28,8 +28,6 @@ int dsa_8021q_rx_switch_id(u16 vid); · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | int dsa_8021q_rx_source_port(u16 vid); | 29 | int dsa_8021q_rx_source_port(u16 vid); |
| 30 | 30 | ||
| 31 | struct sk_buff *dsa_8021q_remove_header(struct sk_buff *skb); | ||
| 32 | |||
| 33 | #else | 31 | #else |
| 34 | 32 | ||
| 35 | int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int index, | 33 | int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int index, |
| @@ -64,11 +62,6 @@ int dsa_8021q_rx_source_port(u16 vid) · 28 unmodified lines | |||
| 64 | return 0; | 62 | return 0; |
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | struct sk_buff *dsa_8021q_remove_header(struct sk_buff *skb) | ||
| 68 | { | ||
| 69 | return NULL; | ||
| 70 | } | ||
| 71 | |||
| 72 | #endif /* IS_ENABLED(CONFIG_NET_DSA_TAG_8021Q) */ | 65 | #endif /* IS_ENABLED(CONFIG_NET_DSA_TAG_8021Q) */ |
| 73 | 66 | ||
| 74 | #endif /* _NET_DSA_8021Q_H */ | 67 | #endif /* _NET_DSA_8021Q_H */ |
| @@ -85,6 +85,7 @@ extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); · 84 unmodified lines | |||
| 85 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); | 85 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); |
| 86 | extern void set_close_on_exec(unsigned int fd, int flag); | 86 | extern void set_close_on_exec(unsigned int fd, int flag); |
| 87 | extern bool get_close_on_exec(unsigned int fd); | 87 | extern bool get_close_on_exec(unsigned int fd); |
| 88 | extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile); | ||
| 88 | extern int get_unused_fd_flags(unsigned flags); | 89 | extern int get_unused_fd_flags(unsigned flags); |
| 89 | extern void put_unused_fd(unsigned int fd); | 90 | extern void put_unused_fd(unsigned int fd); |
| 90 | 91 | ||
| @@ -698,6 +698,7 @@ struct inode { · 697 unmodified lines | |||
| 698 | struct rcu_head i_rcu; | 698 | struct rcu_head i_rcu; |
| 699 | }; | 699 | }; |
| 700 | atomic64_t i_version; | 700 | atomic64_t i_version; |
| 701 | atomic64_t i_sequence; /* see futex */ | ||
| 701 | atomic_t i_count; | 702 | atomic_t i_count; |
| 702 | atomic_t i_dio_count; | 703 | atomic_t i_dio_count; |
| 703 | atomic_t i_writecount; | 704 | atomic_t i_writecount; |
| @@ -31,23 +31,26 @@ struct task_struct; · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | union futex_key { | 32 | union futex_key { |
| 33 | struct { | 33 | struct { |
| 34 | u64 i_seq; | ||
| 34 | unsigned long pgoff; | 35 | unsigned long pgoff; |
| 35 | struct inode *inode; | 36 | unsigned int offset; |
| 36 | int offset; | ||
| 37 | } shared; | 37 | } shared; |
| 38 | struct { | 38 | struct { |
| 39 | union { | ||
| 40 | struct mm_struct *mm; | ||
| 41 | u64 __tmp; | ||
| 42 | }; | ||
| 39 | unsigned long address; | 43 | unsigned long address; |
| 40 | struct mm_struct *mm; | 44 | unsigned int offset; |
| 41 | int offset; | ||
| 42 | } private; | 45 | } private; |
| 43 | struct { | 46 | struct { |
| 47 | u64 ptr; | ||
| 44 | unsigned long word; | 48 | unsigned long word; |
| 45 | void *ptr; | 49 | unsigned int offset; |
| 46 | int offset; | ||
| 47 | } both; | 50 | } both; |
| 48 | }; | 51 | }; |
| 49 | 52 | ||
| 50 | #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = NULL } } | 53 | #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = 0ULL } } |
| 51 | 54 | ||
| 52 | #ifdef CONFIG_FUTEX | 55 | #ifdef CONFIG_FUTEX |
| 53 | enum { | 56 | enum { |
| @@ -245,18 +245,6 @@ static inline bool disk_part_scan_enabled(struct gendisk *disk) · 244 unmodified lines | |||
| 245 | !(disk->flags & GENHD_FL_NO_PART_SCAN); | 245 | !(disk->flags & GENHD_FL_NO_PART_SCAN); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static inline bool disk_has_partitions(struct gendisk *disk) | ||
| 249 | { | ||
| 250 | bool ret = false; | ||
| 251 | |||
| 252 | rcu_read_lock(); | ||
| 253 | if (rcu_dereference(disk->part_tbl)->len > 1) | ||
| 254 | ret = true; | ||
| 255 | rcu_read_unlock(); | ||
| 256 | |||
| 257 | return ret; | ||
| 258 | } | ||
| 259 | |||
| 260 | static inline dev_t disk_devt(struct gendisk *disk) | 248 | static inline dev_t disk_devt(struct gendisk *disk) |
| 261 | { | 249 | { |
| 262 | return MKDEV(disk->major, disk->first_minor); | 250 | return MKDEV(disk->major, disk->first_minor); |
| @@ -298,6 +286,7 @@ extern void disk_part_iter_exit(struct disk_part_iter *piter); · 35 unmodified lines | |||
| 298 | 286 | ||
| 299 | extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, | 287 | extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, |
| 300 | sector_t sector); | 288 | sector_t sector); |
| 289 | bool disk_has_partitions(struct gendisk *disk); | ||
| 301 | 290 | ||
| 302 | /* | 291 | /* |
| 303 | * Macros to operate on percpu disk statistics: | 292 | * Macros to operate on percpu disk statistics: |
| @@ -123,6 +123,8 @@ · 122 unmodified lines | |||
| 123 | 123 | ||
| 124 | #define dmar_readq(a) readq(a) | 124 | #define dmar_readq(a) readq(a) |
| 125 | #define dmar_writeq(a,v) writeq(v,a) | 125 | #define dmar_writeq(a,v) writeq(v,a) |
| 126 | #define dmar_readl(a) readl(a) | ||
| 127 | #define dmar_writel(a, v) writel(v, a) | ||
| 126 | 128 | ||
| 127 | #define DMAR_VER_MAJOR(v) (((v) & 0xf0) >> 4) | 129 | #define DMAR_VER_MAJOR(v) (((v) & 0xf0) >> 4) |
| 128 | #define DMAR_VER_MINOR(v) ((v) & 0x0f) | 130 | #define DMAR_VER_MINOR(v) ((v) & 0x0f) |
| @@ -333,6 +333,7 @@ struct mmc_host { · 332 unmodified lines | |||
| 333 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ | 333 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ |
| 334 | MMC_CAP_UHS_DDR50) | 334 | MMC_CAP_UHS_DDR50) |
| 335 | #define MMC_CAP_SYNC_RUNTIME_PM (1 << 21) /* Synced runtime PM suspends. */ | 335 | #define MMC_CAP_SYNC_RUNTIME_PM (1 << 21) /* Synced runtime PM suspends. */ |
| 336 | #define MMC_CAP_NEED_RSP_BUSY (1 << 22) /* Commands with R1B can't use R1. */ | ||
| 336 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ | 337 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ |
| 337 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ | 338 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ |
| 338 | #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ | 339 | #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ |
| @@ -115,6 +115,19 @@ static inline void nl_set_extack_cookie_u64(struct netlink_ext_ack *extack, · 114 unmodified lines | |||
| 115 | { | 115 | { |
| 116 | u64 __cookie = cookie; | 116 | u64 __cookie = cookie; |
| 117 | 117 | ||
| 118 | if (!extack) | ||
| 119 | return; | ||
| 120 | memcpy(extack->cookie, &__cookie, sizeof(__cookie)); | ||
| 121 | extack->cookie_len = sizeof(__cookie); | ||
| 122 | } | ||
| 123 | |||
| 124 | static inline void nl_set_extack_cookie_u32(struct netlink_ext_ack *extack, | ||
| 125 | u32 cookie) | ||
| 126 | { | ||
| 127 | u32 __cookie = cookie; | ||
| 128 | |||
| 129 | if (!extack) | ||
| 130 | return; | ||
| 118 | memcpy(extack->cookie, &__cookie, sizeof(__cookie)); | 131 | memcpy(extack->cookie, &__cookie, sizeof(__cookie)); |
| 119 | extack->cookie_len = sizeof(__cookie); | 132 | extack->cookie_len = sizeof(__cookie); |
| 120 | } | 133 | } |
| @@ -11,17 +11,17 @@ struct of_device_id; · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #if defined(CONFIG_COMMON_CLK) && defined(CONFIG_OF) | 12 | #if defined(CONFIG_COMMON_CLK) && defined(CONFIG_OF) |
| 13 | 13 | ||
| 14 | unsigned int of_clk_get_parent_count(struct device_node *np); | 14 | unsigned int of_clk_get_parent_count(const struct device_node *np); |
| 15 | const char *of_clk_get_parent_name(struct device_node *np, int index); | 15 | const char *of_clk_get_parent_name(const struct device_node *np, int index); |
| 16 | void of_clk_init(const struct of_device_id *matches); | 16 | void of_clk_init(const struct of_device_id *matches); |
| 17 | 17 | ||
| 18 | #else /* !CONFIG_COMMON_CLK || !CONFIG_OF */ | 18 | #else /* !CONFIG_COMMON_CLK || !CONFIG_OF */ |
| 19 | 19 | ||
| 20 | static inline unsigned int of_clk_get_parent_count(struct device_node *np) | 20 | static inline unsigned int of_clk_get_parent_count(const struct device_node *np) |
| 21 | { | 21 | { |
| 22 | return 0; | 22 | return 0; |
| 23 | } | 23 | } |
| 24 | static inline const char *of_clk_get_parent_name(struct device_node *np, | 24 | static inline const char *of_clk_get_parent_name(const struct device_node *np, |
| 25 | int index) | 25 | int index) |
| 26 | { | 26 | { |
| 27 | return NULL; | 27 | return NULL; |
| @@ -311,7 +311,7 @@ static inline int TestClearPage##uname(struct page *page) { return 0; } · 310 unmodified lines | |||
| 311 | 311 | ||
| 312 | __PAGEFLAG(Locked, locked, PF_NO_TAIL) | 312 | __PAGEFLAG(Locked, locked, PF_NO_TAIL) |
| 313 | PAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) __CLEARPAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) | 313 | PAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) __CLEARPAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) |
| 314 | PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND) | 314 | PAGEFLAG(Error, error, PF_NO_TAIL) TESTCLEARFLAG(Error, error, PF_NO_TAIL) |
| 315 | PAGEFLAG(Referenced, referenced, PF_HEAD) | 315 | PAGEFLAG(Referenced, referenced, PF_HEAD) |
| 316 | TESTCLEARFLAG(Referenced, referenced, PF_HEAD) | 316 | TESTCLEARFLAG(Referenced, referenced, PF_HEAD) |
| 317 | __SETPAGEFLAG(Referenced, referenced, PF_HEAD) | 317 | __SETPAGEFLAG(Referenced, referenced, PF_HEAD) |
| @@ -645,8 +645,8 @@ typedef unsigned char *sk_buff_data_t; · 644 unmodified lines | |||
| 645 | * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware | 645 | * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware |
| 646 | * @tc_skip_classify: do not classify packet. set by IFB device | 646 | * @tc_skip_classify: do not classify packet. set by IFB device |
| 647 | * @tc_at_ingress: used within tc_classify to distinguish in/egress | 647 | * @tc_at_ingress: used within tc_classify to distinguish in/egress |
| 648 | * @tc_redirected: packet was redirected by a tc action | 648 | * @redirected: packet was redirected by packet classifier |
| 649 | * @tc_from_ingress: if tc_redirected, tc_at_ingress at time of redirect | 649 | * @from_ingress: packet was redirected from the ingress path |
| 650 | * @peeked: this packet has been seen already, so stats have been | 650 | * @peeked: this packet has been seen already, so stats have been |
| 651 | * done for it, don't do them again | 651 | * done for it, don't do them again |
| 652 | * @nf_trace: netfilter packet trace flag | 652 | * @nf_trace: netfilter packet trace flag |
| @@ -848,8 +848,10 @@ struct sk_buff { · 195 unmodified lines | |||
| 848 | #ifdef CONFIG_NET_CLS_ACT | 848 | #ifdef CONFIG_NET_CLS_ACT |
| 849 | __u8 tc_skip_classify:1; | 849 | __u8 tc_skip_classify:1; |
| 850 | __u8 tc_at_ingress:1; | 850 | __u8 tc_at_ingress:1; |
| 851 | __u8 tc_redirected:1; | 851 | #endif |
| 852 | __u8 tc_from_ingress:1; | 852 | #ifdef CONFIG_NET_REDIRECT |
| 853 | __u8 redirected:1; | ||
| 854 | __u8 from_ingress:1; | ||
| 853 | #endif | 855 | #endif |
| 854 | #ifdef CONFIG_TLS_DEVICE | 856 | #ifdef CONFIG_TLS_DEVICE |
| 855 | __u8 decrypted:1; | 857 | __u8 decrypted:1; |
| @@ -4571,5 +4573,31 @@ static inline __wsum lco_csum(struct sk_buff *skb) · 3715 unmodified lines | |||
| 4571 | return csum_partial(l4_hdr, csum_start - l4_hdr, partial); | 4573 | return csum_partial(l4_hdr, csum_start - l4_hdr, partial); |
| 4572 | } | 4574 | } |
| 4573 | 4575 | ||
| 4576 | static inline bool skb_is_redirected(const struct sk_buff *skb) | ||
| 4577 | { | ||
| 4578 | #ifdef CONFIG_NET_REDIRECT | ||
| 4579 | return skb->redirected; | ||
| 4580 | #else | ||
| 4581 | return false; | ||
| 4582 | #endif | ||
| 4583 | } | ||
| 4584 | |||
| 4585 | static inline void skb_set_redirected(struct sk_buff *skb, bool from_ingress) | ||
| 4586 | { | ||
| 4587 | #ifdef CONFIG_NET_REDIRECT | ||
| 4588 | skb->redirected = 1; | ||
| 4589 | skb->from_ingress = from_ingress; | ||
| 4590 | if (skb->from_ingress) | ||
| 4591 | skb->tstamp = 0; | ||
| 4592 | #endif | ||
| 4593 | } | ||
| 4594 | |||
| 4595 | static inline void skb_reset_redirect(struct sk_buff *skb) | ||
| 4596 | { | ||
| 4597 | #ifdef CONFIG_NET_REDIRECT | ||
| 4598 | skb->redirected = 0; | ||
| 4599 | #endif | ||
| 4600 | } | ||
| 4601 | |||
| 4574 | #endif /* __KERNEL__ */ | 4602 | #endif /* __KERNEL__ */ |
| 4575 | #endif /* _LINUX_SKBUFF_H */ | 4603 | #endif /* _LINUX_SKBUFF_H */ |
| @@ -401,7 +401,8 @@ extern int __sys_sendto(int fd, void __user *buff, size_t len, · 400 unmodified lines | |||
| 401 | int addr_len); | 401 | int addr_len); |
| 402 | extern int __sys_accept4_file(struct file *file, unsigned file_flags, | 402 | extern int __sys_accept4_file(struct file *file, unsigned file_flags, |
| 403 | struct sockaddr __user *upeer_sockaddr, | 403 | struct sockaddr __user *upeer_sockaddr, |
| 404 | int __user *upeer_addrlen, int flags); | 404 | int __user *upeer_addrlen, int flags, |
| 405 | unsigned long nofile); | ||
| 405 | extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, | 406 | extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, |
| 406 | int __user *upeer_addrlen, int flags); | 407 | int __user *upeer_addrlen, int flags); |
| 407 | extern int __sys_socket(int family, int type, int protocol); | 408 | extern int __sys_socket(int family, int type, int protocol); |
| @@ -141,8 +141,9 @@ extern int remap_vmalloc_range_partial(struct vm_area_struct *vma, · 140 unmodified lines | |||
| 141 | 141 | ||
| 142 | extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, | 142 | extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, |
| 143 | unsigned long pgoff); | 143 | unsigned long pgoff); |
| 144 | void vmalloc_sync_all(void); | 144 | void vmalloc_sync_mappings(void); |
| 145 | 145 | void vmalloc_sync_unmappings(void); | |
| 146 | |||
| 146 | /* | 147 | /* |
| 147 | * Lowlevel-APIs (not for driver use!) | 148 | * Lowlevel-APIs (not for driver use!) |
| 148 | */ | 149 | */ |
| @@ -16,6 +16,12 @@ struct sock; · 15 unmodified lines | |||
| 16 | struct socket; | 16 | struct socket; |
| 17 | struct rxrpc_call; | 17 | struct rxrpc_call; |
| 18 | 18 | ||
| 19 | enum rxrpc_interruptibility { | ||
| 20 | RXRPC_INTERRUPTIBLE, /* Call is interruptible */ | ||
| 21 | RXRPC_PREINTERRUPTIBLE, /* Call can be cancelled whilst waiting for a slot */ | ||
| 22 | RXRPC_UNINTERRUPTIBLE, /* Call should not be interruptible at all */ | ||
| 23 | }; | ||
| 24 | |||
| 19 | /* | 25 | /* |
| 20 | * Debug ID counter for tracing. | 26 | * Debug ID counter for tracing. |
| 21 | */ | 27 | */ |
| @@ -41,7 +47,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *, · 19 unmodified lines | |||
| 41 | gfp_t, | 47 | gfp_t, |
| 42 | rxrpc_notify_rx_t, | 48 | rxrpc_notify_rx_t, |
| 43 | bool, | 49 | bool, |
| 44 | bool, | 50 | enum rxrpc_interruptibility, |
| 45 | unsigned int); | 51 | unsigned int); |
| 46 | int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *, | 52 | int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *, |
| 47 | struct msghdr *, size_t, | 53 | struct msghdr *, size_t, |
| @@ -58,9 +64,7 @@ int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t, · 10 unmodified lines | |||
| 58 | rxrpc_user_attach_call_t, unsigned long, gfp_t, | 64 | rxrpc_user_attach_call_t, unsigned long, gfp_t, |
| 59 | unsigned int); | 65 | unsigned int); |
| 60 | void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64); | 66 | void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64); |
| 61 | bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *, | 67 | bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *); |
| 62 | u32 *); | ||
| 63 | void rxrpc_kernel_probe_life(struct socket *, struct rxrpc_call *); | ||
| 64 | u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); | 68 | u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); |
| 65 | bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, | 69 | bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, |
| 66 | ktime_t *); | 70 | ktime_t *); |
| @@ -675,22 +675,6 @@ void __qdisc_calculate_pkt_len(struct sk_buff *skb, · 674 unmodified lines | |||
| 675 | const struct qdisc_size_table *stab); | 675 | const struct qdisc_size_table *stab); |
| 676 | int skb_do_redirect(struct sk_buff *); | 676 | int skb_do_redirect(struct sk_buff *); |
| 677 | 677 | ||
| 678 | static inline void skb_reset_tc(struct sk_buff *skb) | ||
| 679 | { | ||
| 680 | #ifdef CONFIG_NET_CLS_ACT | ||
| 681 | skb->tc_redirected = 0; | ||
| 682 | #endif | ||
| 683 | } | ||
| 684 | |||
| 685 | static inline bool skb_is_tc_redirected(const struct sk_buff *skb) | ||
| 686 | { | ||
| 687 | #ifdef CONFIG_NET_CLS_ACT | ||
| 688 | return skb->tc_redirected; | ||
| 689 | #else | ||
| 690 | return false; | ||
| 691 | #endif | ||
| 692 | } | ||
| 693 | |||
| 694 | static inline bool skb_at_tc_ingress(const struct sk_buff *skb) | 678 | static inline bool skb_at_tc_ingress(const struct sk_buff *skb) |
| 695 | { | 679 | { |
| 696 | #ifdef CONFIG_NET_CLS_ACT | 680 | #ifdef CONFIG_NET_CLS_ACT |
| @@ -233,7 +233,7 @@ enum afs_cb_break_reason { · 232 unmodified lines | |||
| 233 | EM(afs_call_trace_get, "GET ") \ | 233 | EM(afs_call_trace_get, "GET ") \ |
| 234 | EM(afs_call_trace_put, "PUT ") \ | 234 | EM(afs_call_trace_put, "PUT ") \ |
| 235 | EM(afs_call_trace_wake, "WAKE ") \ | 235 | EM(afs_call_trace_wake, "WAKE ") \ |
| 236 | E_(afs_call_trace_work, "WORK ") | 236 | E_(afs_call_trace_work, "QUEUE") |
| 237 | 237 | ||
| 238 | #define afs_server_traces \ | 238 | #define afs_server_traces \ |
| 239 | EM(afs_server_trace_alloc, "ALLOC ") \ | 239 | EM(afs_server_trace_alloc, "ALLOC ") \ |
| @@ -767,8 +767,7 @@ config ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH · 766 unmodified lines | |||
| 767 | bool | 767 | bool |
| 768 | 768 | ||
| 769 | config CC_HAS_INT128 | 769 | config CC_HAS_INT128 |
| 770 | def_bool y | 770 | def_bool !$(cc-option,$(m64-flag) -D__SIZEOF_INT128__=0) && 64BIT |
| 771 | depends on !$(cc-option,-D__SIZEOF_INT128__=0) | ||
| 772 | 771 | ||
| 773 | # | 772 | # |
| 774 | # For architectures that know their GCC __int128 support is sound | 773 | # For architectures that know their GCC __int128 support is sound |
| @@ -490,13 +490,21 @@ static int bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key) · 489 unmodified lines | |||
| 490 | prev_state = cmpxchg(&st_map->kvalue.state, | 490 | prev_state = cmpxchg(&st_map->kvalue.state, |
| 491 | BPF_STRUCT_OPS_STATE_INUSE, | 491 | BPF_STRUCT_OPS_STATE_INUSE, |
| 492 | BPF_STRUCT_OPS_STATE_TOBEFREE); | 492 | BPF_STRUCT_OPS_STATE_TOBEFREE); |
| 493 | if (prev_state == BPF_STRUCT_OPS_STATE_INUSE) { | 493 | switch (prev_state) { |
| 494 | case BPF_STRUCT_OPS_STATE_INUSE: | ||
| 494 | st_map->st_ops->unreg(&st_map->kvalue.data); | 495 | st_map->st_ops->unreg(&st_map->kvalue.data); |
| 495 | if (refcount_dec_and_test(&st_map->kvalue.refcnt)) | 496 | if (refcount_dec_and_test(&st_map->kvalue.refcnt)) |
| 496 | bpf_map_put(map); | 497 | bpf_map_put(map); |
| 498 | return 0; | ||
| 499 | case BPF_STRUCT_OPS_STATE_TOBEFREE: | ||
| 500 | return -EINPROGRESS; | ||
| 501 | case BPF_STRUCT_OPS_STATE_INIT: | ||
| 502 | return -ENOENT; | ||
| 503 | default: | ||
| 504 | WARN_ON_ONCE(1); | ||
| 505 | /* Should never happen. Treat it as not found. */ | ||
| 506 | return -ENOENT; | ||
| 497 | } | 507 | } |
| 498 | |||
| 499 | return 0; | ||
| 500 | } | 508 | } |
| 501 | 509 | ||
| 502 | static void bpf_struct_ops_map_seq_show_elem(struct bpf_map *map, void *key, | 510 | static void bpf_struct_ops_map_seq_show_elem(struct bpf_map *map, void *key, |
| @@ -2418,7 +2418,7 @@ static int btf_enum_check_member(struct btf_verifier_env *env, · 2417 unmodified lines | |||
| 2418 | 2418 | ||
| 2419 | struct_size = struct_type->size; | 2419 | struct_size = struct_type->size; |
| 2420 | bytes_offset = BITS_ROUNDDOWN_BYTES(struct_bits_off); | 2420 | bytes_offset = BITS_ROUNDDOWN_BYTES(struct_bits_off); |
| 2421 | if (struct_size - bytes_offset < sizeof(int)) { | 2421 | if (struct_size - bytes_offset < member_type->size) { |
| 2422 | btf_verifier_log_member(env, struct_type, member, | 2422 | btf_verifier_log_member(env, struct_type, member, |
| 2423 | "Member exceeds struct_size"); | 2423 | "Member exceeds struct_size"); |
| 2424 | return -EINVAL; | 2424 | return -EINVAL; |
| @@ -227,6 +227,9 @@ cleanup: · 226 unmodified lines | |||
| 227 | for (i = 0; i < NR; i++) | 227 | for (i = 0; i < NR; i++) |
| 228 | bpf_prog_array_free(arrays[i]); | 228 | bpf_prog_array_free(arrays[i]); |
| 229 | 229 | ||
| 230 | for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p)) | ||
| 231 | cgroup_bpf_put(p); | ||
| 232 | |||
| 230 | percpu_ref_exit(&cgrp->bpf.refcnt); | 233 | percpu_ref_exit(&cgrp->bpf.refcnt); |
| 231 | 234 | ||
| 232 | return -ENOMEM; | 235 | return -ENOMEM; |
| @@ -302,8 +305,8 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, · 69 unmodified lines | |||
| 302 | u32 saved_flags = (flags & (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)); | 305 | u32 saved_flags = (flags & (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)); |
| 303 | struct list_head *progs = &cgrp->bpf.progs[type]; | 306 | struct list_head *progs = &cgrp->bpf.progs[type]; |
| 304 | struct bpf_prog *old_prog = NULL; | 307 | struct bpf_prog *old_prog = NULL; |
| 305 | struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE], | 308 | struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {}; |
| 306 | *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {NULL}; | 309 | struct bpf_cgroup_storage *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {}; |
| 307 | struct bpf_prog_list *pl, *replace_pl = NULL; | 310 | struct bpf_prog_list *pl, *replace_pl = NULL; |
| 308 | enum bpf_cgroup_storage_type stype; | 311 | enum bpf_cgroup_storage_type stype; |
| 309 | int err; | 312 | int err; |
| @@ -1514,6 +1514,11 @@ static int map_freeze(const union bpf_attr *attr) · 1513 unmodified lines | |||
| 1514 | if (IS_ERR(map)) | 1514 | if (IS_ERR(map)) |
| 1515 | return PTR_ERR(map); | 1515 | return PTR_ERR(map); |
| 1516 | 1516 | ||
| 1517 | if (map->map_type == BPF_MAP_TYPE_STRUCT_OPS) { | ||
| 1518 | fdput(f); | ||
| 1519 | return -ENOTSUPP; | ||
| 1520 | } | ||
| 1521 | |||
| 1517 | mutex_lock(&map->freeze_mutex); | 1522 | mutex_lock(&map->freeze_mutex); |
| 1518 | 1523 | ||
| 1519 | if (map->writecnt) { | 1524 | if (map->writecnt) { |
| @@ -385,9 +385,9 @@ static inline int hb_waiters_pending(struct futex_hash_bucket *hb) · 384 unmodified lines | |||
| 385 | */ | 385 | */ |
| 386 | static struct futex_hash_bucket *hash_futex(union futex_key *key) | 386 | static struct futex_hash_bucket *hash_futex(union futex_key *key) |
| 387 | { | 387 | { |
| 388 | u32 hash = jhash2((u32*)&key->both.word, | 388 | u32 hash = jhash2((u32 *)key, offsetof(typeof(*key), both.offset) / 4, |
| 389 | (sizeof(key->both.word)+sizeof(key->both.ptr))/4, | ||
| 390 | key->both.offset); | 389 | key->both.offset); |
| 390 | |||
| 391 | return &futex_queues[hash & (futex_hashsize - 1)]; | 391 | return &futex_queues[hash & (futex_hashsize - 1)]; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| @@ -429,7 +429,7 @@ static void get_futex_key_refs(union futex_key *key) · 35 unmodified lines | |||
| 429 | 429 | ||
| 430 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { | 430 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
| 431 | case FUT_OFF_INODE: | 431 | case FUT_OFF_INODE: |
| 432 | ihold(key->shared.inode); /* implies smp_mb(); (B) */ | 432 | smp_mb(); /* explicit smp_mb(); (B) */ |
| 433 | break; | 433 | break; |
| 434 | case FUT_OFF_MMSHARED: | 434 | case FUT_OFF_MMSHARED: |
| 435 | futex_get_mm(key); /* implies smp_mb(); (B) */ | 435 | futex_get_mm(key); /* implies smp_mb(); (B) */ |
| @@ -463,7 +463,6 @@ static void drop_futex_key_refs(union futex_key *key) · 27 unmodified lines | |||
| 463 | 463 | ||
| 464 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { | 464 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
| 465 | case FUT_OFF_INODE: | 465 | case FUT_OFF_INODE: |
| 466 | iput(key->shared.inode); | ||
| 467 | break; | 466 | break; |
| 468 | case FUT_OFF_MMSHARED: | 467 | case FUT_OFF_MMSHARED: |
| 469 | mmdrop(key->private.mm); | 468 | mmdrop(key->private.mm); |
| @@ -505,6 +504,46 @@ futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, · 35 unmodified lines | |||
| 505 | return timeout; | 504 | return timeout; |
| 506 | } | 505 | } |
| 507 | 506 | ||
| 507 | /* | ||
| 508 | * Generate a machine wide unique identifier for this inode. | ||
| 509 | * | ||
| 510 | * This relies on u64 not wrapping in the life-time of the machine; which with | ||
| 511 | * 1ns resolution means almost 585 years. | ||
| 512 | * | ||
| 513 | * This further relies on the fact that a well formed program will not unmap | ||
| 514 | * the file while it has a (shared) futex waiting on it. This mapping will have | ||
| 515 | * a file reference which pins the mount and inode. | ||
| 516 | * | ||
| 517 | * If for some reason an inode gets evicted and read back in again, it will get | ||
| 518 | * a new sequence number and will _NOT_ match, even though it is the exact same | ||
| 519 | * file. | ||
| 520 | * | ||
| 521 | * It is important that match_futex() will never have a false-positive, esp. | ||
| 522 | * for PI futexes that can mess up the state. The above argues that false-negatives | ||
| 523 | * are only possible for malformed programs. | ||
| 524 | */ | ||
| 525 | static u64 get_inode_sequence_number(struct inode *inode) | ||
| 526 | { | ||
| 527 | static atomic64_t i_seq; | ||
| 528 | u64 old; | ||
| 529 | |||
| 530 | /* Does the inode already have a sequence number? */ | ||
| 531 | old = atomic64_read(&inode->i_sequence); | ||
| 532 | if (likely(old)) | ||
| 533 | return old; | ||
| 534 | |||
| 535 | for (;;) { | ||
| 536 | u64 new = atomic64_add_return(1, &i_seq); | ||
| 537 | if (WARN_ON_ONCE(!new)) | ||
| 538 | continue; | ||
| 539 | |||
| 540 | old = atomic64_cmpxchg_relaxed(&inode->i_sequence, 0, new); | ||
| 541 | if (old) | ||
| 542 | return old; | ||
| 543 | return new; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | |||
| 508 | /** | 547 | /** |
| 509 | * get_futex_key() - Get parameters which are the keys for a futex | 548 | * get_futex_key() - Get parameters which are the keys for a futex |
| 510 | * @uaddr: virtual address of the futex | 549 | * @uaddr: virtual address of the futex |
| @@ -517,9 +556,15 @@ futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, · 6 unmodified lines | |||
| 517 | * | 556 | * |
| 518 | * The key words are stored in @key on success. | 557 | * The key words are stored in @key on success. |
| 519 | * | 558 | * |
| 520 | * For shared mappings, it's (page->index, file_inode(vma->vm_file), | 559 | * For shared mappings (when @fshared), the key is: |
| 521 | * offset_within_page). For private mappings, it's (uaddr, current->mm). | 560 | * ( inode->i_sequence, page->index, offset_within_page ) |
| 522 | * We can usually work out the index without swapping in the page. | 561 | * [ also see get_inode_sequence_number() ] |
| 562 | * | ||
| 563 | * For private mappings (or when !@fshared), the key is: | ||
| 564 | * ( current->mm, address, 0 ) | ||
| 565 | * | ||
| 566 | * This allows (cross process, where applicable) identification of the futex | ||
| 567 | * without keeping the page pinned for the duration of the FUTEX_WAIT. | ||
| 523 | * | 568 | * |
| 524 | * lock_page() might sleep, the caller should not hold a spinlock. | 569 | * lock_page() might sleep, the caller should not hold a spinlock. |
| 525 | */ | 570 | */ |
| @@ -659,8 +704,6 @@ again: · 133 unmodified lines | |||
| 659 | key->private.mm = mm; | 704 | key->private.mm = mm; |
| 660 | key->private.address = address; | 705 | key->private.address = address; |
| 661 | 706 | ||
| 662 | get_futex_key_refs(key); /* implies smp_mb(); (B) */ | ||
| 663 | |||
| 664 | } else { | 707 | } else { |
| 665 | struct inode *inode; | 708 | struct inode *inode; |
| 666 | 709 | ||
| @@ -692,40 +735,14 @@ again: · 25 unmodified lines | |||
| 692 | goto again; | 735 | goto again; |
| 693 | } | 736 | } |
| 694 | 737 | ||
| 695 | /* | ||
| 696 | * Take a reference unless it is about to be freed. Previously | ||
| 697 | * this reference was taken by ihold under the page lock | ||
| 698 | * pinning the inode in place so i_lock was unnecessary. The | ||
| 699 | * only way for this check to fail is if the inode was | ||
| 700 | * truncated in parallel which is almost certainly an | ||
| 701 | * application bug. In such a case, just retry. | ||
| 702 | * | ||
| 703 | * We are not calling into get_futex_key_refs() in file-backed | ||
| 704 | * cases, therefore a successful atomic_inc return below will | ||
| 705 | * guarantee that get_futex_key() will still imply smp_mb(); (B). | ||
| 706 | */ | ||
| 707 | if (!atomic_inc_not_zero(&inode->i_count)) { | ||
| 708 | rcu_read_unlock(); | ||
| 709 | put_page(page); | ||
| 710 | |||
| 711 | goto again; | ||
| 712 | } | ||
| 713 | |||
| 714 | /* Should be impossible but lets be paranoid for now */ | ||
| 715 | if (WARN_ON_ONCE(inode->i_mapping != mapping)) { | ||
| 716 | err = -EFAULT; | ||
| 717 | rcu_read_unlock(); | ||
| 718 | iput(inode); | ||
| 719 | |||
| 720 | goto out; | ||
| 721 | } | ||
| 722 | |||
| 723 | key->both.offset |= FUT_OFF_INODE; /* inode-based key */ | 738 | key->both.offset |= FUT_OFF_INODE; /* inode-based key */ |
| 724 | key->shared.inode = inode; | 739 | key->shared.i_seq = get_inode_sequence_number(inode); |
| 725 | key->shared.pgoff = basepage_index(tail); | 740 | key->shared.pgoff = basepage_index(tail); |
| 726 | rcu_read_unlock(); | 741 | rcu_read_unlock(); |
| 727 | } | 742 | } |
| 728 | 743 | ||
| 744 | get_futex_key_refs(key); /* implies smp_mb(); (B) */ | ||
| 745 | |||
| 729 | out: | 746 | out: |
| 730 | put_page(page); | 747 | put_page(page); |
| 731 | return err; | 748 | return err; |
| @@ -519,7 +519,7 @@ NOKPROBE_SYMBOL(notify_die); · 518 unmodified lines | |||
| 519 | 519 | ||
| 520 | int register_die_notifier(struct notifier_block *nb) | 520 | int register_die_notifier(struct notifier_block *nb) |
| 521 | { | 521 | { |
| 522 | vmalloc_sync_all(); | 522 | vmalloc_sync_mappings(); |
| 523 | return atomic_notifier_chain_register(&die_chain, nb); | 523 | return atomic_notifier_chain_register(&die_chain, nb); |
| 524 | } | 524 | } |
| 525 | EXPORT_SYMBOL_GPL(register_die_notifier); | 525 | EXPORT_SYMBOL_GPL(register_die_notifier); |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | |||
| 47 | #include <linux/syscalls.h> | 47 | #include <linux/syscalls.h> |
| 48 | #include <linux/kprobes.h> | 48 | #include <linux/kprobes.h> |
| 49 | #include <linux/user_namespace.h> | 49 | #include <linux/user_namespace.h> |
| 50 | #include <linux/time_namespace.h> | ||
| 50 | #include <linux/binfmts.h> | 51 | #include <linux/binfmts.h> |
| 51 | 52 | ||
| 52 | #include <linux/sched.h> | 53 | #include <linux/sched.h> |
| @@ -2546,6 +2547,7 @@ static int do_sysinfo(struct sysinfo *info) · 2493 unmodified lines | |||
| 2546 | memset(info, 0, sizeof(struct sysinfo)); | 2547 | memset(info, 0, sizeof(struct sysinfo)); |
| 2547 | 2548 | ||
| 2548 | ktime_get_boottime_ts64(&tp); | 2549 | ktime_get_boottime_ts64(&tp); |
| 2550 | timens_add_boottime(&tp); | ||
| 2549 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); | 2551 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
| 2550 | 2552 | ||
| 2551 | get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); | 2553 | get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); |
| @@ -730,7 +730,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) · 729 unmodified lines | |||
| 730 | if (unlikely(!nmi_uaccess_okay())) | 730 | if (unlikely(!nmi_uaccess_okay())) |
| 731 | return -EPERM; | 731 | return -EPERM; |
| 732 | 732 | ||
| 733 | if (in_nmi()) { | 733 | if (irqs_disabled()) { |
| 734 | /* Do an early check on signal validity. Otherwise, | 734 | /* Do an early check on signal validity. Otherwise, |
| 735 | * the error is lost in deferred irq_work. | 735 | * the error is lost in deferred irq_work. |
| 736 | */ | 736 | */ |
| @@ -9028,10 +9028,15 @@ bool __init chacha20poly1305_selftest(void) · 9027 unmodified lines | |||
| 9028 | && total_len <= 1 << 10; ++total_len) { | 9028 | && total_len <= 1 << 10; ++total_len) { |
| 9029 | for (i = 0; i <= total_len; ++i) { | 9029 | for (i = 0; i <= total_len; ++i) { |
| 9030 | for (j = i; j <= total_len; ++j) { | 9030 | for (j = i; j <= total_len; ++j) { |
| 9031 | k = 0; | ||
| 9031 | sg_init_table(sg_src, 3); | 9032 | sg_init_table(sg_src, 3); |
| 9032 | sg_set_buf(&sg_src[0], input, i); | 9033 | if (i) |
| 9033 | sg_set_buf(&sg_src[1], input + i, j - i); | 9034 | sg_set_buf(&sg_src[k++], input, i); |
| 9034 | sg_set_buf(&sg_src[2], input + j, total_len - j); | 9035 | if (j - i) |
| 9036 | sg_set_buf(&sg_src[k++], input + i, j - i); | ||
| 9037 | if (total_len - j) | ||
| 9038 | sg_set_buf(&sg_src[k++], input + j, total_len - j); | ||
| 9039 | sg_init_marker(sg_src, k); | ||
| 9035 | memset(computed_output, 0, total_len); | 9040 | memset(computed_output, 0, total_len); |
| 9036 | memset(input, 0, total_len); | 9041 | memset(input, 0, total_len); |
| 9037 | 9042 | ||
| @@ -335,12 +335,14 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd, · 334 unmodified lines | |||
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | page = pmd_page(orig_pmd); | 337 | page = pmd_page(orig_pmd); |
| 338 | |||
| 339 | /* Do not interfere with other mappings of this page */ | ||
| 340 | if (page_mapcount(page) != 1) | ||
| 341 | goto huge_unlock; | ||
| 342 | |||
| 338 | if (next - addr != HPAGE_PMD_SIZE) { | 343 | if (next - addr != HPAGE_PMD_SIZE) { |
| 339 | int err; | 344 | int err; |
| 340 | 345 | ||
| 341 | if (page_mapcount(page) != 1) | ||
| 342 | goto huge_unlock; | ||
| 343 | |||
| 344 | get_page(page); | 346 | get_page(page); |
| 345 | spin_unlock(ptl); | 347 | spin_unlock(ptl); |
| 346 | lock_page(page); | 348 | lock_page(page); |
| @@ -426,6 +428,10 @@ regular_page: · 79 unmodified lines | |||
| 426 | continue; | 428 | continue; |
| 427 | } | 429 | } |
| 428 | 430 | ||
| 431 | /* Do not interfere with other mappings of this page */ | ||
| 432 | if (page_mapcount(page) != 1) | ||
| 433 | continue; | ||
| 434 | |||
| 429 | VM_BUG_ON_PAGE(PageTransCompound(page), page); | 435 | VM_BUG_ON_PAGE(PageTransCompound(page), page); |
| 430 | 436 | ||
| 431 | if (pte_young(ptent)) { | 437 | if (pte_young(ptent)) { |
| @@ -2297,28 +2297,41 @@ static void high_work_func(struct work_struct *work) · 2296 unmodified lines | |||
| 2297 | #define MEMCG_DELAY_SCALING_SHIFT 14 | 2297 | #define MEMCG_DELAY_SCALING_SHIFT 14 |
| 2298 | 2298 | ||
| 2299 | /* | 2299 | /* |
| 2300 | * Scheduled by try_charge() to be executed from the userland return path | 2300 | * Get the number of jiffies that we should penalise a mischievous cgroup which |
| 2301 | * and reclaims memory over the high limit. | 2301 | * is exceeding its memory.high by checking both it and its ancestors. |
| 2302 | */ | 2302 | */ |
| 2303 | void mem_cgroup_handle_over_high(void) | 2303 | static unsigned long calculate_high_delay(struct mem_cgroup *memcg, |
| 2304 | unsigned int nr_pages) | ||
| 2304 | { | 2305 | { |
| 2305 | unsigned long usage, high, clamped_high; | 2306 | unsigned long penalty_jiffies; |
| 2306 | unsigned long pflags; | 2307 | u64 max_overage = 0; |
| 2307 | unsigned long penalty_jiffies, overage; | ||
| 2308 | unsigned int nr_pages = current->memcg_nr_pages_over_high; | ||
| 2309 | struct mem_cgroup *memcg; | ||
| 2310 | 2308 | ||
| 2311 | if (likely(!nr_pages)) | 2309 | do { |
| 2312 | return; | 2310 | unsigned long usage, high; |
| 2311 | u64 overage; | ||
| 2313 | 2312 | ||
| 2314 | memcg = get_mem_cgroup_from_mm(current->mm); | 2313 | usage = page_counter_read(&memcg->memory); |
| 2315 | reclaim_high(memcg, nr_pages, GFP_KERNEL); | 2314 | high = READ_ONCE(memcg->high); |
| 2316 | current->memcg_nr_pages_over_high = 0; | 2315 | |
| 2316 | /* | ||
| 2317 | * Prevent division by 0 in overage calculation by acting as if | ||
| 2318 | * it was a threshold of 1 page | ||
| 2319 | */ | ||
| 2320 | high = max(high, 1UL); | ||
| 2321 | |||
| 2322 | overage = usage - high; | ||
| 2323 | overage <<= MEMCG_DELAY_PRECISION_SHIFT; | ||
| 2324 | overage = div64_u64(overage, high); | ||
| 2325 | |||
| 2326 | if (overage > max_overage) | ||
| 2327 | max_overage = overage; | ||
| 2328 | } while ((memcg = parent_mem_cgroup(memcg)) && | ||
| 2329 | !mem_cgroup_is_root(memcg)); | ||
| 2330 | |||
| 2331 | if (!max_overage) | ||
| 2332 | return 0; | ||
| 2317 | 2333 | ||
| 2318 | /* | 2334 | /* |
| 2319 | * memory.high is breached and reclaim is unable to keep up. Throttle | ||
| 2320 | * allocators proactively to slow down excessive growth. | ||
| 2321 | * | ||
| 2322 | * We use overage compared to memory.high to calculate the number of | 2335 | * We use overage compared to memory.high to calculate the number of |
| 2323 | * jiffies to sleep (penalty_jiffies). Ideally this value should be | 2336 | * jiffies to sleep (penalty_jiffies). Ideally this value should be |
| 2324 | * fairly lenient on small overages, and increasingly harsh when the | 2337 | * fairly lenient on small overages, and increasingly harsh when the |
| @@ -2326,24 +2339,9 @@ void mem_cgroup_handle_over_high(void) · 1 unmodified line | |||
| 2326 | * its crazy behaviour, so we exponentially increase the delay based on | 2339 | * its crazy behaviour, so we exponentially increase the delay based on |
| 2327 | * overage amount. | 2340 | * overage amount. |
| 2328 | */ | 2341 | */ |
| 2329 | 2342 | penalty_jiffies = max_overage * max_overage * HZ; | |
| 2330 | usage = page_counter_read(&memcg->memory); | 2343 | penalty_jiffies >>= MEMCG_DELAY_PRECISION_SHIFT; |
| 2331 | high = READ_ONCE(memcg->high); | 2344 | penalty_jiffies >>= MEMCG_DELAY_SCALING_SHIFT; |
| 2332 | |||
| 2333 | if (usage <= high) | ||
| 2334 | goto out; | ||
| 2335 | |||
| 2336 | /* | ||
| 2337 | * Prevent division by 0 in overage calculation by acting as if it was a | ||
| 2338 | * threshold of 1 page | ||
| 2339 | */ | ||
| 2340 | clamped_high = max(high, 1UL); | ||
| 2341 | |||
| 2342 | overage = div_u64((u64)(usage - high) << MEMCG_DELAY_PRECISION_SHIFT, | ||
| 2343 | clamped_high); | ||
| 2344 | |||
| 2345 | penalty_jiffies = ((u64)overage * overage * HZ) | ||
| 2346 | >> (MEMCG_DELAY_PRECISION_SHIFT + MEMCG_DELAY_SCALING_SHIFT); | ||
| 2347 | 2345 | ||
| 2348 | /* | 2346 | /* |
| 2349 | * Factor in the task's own contribution to the overage, such that four | 2347 | * Factor in the task's own contribution to the overage, such that four |
| @@ -2360,7 +2358,32 @@ void mem_cgroup_handle_over_high(void) · 10 unmodified lines | |||
| 2360 | * application moving forwards and also permit diagnostics, albeit | 2358 | * application moving forwards and also permit diagnostics, albeit |
| 2361 | * extremely slowly. | 2359 | * extremely slowly. |
| 2362 | */ | 2360 | */ |
| 2363 | penalty_jiffies = min(penalty_jiffies, MEMCG_MAX_HIGH_DELAY_JIFFIES); | 2361 | return min(penalty_jiffies, MEMCG_MAX_HIGH_DELAY_JIFFIES); |
| 2362 | } | ||
| 2363 | |||
| 2364 | /* | ||
| 2365 | * Scheduled by try_charge() to be executed from the userland return path | ||
| 2366 | * and reclaims memory over the high limit. | ||
| 2367 | */ | ||
| 2368 | void mem_cgroup_handle_over_high(void) | ||
| 2369 | { | ||
| 2370 | unsigned long penalty_jiffies; | ||
| 2371 | unsigned long pflags; | ||
| 2372 | unsigned int nr_pages = current->memcg_nr_pages_over_high; | ||
| 2373 | struct mem_cgroup *memcg; | ||
| 2374 | |||
| 2375 | if (likely(!nr_pages)) | ||
| 2376 | return; | ||
| 2377 | |||
| 2378 | memcg = get_mem_cgroup_from_mm(current->mm); | ||
| 2379 | reclaim_high(memcg, nr_pages, GFP_KERNEL); | ||
| 2380 | current->memcg_nr_pages_over_high = 0; | ||
| 2381 | |||
| 2382 | /* | ||
| 2383 | * memory.high is breached and reclaim is unable to keep up. Throttle | ||
| 2384 | * allocators proactively to slow down excessive growth. | ||
| 2385 | */ | ||
| 2386 | penalty_jiffies = calculate_high_delay(memcg, nr_pages); | ||
| 2364 | 2387 | ||
| 2365 | /* | 2388 | /* |
| 2366 | * Don't sleep if the amount of jiffies this memcg owes us is so low | 2389 | * Don't sleep if the amount of jiffies this memcg owes us is so low |
| @@ -4027,7 +4050,7 @@ static void __mem_cgroup_usage_unregister_event(struct mem_cgroup *memcg, · 1660 unmodified lines | |||
| 4027 | struct mem_cgroup_thresholds *thresholds; | 4050 | struct mem_cgroup_thresholds *thresholds; |
| 4028 | struct mem_cgroup_threshold_ary *new; | 4051 | struct mem_cgroup_threshold_ary *new; |
| 4029 | unsigned long usage; | 4052 | unsigned long usage; |
| 4030 | int i, j, size; | 4053 | int i, j, size, entries; |
| 4031 | 4054 | ||
| 4032 | mutex_lock(&memcg->thresholds_lock); | 4055 | mutex_lock(&memcg->thresholds_lock); |
| 4033 | 4056 | ||
| @@ -4047,14 +4070,20 @@ static void __mem_cgroup_usage_unregister_event(struct mem_cgroup *memcg, · 13 unmodified lines | |||
| 4047 | __mem_cgroup_threshold(memcg, type == _MEMSWAP); | 4070 | __mem_cgroup_threshold(memcg, type == _MEMSWAP); |
| 4048 | 4071 | ||
| 4049 | /* Calculate new number of threshold */ | 4072 | /* Calculate new number of threshold */ |
| 4050 | size = 0; | 4073 | size = entries = 0; |
| 4051 | for (i = 0; i < thresholds->primary->size; i++) { | 4074 | for (i = 0; i < thresholds->primary->size; i++) { |
| 4052 | if (thresholds->primary->entries[i].eventfd != eventfd) | 4075 | if (thresholds->primary->entries[i].eventfd != eventfd) |
| 4053 | size++; | 4076 | size++; |
| 4077 | else | ||
| 4078 | entries++; | ||
| 4054 | } | 4079 | } |
| 4055 | 4080 | ||
| 4056 | new = thresholds->spare; | 4081 | new = thresholds->spare; |
| 4057 | 4082 | ||
| 4083 | /* If no items related to eventfd have been cleared, nothing to do */ | ||
| 4084 | if (!entries) | ||
| 4085 | goto unlock; | ||
| 4086 | |||
| 4058 | /* Set thresholds array to NULL if we don't have thresholds */ | 4087 | /* Set thresholds array to NULL if we don't have thresholds */ |
| 4059 | if (!size) { | 4088 | if (!size) { |
| 4060 | kfree(new); | 4089 | kfree(new); |
| @@ -307,7 +307,8 @@ static void mn_hlist_release(struct mmu_notifier_subscriptions *subscriptions, · 306 unmodified lines | |||
| 307 | * ->release returns. | 307 | * ->release returns. |
| 308 | */ | 308 | */ |
| 309 | id = srcu_read_lock(&srcu); | 309 | id = srcu_read_lock(&srcu); |
| 310 | hlist_for_each_entry_rcu(subscription, &subscriptions->list, hlist) | 310 | hlist_for_each_entry_rcu(subscription, &subscriptions->list, hlist, |
| 311 | srcu_read_lock_held(&srcu)) | ||
| 311 | /* | 312 | /* |
| 312 | * If ->release runs before mmu_notifier_unregister it must be | 313 | * If ->release runs before mmu_notifier_unregister it must be |
| 313 | * handled, as it's the only way for the driver to flush all | 314 | * handled, as it's the only way for the driver to flush all |
| @@ -370,7 +371,8 @@ int __mmu_notifier_clear_flush_young(struct mm_struct *mm, · 56 unmodified lines | |||
| 370 | 371 | ||
| 371 | id = srcu_read_lock(&srcu); | 372 | id = srcu_read_lock(&srcu); |
| 372 | hlist_for_each_entry_rcu(subscription, | 373 | hlist_for_each_entry_rcu(subscription, |
| 373 | &mm->notifier_subscriptions->list, hlist) { | 374 | &mm->notifier_subscriptions->list, hlist, |
| 375 | srcu_read_lock_held(&srcu)) { | ||
| 374 | if (subscription->ops->clear_flush_young) | 376 | if (subscription->ops->clear_flush_young) |
| 375 | young |= subscription->ops->clear_flush_young( | 377 | young |= subscription->ops->clear_flush_young( |
| 376 | subscription, mm, start, end); | 378 | subscription, mm, start, end); |
| @@ -389,7 +391,8 @@ int __mmu_notifier_clear_young(struct mm_struct *mm, · 12 unmodified lines | |||
| 389 | 391 | ||
| 390 | id = srcu_read_lock(&srcu); | 392 | id = srcu_read_lock(&srcu); |
| 391 | hlist_for_each_entry_rcu(subscription, | 393 | hlist_for_each_entry_rcu(subscription, |
| 392 | &mm->notifier_subscriptions->list, hlist) { | 394 | &mm->notifier_subscriptions->list, hlist, |
| 395 | srcu_read_lock_held(&srcu)) { | ||
| 393 | if (subscription->ops->clear_young) | 396 | if (subscription->ops->clear_young) |
| 394 | young |= subscription->ops->clear_young(subscription, | 397 | young |= subscription->ops->clear_young(subscription, |
| 395 | mm, start, end); | 398 | mm, start, end); |
| @@ -407,7 +410,8 @@ int __mmu_notifier_test_young(struct mm_struct *mm, · 11 unmodified lines | |||
| 407 | 410 | ||
| 408 | id = srcu_read_lock(&srcu); | 411 | id = srcu_read_lock(&srcu); |
| 409 | hlist_for_each_entry_rcu(subscription, | 412 | hlist_for_each_entry_rcu(subscription, |
| 410 | &mm->notifier_subscriptions->list, hlist) { | 413 | &mm->notifier_subscriptions->list, hlist, |
| 414 | srcu_read_lock_held(&srcu)) { | ||
| 411 | if (subscription->ops->test_young) { | 415 | if (subscription->ops->test_young) { |
| 412 | young = subscription->ops->test_young(subscription, mm, | 416 | young = subscription->ops->test_young(subscription, mm, |
| 413 | address); | 417 | address); |
| @@ -428,7 +432,8 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, · 14 unmodified lines | |||
| 428 | 432 | ||
| 429 | id = srcu_read_lock(&srcu); | 433 | id = srcu_read_lock(&srcu); |
| 430 | hlist_for_each_entry_rcu(subscription, | 434 | hlist_for_each_entry_rcu(subscription, |
| 431 | &mm->notifier_subscriptions->list, hlist) { | 435 | &mm->notifier_subscriptions->list, hlist, |
| 436 | srcu_read_lock_held(&srcu)) { | ||
| 432 | if (subscription->ops->change_pte) | 437 | if (subscription->ops->change_pte) |
| 433 | subscription->ops->change_pte(subscription, mm, address, | 438 | subscription->ops->change_pte(subscription, mm, address, |
| 434 | pte); | 439 | pte); |
| @@ -476,7 +481,8 @@ static int mn_hlist_invalidate_range_start( · 41 unmodified lines | |||
| 476 | int id; | 481 | int id; |
| 477 | 482 | ||
| 478 | id = srcu_read_lock(&srcu); | 483 | id = srcu_read_lock(&srcu); |
| 479 | hlist_for_each_entry_rcu(subscription, &subscriptions->list, hlist) { | 484 | hlist_for_each_entry_rcu(subscription, &subscriptions->list, hlist, |
| 485 | srcu_read_lock_held(&srcu)) { | ||
| 480 | const struct mmu_notifier_ops *ops = subscription->ops; | 486 | const struct mmu_notifier_ops *ops = subscription->ops; |
| 481 | 487 | ||
| 482 | if (ops->invalidate_range_start) { | 488 | if (ops->invalidate_range_start) { |
| @@ -528,7 +534,8 @@ mn_hlist_invalidate_end(struct mmu_notifier_subscriptions *subscriptions, · 45 unmodified lines | |||
| 528 | int id; | 534 | int id; |
| 529 | 535 | ||
| 530 | id = srcu_read_lock(&srcu); | 536 | id = srcu_read_lock(&srcu); |
| 531 | hlist_for_each_entry_rcu(subscription, &subscriptions->list, hlist) { | 537 | hlist_for_each_entry_rcu(subscription, &subscriptions->list, hlist, |
| 538 | srcu_read_lock_held(&srcu)) { | ||
| 532 | /* | 539 | /* |
| 533 | * Call invalidate_range here too to avoid the need for the | 540 | * Call invalidate_range here too to avoid the need for the |
| 534 | * subsystem of having to register an invalidate_range_end | 541 | * subsystem of having to register an invalidate_range_end |
| @@ -582,7 +589,8 @@ void __mmu_notifier_invalidate_range(struct mm_struct *mm, · 47 unmodified lines | |||
| 582 | 589 | ||
| 583 | id = srcu_read_lock(&srcu); | 590 | id = srcu_read_lock(&srcu); |
| 584 | hlist_for_each_entry_rcu(subscription, | 591 | hlist_for_each_entry_rcu(subscription, |
| 585 | &mm->notifier_subscriptions->list, hlist) { | 592 | &mm->notifier_subscriptions->list, hlist, |
| 593 | srcu_read_lock_held(&srcu)) { | ||
| 586 | if (subscription->ops->invalidate_range) | 594 | if (subscription->ops->invalidate_range) |
| 587 | subscription->ops->invalidate_range(subscription, mm, | 595 | subscription->ops->invalidate_range(subscription, mm, |
| 588 | start, end); | 596 | start, end); |
| @@ -714,7 +722,8 @@ find_get_mmu_notifier(struct mm_struct *mm, const struct mmu_notifier_ops *ops) · 125 unmodified lines | |||
| 714 | 722 | ||
| 715 | spin_lock(&mm->notifier_subscriptions->lock); | 723 | spin_lock(&mm->notifier_subscriptions->lock); |
| 716 | hlist_for_each_entry_rcu(subscription, | 724 | hlist_for_each_entry_rcu(subscription, |
| 717 | &mm->notifier_subscriptions->list, hlist) { | 725 | &mm->notifier_subscriptions->list, hlist, |
| 726 | lockdep_is_held(&mm->notifier_subscriptions->lock)) { | ||
| 718 | if (subscription->ops != ops) | 727 | if (subscription->ops != ops) |
| 719 | continue; | 728 | continue; |
| 720 | 729 | ||
| @@ -370,10 +370,14 @@ void vm_unmap_aliases(void) · 369 unmodified lines | |||
| 370 | EXPORT_SYMBOL_GPL(vm_unmap_aliases); | 370 | EXPORT_SYMBOL_GPL(vm_unmap_aliases); |
| 371 | 371 | ||
| 372 | /* | 372 | /* |
| 373 | * Implement a stub for vmalloc_sync_all() if the architecture chose not to | 373 | * Implement a stub for vmalloc_sync_[un]mapping() if the architecture |
| 374 | * have one. | 374 | * chose not to have one. |
| 375 | */ | 375 | */ |
| 376 | void __weak vmalloc_sync_all(void) | 376 | void __weak vmalloc_sync_mappings(void) |
| 377 | { | ||
| 378 | } | ||
| 379 | |||
| 380 | void __weak vmalloc_sync_unmappings(void) | ||
| 377 | { | 381 | { |
| 378 | } | 382 | } |
| 379 | 383 | ||
| @@ -1973,8 +1973,6 @@ static void *get_partial(struct kmem_cache *s, gfp_t flags, int node, · 1972 unmodified lines | |||
| 1973 | 1973 | ||
| 1974 | if (node == NUMA_NO_NODE) | 1974 | if (node == NUMA_NO_NODE) |
| 1975 | searchnode = numa_mem_id(); | 1975 | searchnode = numa_mem_id(); |
| 1976 | else if (!node_present_pages(node)) | ||
| 1977 | searchnode = node_to_mem_node(node); | ||
| 1978 | 1976 | ||
| 1979 | object = get_partial_node(s, get_node(s, searchnode), c, flags); | 1977 | object = get_partial_node(s, get_node(s, searchnode), c, flags); |
| 1980 | if (object || node != NUMA_NO_NODE) | 1978 | if (object || node != NUMA_NO_NODE) |
| @@ -2563,17 +2561,27 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, · 582 unmodified lines | |||
| 2563 | struct page *page; | 2561 | struct page *page; |
| 2564 | 2562 | ||
| 2565 | page = c->page; | 2563 | page = c->page; |
| 2566 | if (!page) | 2564 | if (!page) { |
| 2565 | /* | ||
| 2566 | * if the node is not online or has no normal memory, just | ||
| 2567 | * ignore the node constraint | ||
| 2568 | */ | ||
| 2569 | if (unlikely(node != NUMA_NO_NODE && | ||
| 2570 | !node_state(node, N_NORMAL_MEMORY))) | ||
| 2571 | node = NUMA_NO_NODE; | ||
| 2567 | goto new_slab; | 2572 | goto new_slab; |
| 2573 | } | ||
| 2568 | redo: | 2574 | redo: |
| 2569 | 2575 | ||
| 2570 | if (unlikely(!node_match(page, node))) { | 2576 | if (unlikely(!node_match(page, node))) { |
| 2571 | int searchnode = node; | 2577 | /* |
| 2572 | 2578 | * same as above but node_match() being false already | |
| 2573 | if (node != NUMA_NO_NODE && !node_present_pages(node)) | 2579 | * implies node != NUMA_NO_NODE |
| 2574 | searchnode = node_to_mem_node(node); | 2580 | */ |
| 2575 | 2581 | if (!node_state(node, N_NORMAL_MEMORY)) { | |
| 2576 | if (unlikely(!node_match(page, searchnode))) { | 2582 | node = NUMA_NO_NODE; |
| 2583 | goto redo; | ||
| 2584 | } else { | ||
| 2577 | stat(s, ALLOC_NODE_MISMATCH); | 2585 | stat(s, ALLOC_NODE_MISMATCH); |
| 2578 | deactivate_slab(s, page, c->freelist, c); | 2586 | deactivate_slab(s, page, c->freelist, c); |
| 2579 | goto new_slab; | 2587 | goto new_slab; |
| @@ -2997,11 +3005,13 @@ redo: · 417 unmodified lines | |||
| 2997 | barrier(); | 3005 | barrier(); |
| 2998 | 3006 | ||
| 2999 | if (likely(page == c->page)) { | 3007 | if (likely(page == c->page)) { |
| 3000 | set_freepointer(s, tail_obj, c->freelist); | 3008 | void **freelist = READ_ONCE(c->freelist); |
| 3009 | |||
| 3010 | set_freepointer(s, tail_obj, freelist); | ||
| 3001 | 3011 | ||
| 3002 | if (unlikely(!this_cpu_cmpxchg_double( | 3012 | if (unlikely(!this_cpu_cmpxchg_double( |
| 3003 | s->cpu_slab->freelist, s->cpu_slab->tid, | 3013 | s->cpu_slab->freelist, s->cpu_slab->tid, |
| 3004 | c->freelist, tid, | 3014 | freelist, tid, |
| 3005 | head, next_tid(tid)))) { | 3015 | head, next_tid(tid)))) { |
| 3006 | 3016 | ||
| 3007 | note_cmpxchg_failure("slab_free", s, tid); | 3017 | note_cmpxchg_failure("slab_free", s, tid); |
| @@ -3174,6 +3184,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, · 166 unmodified lines | |||
| 3174 | void *object = c->freelist; | 3184 | void *object = c->freelist; |
| 3175 | 3185 | ||
| 3176 | if (unlikely(!object)) { | 3186 | if (unlikely(!object)) { |
| 3187 | /* | ||
| 3188 | * We may have removed an object from c->freelist using | ||
| 3189 | * the fastpath in the previous iteration; in that case, | ||
| 3190 | * c->tid has not been bumped yet. | ||
| 3191 | * Since ___slab_alloc() may reenable interrupts while | ||
| 3192 | * allocating memory, we should bump c->tid now. | ||
| 3193 | */ | ||
| 3194 | c->tid = next_tid(c->tid); | ||
| 3195 | |||
| 3177 | /* | 3196 | /* |
| 3178 | * Invoking slow path likely have side-effect | 3197 | * Invoking slow path likely have side-effect |
| 3179 | * of re-populating per CPU c->freelist | 3198 | * of re-populating per CPU c->freelist |
| @@ -734,6 +734,7 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, · 733 unmodified lines | |||
| 734 | struct mem_section *ms = __pfn_to_section(pfn); | 734 | struct mem_section *ms = __pfn_to_section(pfn); |
| 735 | bool section_is_early = early_section(ms); | 735 | bool section_is_early = early_section(ms); |
| 736 | struct page *memmap = NULL; | 736 | struct page *memmap = NULL; |
| 737 | bool empty; | ||
| 737 | unsigned long *subsection_map = ms->usage | 738 | unsigned long *subsection_map = ms->usage |
| 738 | ? &ms->usage->subsection_map[0] : NULL; | 739 | ? &ms->usage->subsection_map[0] : NULL; |
| 739 | 740 | ||
| @@ -764,7 +765,8 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, · 24 unmodified lines | |||
| 764 | * For 2/ and 3/ the SPARSEMEM_VMEMMAP={y,n} cases are unified | 765 | * For 2/ and 3/ the SPARSEMEM_VMEMMAP={y,n} cases are unified |
| 765 | */ | 766 | */ |
| 766 | bitmap_xor(subsection_map, map, subsection_map, SUBSECTIONS_PER_SECTION); | 767 | bitmap_xor(subsection_map, map, subsection_map, SUBSECTIONS_PER_SECTION); |
| 767 | if (bitmap_empty(subsection_map, SUBSECTIONS_PER_SECTION)) { | 768 | empty = bitmap_empty(subsection_map, SUBSECTIONS_PER_SECTION); |
| 769 | if (empty) { | ||
| 768 | unsigned long section_nr = pfn_to_section_nr(pfn); | 770 | unsigned long section_nr = pfn_to_section_nr(pfn); |
| 769 | 771 | ||
| 770 | /* | 772 | /* |
| @@ -779,13 +781,15 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, · 8 unmodified lines | |||
| 779 | ms->usage = NULL; | 781 | ms->usage = NULL; |
| 780 | } | 782 | } |
| 781 | memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr); | 783 | memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr); |
| 782 | ms->section_mem_map = (unsigned long)NULL; | ||
| 783 | } | 784 | } |
| 784 | 785 | ||
| 785 | if (section_is_early && memmap) | 786 | if (section_is_early && memmap) |
| 786 | free_map_bootmem(memmap); | 787 | free_map_bootmem(memmap); |
| 787 | else | 788 | else |
| 788 | depopulate_section_memmap(pfn, nr_pages, altmap); | 789 | depopulate_section_memmap(pfn, nr_pages, altmap); |
| 790 | |||
| 791 | if (empty) | ||
| 792 | ms->section_mem_map = (unsigned long)NULL; | ||
| 789 | } | 793 | } |
| 790 | 794 | ||
| 791 | static struct page * __meminit section_activate(int nid, unsigned long pfn, | 795 | static struct page * __meminit section_activate(int nid, unsigned long pfn, |
| @@ -1295,7 +1295,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) · 1294 unmodified lines | |||
| 1295 | * First make sure the mappings are removed from all page-tables | 1295 | * First make sure the mappings are removed from all page-tables |
| 1296 | * before they are freed. | 1296 | * before they are freed. |
| 1297 | */ | 1297 | */ |
| 1298 | vmalloc_sync_all(); | 1298 | vmalloc_sync_unmappings(); |
| 1299 | 1299 | ||
| 1300 | /* | 1300 | /* |
| 1301 | * TODO: to calculate a flush range without looping. | 1301 | * TODO: to calculate a flush range without looping. |
| @@ -3128,16 +3128,19 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, · 1826 unmodified lines | |||
| 3128 | EXPORT_SYMBOL(remap_vmalloc_range); | 3128 | EXPORT_SYMBOL(remap_vmalloc_range); |
| 3129 | 3129 | ||
| 3130 | /* | 3130 | /* |
| 3131 | * Implement a stub for vmalloc_sync_all() if the architecture chose not to | 3131 | * Implement stubs for vmalloc_sync_[un]mappings () if the architecture chose |
| 3132 | * have one. | 3132 | * not to have one. |
| 3133 | * | 3133 | * |
| 3134 | * The purpose of this function is to make sure the vmalloc area | 3134 | * The purpose of this function is to make sure the vmalloc area |
| 3135 | * mappings are identical in all page-tables in the system. | 3135 | * mappings are identical in all page-tables in the system. |
| 3136 | */ | 3136 | */ |
| 3137 | void __weak vmalloc_sync_all(void) | 3137 | void __weak vmalloc_sync_mappings(void) |
| 3138 | { | 3138 | { |
| 3139 | } | 3139 | } |
| 3140 | 3140 | ||
| 3141 | void __weak vmalloc_sync_unmappings(void) | ||
| 3142 | { | ||
| 3143 | } | ||
| 3141 | 3144 | ||
| 3142 | static int f(pte_t *pte, unsigned long addr, void *data) | 3145 | static int f(pte_t *pte, unsigned long addr, void *data) |
| 3143 | { | 3146 | { |
| @@ -52,6 +52,9 @@ config NET_INGRESS · 51 unmodified lines | |||
| 52 | config NET_EGRESS | 52 | config NET_EGRESS |
| 53 | bool | 53 | bool |
| 54 | 54 | ||
| 55 | config NET_REDIRECT | ||
| 56 | bool | ||
| 57 | |||
| 55 | config SKB_EXTENSIONS | 58 | config SKB_EXTENSIONS |
| 56 | bool | 59 | bool |
| 57 | 60 | ||
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 10 | #include <asm/unistd.h> | 10 | #include <asm/unistd.h> |
| 11 | #include "msgfmt.h" | 11 | #include "msgfmt.h" |
| 12 | 12 | ||
| 13 | int debug_fd; | 13 | FILE *debug_f; |
| 14 | 14 | ||
| 15 | static int handle_get_cmd(struct mbox_request *cmd) | 15 | static int handle_get_cmd(struct mbox_request *cmd) |
| 16 | { | 16 | { |
| @@ -35,9 +35,10 @@ static void loop(void) · 18 unmodified lines | |||
| 35 | struct mbox_reply reply; | 35 | struct mbox_reply reply; |
| 36 | int n; | 36 | int n; |
| 37 | 37 | ||
| 38 | fprintf(debug_f, "testing the buffer\n"); | ||
| 38 | n = read(0, &req, sizeof(req)); | 39 | n = read(0, &req, sizeof(req)); |
| 39 | if (n != sizeof(req)) { | 40 | if (n != sizeof(req)) { |
| 40 | dprintf(debug_fd, "invalid request %d\n", n); | 41 | fprintf(debug_f, "invalid request %d\n", n); |
| 41 | return; | 42 | return; |
| 42 | } | 43 | } |
| 43 | 44 | ||
| @@ -47,7 +48,7 @@ static void loop(void) · 3 unmodified lines | |||
| 47 | 48 | ||
| 48 | n = write(1, &reply, sizeof(reply)); | 49 | n = write(1, &reply, sizeof(reply)); |
| 49 | if (n != sizeof(reply)) { | 50 | if (n != sizeof(reply)) { |
| 50 | dprintf(debug_fd, "reply failed %d\n", n); | 51 | fprintf(debug_f, "reply failed %d\n", n); |
| 51 | return; | 52 | return; |
| 52 | } | 53 | } |
| 53 | } | 54 | } |
| @@ -55,9 +56,10 @@ static void loop(void) · 1 unmodified line | |||
| 55 | 56 | ||
| 56 | int main(void) | 57 | int main(void) |
| 57 | { | 58 | { |
| 58 | debug_fd = open("/dev/kmsg", 00000002); | 59 | debug_f = fopen("/dev/kmsg", "w"); |
| 59 | dprintf(debug_fd, "Started bpfilter\n"); | 60 | setvbuf(debug_f, 0, _IOLBF, 0); |
| 61 | fprintf(debug_f, "Started bpfilter\n"); | ||
| 60 | loop(); | 62 | loop(); |
| 61 | close(debug_fd); | 63 | fclose(debug_f); |
| 62 | return 0; | 64 | return 0; |
| 63 | } | 65 | } |
| @@ -4516,7 +4516,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, · 4515 unmodified lines | |||
| 4516 | /* Reinjected packets coming from act_mirred or similar should | 4516 | /* Reinjected packets coming from act_mirred or similar should |
| 4517 | * not get XDP generic processing. | 4517 | * not get XDP generic processing. |
| 4518 | */ | 4518 | */ |
| 4519 | if (skb_is_tc_redirected(skb)) | 4519 | if (skb_is_redirected(skb)) |
| 4520 | return XDP_PASS; | 4520 | return XDP_PASS; |
| 4521 | 4521 | ||
| 4522 | /* XDP packets must be linear and must have sufficient headroom | 4522 | /* XDP packets must be linear and must have sufficient headroom |
| @@ -5063,7 +5063,7 @@ skip_taps: · 540 unmodified lines | |||
| 5063 | goto out; | 5063 | goto out; |
| 5064 | } | 5064 | } |
| 5065 | #endif | 5065 | #endif |
| 5066 | skb_reset_tc(skb); | 5066 | skb_reset_redirect(skb); |
| 5067 | skip_classify: | 5067 | skip_classify: |
| 5068 | if (pfmemalloc && !skb_pfmemalloc_protocol(skb)) | 5068 | if (pfmemalloc && !skb_pfmemalloc_protocol(skb)) |
| 5069 | goto drop; | 5069 | goto drop; |
| @@ -5195,7 +5195,7 @@ static int __netif_receive_skb_one_core(struct sk_buff *skb, bool pfmemalloc) · 125 unmodified lines | |||
| 5195 | * | 5195 | * |
| 5196 | * More direct receive version of netif_receive_skb(). It should | 5196 | * More direct receive version of netif_receive_skb(). It should |
| 5197 | * only be used by callers that have a need to skip RPS and Generic XDP. | 5197 | * only be used by callers that have a need to skip RPS and Generic XDP. |
| 5198 | * Caller must also take care of handling if (page_is_)pfmemalloc. | 5198 | * Caller must also take care of handling if ``(page_is_)pfmemalloc``. |
| 5199 | * | 5199 | * |
| 5200 | * This function may only be called from softirq context and interrupts | 5200 | * This function may only be called from softirq context and interrupts |
| 5201 | * should be enabled. | 5201 | * should be enabled. |
| @@ -3362,7 +3362,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) · 3361 unmodified lines | |||
| 3362 | /* skb was 'freed' by stack, so clean few | 3362 | /* skb was 'freed' by stack, so clean few |
| 3363 | * bits and reuse it | 3363 | * bits and reuse it |
| 3364 | */ | 3364 | */ |
| 3365 | skb_reset_tc(skb); | 3365 | skb_reset_redirect(skb); |
| 3366 | } while (--burst > 0); | 3366 | } while (--burst > 0); |
| 3367 | goto out; /* Skips xmit_mode M_START_XMIT */ | 3367 | goto out; /* Skips xmit_mode M_START_XMIT */ |
| 3368 | } else if (pkt_dev->xmit_mode == M_QUEUE_XMIT) { | 3368 | } else if (pkt_dev->xmit_mode == M_QUEUE_XMIT) { |
| @@ -299,8 +299,11 @@ static void sock_map_free(struct bpf_map *map) · 298 unmodified lines | |||
| 299 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); | 299 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); |
| 300 | int i; | 300 | int i; |
| 301 | 301 | ||
| 302 | /* After the sync no updates or deletes will be in-flight so it | ||
| 303 | * is safe to walk map and remove entries without risking a race | ||
| 304 | * in EEXIST update case. | ||
| 305 | */ | ||
| 302 | synchronize_rcu(); | 306 | synchronize_rcu(); |
| 303 | raw_spin_lock_bh(&stab->lock); | ||
| 304 | for (i = 0; i < stab->map.max_entries; i++) { | 307 | for (i = 0; i < stab->map.max_entries; i++) { |
| 305 | struct sock **psk = &stab->sks[i]; | 308 | struct sock **psk = &stab->sks[i]; |
| 306 | struct sock *sk; | 309 | struct sock *sk; |
| @@ -314,7 +317,6 @@ static void sock_map_free(struct bpf_map *map) · 7 unmodified lines | |||
| 314 | release_sock(sk); | 317 | release_sock(sk); |
| 315 | } | 318 | } |
| 316 | } | 319 | } |
| 317 | raw_spin_unlock_bh(&stab->lock); | ||
| 318 | 320 | ||
| 319 | /* wait for psock readers accessing its map link */ | 321 | /* wait for psock readers accessing its map link */ |
| 320 | synchronize_rcu(); | 322 | synchronize_rcu(); |
| @@ -1008,10 +1010,13 @@ static void sock_hash_free(struct bpf_map *map) · 687 unmodified lines | |||
| 1008 | struct hlist_node *node; | 1010 | struct hlist_node *node; |
| 1009 | int i; | 1011 | int i; |
| 1010 | 1012 | ||
| 1013 | /* After the sync no updates or deletes will be in-flight so it | ||
| 1014 | * is safe to walk map and remove entries without risking a race | ||
| 1015 | * in EEXIST update case. | ||
| 1016 | */ | ||
| 1011 | synchronize_rcu(); | 1017 | synchronize_rcu(); |
| 1012 | for (i = 0; i < htab->buckets_num; i++) { | 1018 | for (i = 0; i < htab->buckets_num; i++) { |
| 1013 | bucket = sock_hash_select_bucket(htab, i); | 1019 | bucket = sock_hash_select_bucket(htab, i); |
| 1014 | raw_spin_lock_bh(&bucket->lock); | ||
| 1015 | hlist_for_each_entry_safe(elem, node, &bucket->head, node) { | 1020 | hlist_for_each_entry_safe(elem, node, &bucket->head, node) { |
| 1016 | hlist_del_rcu(&elem->node); | 1021 | hlist_del_rcu(&elem->node); |
| 1017 | lock_sock(elem->sk); | 1022 | lock_sock(elem->sk); |
| @@ -1020,7 +1025,6 @@ static void sock_hash_free(struct bpf_map *map) · 2 unmodified lines | |||
| 1020 | rcu_read_unlock(); | 1025 | rcu_read_unlock(); |
| 1021 | release_sock(elem->sk); | 1026 | release_sock(elem->sk); |
| 1022 | } | 1027 | } |
| 1023 | raw_spin_unlock_bh(&bucket->lock); | ||
| 1024 | } | 1028 | } |
| 1025 | 1029 | ||
| 1026 | /* wait for psock readers accessing its map link */ | 1030 | /* wait for psock readers accessing its map link */ |
| @@ -298,47 +298,4 @@ struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev, · 297 unmodified lines | |||
| 298 | } | 298 | } |
| 299 | EXPORT_SYMBOL_GPL(dsa_8021q_xmit); | 299 | EXPORT_SYMBOL_GPL(dsa_8021q_xmit); |
| 300 | 300 | ||
| 301 | /* In the DSA packet_type handler, skb->data points in the middle of the VLAN | ||
| 302 | * tag, after tpid and before tci. This is because so far, ETH_HLEN | ||
| 303 | * (DMAC, SMAC, EtherType) bytes were pulled. | ||
| 304 | * There are 2 bytes of VLAN tag left in skb->data, and upper | ||
| 305 | * layers expect the 'real' EtherType to be consumed as well. | ||
| 306 | * Coincidentally, a VLAN header is also of the same size as | ||
| 307 | * the number of bytes that need to be pulled. | ||
| 308 | * | ||
| 309 | * skb_mac_header skb->data | ||
| 310 | * | | | ||
| 311 | * v v | ||
| 312 | * | | | | | | | | | | | | | | | | | | | | ||
| 313 | * +-----------------------+-----------------------+-------+-------+-------+ | ||
| 314 | * | Destination MAC | Source MAC | TPID | TCI | EType | | ||
| 315 | * +-----------------------+-----------------------+-------+-------+-------+ | ||
| 316 | * ^ | | | ||
| 317 | * |<--VLAN_HLEN-->to <---VLAN_HLEN---> | ||
| 318 | * from | | ||
| 319 | * >>>>>>> v | ||
| 320 | * >>>>>>> | | | | | | | | | | | | | | | | ||
| 321 | * >>>>>>> +-----------------------+-----------------------+-------+ | ||
| 322 | * >>>>>>> | Destination MAC | Source MAC | EType | | ||
| 323 | * +-----------------------+-----------------------+-------+ | ||
| 324 | * ^ ^ | ||
| 325 | * (now part of | | | ||
| 326 | * skb->head) skb_mac_header skb->data | ||
| 327 | */ | ||
| 328 | struct sk_buff *dsa_8021q_remove_header(struct sk_buff *skb) | ||
| 329 | { | ||
| 330 | u8 *from = skb_mac_header(skb); | ||
| 331 | u8 *dest = from + VLAN_HLEN; | ||
| 332 | |||
| 333 | memmove(dest, from, ETH_HLEN - VLAN_HLEN); | ||
| 334 | skb_pull(skb, VLAN_HLEN); | ||
| 335 | skb_push(skb, ETH_HLEN); | ||
| 336 | skb_reset_mac_header(skb); | ||
| 337 | skb_reset_mac_len(skb); | ||
| 338 | skb_pull_rcsum(skb, ETH_HLEN); | ||
| 339 | |||
| 340 | return skb; | ||
| 341 | } | ||
| 342 | EXPORT_SYMBOL_GPL(dsa_8021q_remove_header); | ||
| 343 | |||
| 344 | MODULE_LICENSE("GPL v2"); | 301 | MODULE_LICENSE("GPL v2"); |
| @@ -140,6 +140,8 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, · 139 unmodified lines | |||
| 140 | /* Remove Broadcom tag and update checksum */ | 140 | /* Remove Broadcom tag and update checksum */ |
| 141 | skb_pull_rcsum(skb, BRCM_TAG_LEN); | 141 | skb_pull_rcsum(skb, BRCM_TAG_LEN); |
| 142 | 142 | ||
| 143 | skb->offload_fwd_mark = 1; | ||
| 144 | |||
| 143 | return skb; | 145 | return skb; |
| 144 | } | 146 | } |
| 145 | 147 | ||
| @@ -250,14 +250,14 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb, · 249 unmodified lines | |||
| 250 | { | 250 | { |
| 251 | struct sja1105_meta meta = {0}; | 251 | struct sja1105_meta meta = {0}; |
| 252 | int source_port, switch_id; | 252 | int source_port, switch_id; |
| 253 | struct vlan_ethhdr *hdr; | 253 | struct ethhdr *hdr; |
| 254 | u16 tpid, vid, tci; | 254 | u16 tpid, vid, tci; |
| 255 | bool is_link_local; | 255 | bool is_link_local; |
| 256 | bool is_tagged; | 256 | bool is_tagged; |
| 257 | bool is_meta; | 257 | bool is_meta; |
| 258 | 258 | ||
| 259 | hdr = vlan_eth_hdr(skb); | 259 | hdr = eth_hdr(skb); |
| 260 | tpid = ntohs(hdr->h_vlan_proto); | 260 | tpid = ntohs(hdr->h_proto); |
| 261 | is_tagged = (tpid == ETH_P_SJA1105); | 261 | is_tagged = (tpid == ETH_P_SJA1105); |
| 262 | is_link_local = sja1105_is_link_local(skb); | 262 | is_link_local = sja1105_is_link_local(skb); |
| 263 | is_meta = sja1105_is_meta_frame(skb); | 263 | is_meta = sja1105_is_meta_frame(skb); |
| @@ -266,7 +266,12 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb, · 2 unmodified lines | |||
| 266 | 266 | ||
| 267 | if (is_tagged) { | 267 | if (is_tagged) { |
| 268 | /* Normal traffic path. */ | 268 | /* Normal traffic path. */ |
| 269 | tci = ntohs(hdr->h_vlan_TCI); | 269 | skb_push_rcsum(skb, ETH_HLEN); |
| 270 | __skb_vlan_pop(skb, &tci); | ||
| 271 | skb_pull_rcsum(skb, ETH_HLEN); | ||
| 272 | skb_reset_network_header(skb); | ||
| 273 | skb_reset_transport_header(skb); | ||
| 274 | |||
| 270 | vid = tci & VLAN_VID_MASK; | 275 | vid = tci & VLAN_VID_MASK; |
| 271 | source_port = dsa_8021q_rx_source_port(vid); | 276 | source_port = dsa_8021q_rx_source_port(vid); |
| 272 | switch_id = dsa_8021q_rx_switch_id(vid); | 277 | switch_id = dsa_8021q_rx_switch_id(vid); |
| @@ -295,12 +300,6 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb, · 22 unmodified lines | |||
| 295 | return NULL; | 300 | return NULL; |
| 296 | } | 301 | } |
| 297 | 302 | ||
| 298 | /* Delete/overwrite fake VLAN header, DSA expects to not find | ||
| 299 | * it there, see dsa_switch_rcv: skb_push(skb, ETH_HLEN). | ||
| 300 | */ | ||
| 301 | if (is_tagged) | ||
| 302 | skb = dsa_8021q_remove_header(skb); | ||
| 303 | |||
| 304 | return sja1105_rcv_meta_state_machine(skb, &meta, is_link_local, | 303 | return sja1105_rcv_meta_state_machine(skb, &meta, is_link_local, |
| 305 | is_meta); | 304 | is_meta); |
| 306 | } | 305 | } |
| @@ -109,8 +109,9 @@ int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info) · 108 unmodified lines | |||
| 109 | if (ret < 0) | 109 | if (ret < 0) |
| 110 | return ret; | 110 | return ret; |
| 111 | dev = req_info.dev; | 111 | dev = req_info.dev; |
| 112 | ret = -EOPNOTSUPP; | ||
| 112 | if (!dev->ethtool_ops->get_msglevel || !dev->ethtool_ops->set_msglevel) | 113 | if (!dev->ethtool_ops->get_msglevel || !dev->ethtool_ops->set_msglevel) |
| 113 | return -EOPNOTSUPP; | 114 | goto out_dev; |
| 114 | 115 | ||
| 115 | rtnl_lock(); | 116 | rtnl_lock(); |
| 116 | ret = ethnl_ops_begin(dev); | 117 | ret = ethnl_ops_begin(dev); |
| @@ -131,6 +132,7 @@ out_ops: · 14 unmodified lines | |||
| 131 | ethnl_ops_complete(dev); | 132 | ethnl_ops_complete(dev); |
| 132 | out_rtnl: | 133 | out_rtnl: |
| 133 | rtnl_unlock(); | 134 | rtnl_unlock(); |
| 135 | out_dev: | ||
| 134 | dev_put(dev); | 136 | dev_put(dev); |
| 135 | return ret; | 137 | return ret; |
| 136 | } | 138 | } |
| @@ -128,9 +128,10 @@ int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info) · 127 unmodified lines | |||
| 128 | if (ret < 0) | 128 | if (ret < 0) |
| 129 | return ret; | 129 | return ret; |
| 130 | dev = req_info.dev; | 130 | dev = req_info.dev; |
| 131 | ret = -EOPNOTSUPP; | ||
| 131 | if (!dev->ethtool_ops->get_link_ksettings || | 132 | if (!dev->ethtool_ops->get_link_ksettings || |
| 132 | !dev->ethtool_ops->set_link_ksettings) | 133 | !dev->ethtool_ops->set_link_ksettings) |
| 133 | return -EOPNOTSUPP; | 134 | goto out_dev; |
| 134 | 135 | ||
| 135 | rtnl_lock(); | 136 | rtnl_lock(); |
| 136 | ret = ethnl_ops_begin(dev); | 137 | ret = ethnl_ops_begin(dev); |
| @@ -164,6 +165,7 @@ out_ops: · 27 unmodified lines | |||
| 164 | ethnl_ops_complete(dev); | 165 | ethnl_ops_complete(dev); |
| 165 | out_rtnl: | 166 | out_rtnl: |
| 166 | rtnl_unlock(); | 167 | rtnl_unlock(); |
| 168 | out_dev: | ||
| 167 | dev_put(dev); | 169 | dev_put(dev); |
| 168 | return ret; | 170 | return ret; |
| 169 | } | 171 | } |
| @@ -341,9 +341,10 @@ int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info) · 340 unmodified lines | |||
| 341 | if (ret < 0) | 341 | if (ret < 0) |
| 342 | return ret; | 342 | return ret; |
| 343 | dev = req_info.dev; | 343 | dev = req_info.dev; |
| 344 | ret = -EOPNOTSUPP; | ||
| 344 | if (!dev->ethtool_ops->get_link_ksettings || | 345 | if (!dev->ethtool_ops->get_link_ksettings || |
| 345 | !dev->ethtool_ops->set_link_ksettings) | 346 | !dev->ethtool_ops->set_link_ksettings) |
| 346 | return -EOPNOTSUPP; | 347 | goto out_dev; |
| 347 | 348 | ||
| 348 | rtnl_lock(); | 349 | rtnl_lock(); |
| 349 | ret = ethnl_ops_begin(dev); | 350 | ret = ethnl_ops_begin(dev); |
| @@ -373,6 +374,7 @@ out_ops: · 23 unmodified lines | |||
| 373 | ethnl_ops_complete(dev); | 374 | ethnl_ops_complete(dev); |
| 374 | out_rtnl: | 375 | out_rtnl: |
| 375 | rtnl_unlock(); | 376 | rtnl_unlock(); |
| 377 | out_dev: | ||
| 376 | dev_put(dev); | 378 | dev_put(dev); |
| 377 | return ret; | 379 | return ret; |
| 378 | } | 380 | } |
| @@ -40,6 +40,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info, · 39 unmodified lines | |||
| 40 | struct nlattr *tb[ETHTOOL_A_HEADER_MAX + 1]; | 40 | struct nlattr *tb[ETHTOOL_A_HEADER_MAX + 1]; |
| 41 | const struct nlattr *devname_attr; | 41 | const struct nlattr *devname_attr; |
| 42 | struct net_device *dev = NULL; | 42 | struct net_device *dev = NULL; |
| 43 | u32 flags = 0; | ||
| 43 | int ret; | 44 | int ret; |
| 44 | 45 | ||
| 45 | if (!header) { | 46 | if (!header) { |
| @@ -50,8 +51,17 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info, · 4 unmodified lines | |||
| 50 | ethnl_header_policy, extack); | 51 | ethnl_header_policy, extack); |
| 51 | if (ret < 0) | 52 | if (ret < 0) |
| 52 | return ret; | 53 | return ret; |
| 53 | devname_attr = tb[ETHTOOL_A_HEADER_DEV_NAME]; | 54 | if (tb[ETHTOOL_A_HEADER_FLAGS]) { |
| 55 | flags = nla_get_u32(tb[ETHTOOL_A_HEADER_FLAGS]); | ||
| 56 | if (flags & ~ETHTOOL_FLAG_ALL) { | ||
| 57 | NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_HEADER_FLAGS], | ||
| 58 | "unrecognized request flags"); | ||
| 59 | nl_set_extack_cookie_u32(extack, ETHTOOL_FLAG_ALL); | ||
| 60 | return -EOPNOTSUPP; | ||
| 61 | } | ||
| 62 | } | ||
| 54 | 63 | ||
| 64 | devname_attr = tb[ETHTOOL_A_HEADER_DEV_NAME]; | ||
| 55 | if (tb[ETHTOOL_A_HEADER_DEV_INDEX]) { | 65 | if (tb[ETHTOOL_A_HEADER_DEV_INDEX]) { |
| 56 | u32 ifindex = nla_get_u32(tb[ETHTOOL_A_HEADER_DEV_INDEX]); | 66 | u32 ifindex = nla_get_u32(tb[ETHTOOL_A_HEADER_DEV_INDEX]); |
| 57 | 67 | ||
| @@ -90,9 +100,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info, · 32 unmodified lines | |||
| 90 | } | 100 | } |
| 91 | 101 | ||
| 92 | req_info->dev = dev; | 102 | req_info->dev = dev; |
| 93 | if (tb[ETHTOOL_A_HEADER_FLAGS]) | 103 | req_info->flags = flags; |
| 94 | req_info->flags = nla_get_u32(tb[ETHTOOL_A_HEADER_FLAGS]); | ||
| 95 | |||
| 96 | return 0; | 104 | return 0; |
| 97 | } | 105 | } |
| 98 | 106 | ||
| @@ -129,8 +129,9 @@ int ethnl_set_wol(struct sk_buff *skb, struct genl_info *info) · 128 unmodified lines | |||
| 129 | if (ret < 0) | 129 | if (ret < 0) |
| 130 | return ret; | 130 | return ret; |
| 131 | dev = req_info.dev; | 131 | dev = req_info.dev; |
| 132 | ret = -EOPNOTSUPP; | ||
| 132 | if (!dev->ethtool_ops->get_wol || !dev->ethtool_ops->set_wol) | 133 | if (!dev->ethtool_ops->get_wol || !dev->ethtool_ops->set_wol) |
| 133 | return -EOPNOTSUPP; | 134 | goto out_dev; |
| 134 | 135 | ||
| 135 | rtnl_lock(); | 136 | rtnl_lock(); |
| 136 | ret = ethnl_ops_begin(dev); | 137 | ret = ethnl_ops_begin(dev); |
| @@ -173,6 +174,7 @@ out_ops: · 36 unmodified lines | |||
| 173 | ethnl_ops_complete(dev); | 174 | ethnl_ops_complete(dev); |
| 174 | out_rtnl: | 175 | out_rtnl: |
| 175 | rtnl_unlock(); | 176 | rtnl_unlock(); |
| 177 | out_dev: | ||
| 176 | dev_put(dev); | 178 | dev_put(dev); |
| 177 | return ret; | 179 | return ret; |
| 178 | } | 180 | } |
| @@ -483,12 +483,9 @@ int hsr_get_node_data(struct hsr_priv *hsr, · 482 unmodified lines | |||
| 483 | struct hsr_port *port; | 483 | struct hsr_port *port; |
| 484 | unsigned long tdiff; | 484 | unsigned long tdiff; |
| 485 | 485 | ||
| 486 | rcu_read_lock(); | ||
| 487 | node = find_node_by_addr_A(&hsr->node_db, addr); | 486 | node = find_node_by_addr_A(&hsr->node_db, addr); |
| 488 | if (!node) { | 487 | if (!node) |
| 489 | rcu_read_unlock(); | 488 | return -ENOENT; |
| 490 | return -ENOENT; /* No such entry */ | ||
| 491 | } | ||
| 492 | 489 | ||
| 493 | ether_addr_copy(addr_b, node->macaddress_B); | 490 | ether_addr_copy(addr_b, node->macaddress_B); |
| 494 | 491 | ||
| @@ -523,7 +520,5 @@ int hsr_get_node_data(struct hsr_priv *hsr, · 28 unmodified lines | |||
| 523 | *addr_b_ifindex = -1; | 520 | *addr_b_ifindex = -1; |
| 524 | } | 521 | } |
| 525 | 522 | ||
| 526 | rcu_read_unlock(); | ||
| 527 | |||
| 528 | return 0; | 523 | return 0; |
| 529 | } | 524 | } |
| @@ -250,15 +250,16 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info) · 249 unmodified lines | |||
| 250 | if (!na) | 250 | if (!na) |
| 251 | goto invalid; | 251 | goto invalid; |
| 252 | 252 | ||
| 253 | hsr_dev = __dev_get_by_index(genl_info_net(info), | 253 | rcu_read_lock(); |
| 254 | nla_get_u32(info->attrs[HSR_A_IFINDEX])); | 254 | hsr_dev = dev_get_by_index_rcu(genl_info_net(info), |
| 255 | nla_get_u32(info->attrs[HSR_A_IFINDEX])); | ||
| 255 | if (!hsr_dev) | 256 | if (!hsr_dev) |
| 256 | goto invalid; | 257 | goto rcu_unlock; |
| 257 | if (!is_hsr_master(hsr_dev)) | 258 | if (!is_hsr_master(hsr_dev)) |
| 258 | goto invalid; | 259 | goto rcu_unlock; |
| 259 | 260 | ||
| 260 | /* Send reply */ | 261 | /* Send reply */ |
| 261 | skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 262 | skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); |
| 262 | if (!skb_out) { | 263 | if (!skb_out) { |
| 263 | res = -ENOMEM; | 264 | res = -ENOMEM; |
| 264 | goto fail; | 265 | goto fail; |
| @@ -312,12 +313,10 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info) · 47 unmodified lines | |||
| 312 | res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq); | 313 | res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq); |
| 313 | if (res < 0) | 314 | if (res < 0) |
| 314 | goto nla_put_failure; | 315 | goto nla_put_failure; |
| 315 | rcu_read_lock(); | ||
| 316 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A); | 316 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A); |
| 317 | if (port) | 317 | if (port) |
| 318 | res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX, | 318 | res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX, |
| 319 | port->dev->ifindex); | 319 | port->dev->ifindex); |
| 320 | rcu_read_unlock(); | ||
| 321 | if (res < 0) | 320 | if (res < 0) |
| 322 | goto nla_put_failure; | 321 | goto nla_put_failure; |
| 323 | 322 | ||
| @@ -327,20 +326,22 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info) · 3 unmodified lines | |||
| 327 | res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq); | 326 | res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq); |
| 328 | if (res < 0) | 327 | if (res < 0) |
| 329 | goto nla_put_failure; | 328 | goto nla_put_failure; |
| 330 | rcu_read_lock(); | ||
| 331 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B); | 329 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B); |
| 332 | if (port) | 330 | if (port) |
| 333 | res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX, | 331 | res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX, |
| 334 | port->dev->ifindex); | 332 | port->dev->ifindex); |
| 335 | rcu_read_unlock(); | ||
| 336 | if (res < 0) | 333 | if (res < 0) |
| 337 | goto nla_put_failure; | 334 | goto nla_put_failure; |
| 338 | 335 | ||
| 336 | rcu_read_unlock(); | ||
| 337 | |||
| 339 | genlmsg_end(skb_out, msg_head); | 338 | genlmsg_end(skb_out, msg_head); |
| 340 | genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid); | 339 | genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid); |
| 341 | 340 | ||
| 342 | return 0; | 341 | return 0; |
| 343 | 342 | ||
| 343 | rcu_unlock: | ||
| 344 | rcu_read_unlock(); | ||
| 344 | invalid: | 345 | invalid: |
| 345 | netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL); | 346 | netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL); |
| 346 | return 0; | 347 | return 0; |
| @@ -350,6 +351,7 @@ nla_put_failure: · 3 unmodified lines | |||
| 350 | /* Fall through */ | 351 | /* Fall through */ |
| 351 | 352 | ||
| 352 | fail: | 353 | fail: |
| 354 | rcu_read_unlock(); | ||
| 353 | return res; | 355 | return res; |
| 354 | } | 356 | } |
| 355 | 357 | ||
| @@ -357,16 +359,14 @@ fail: · 1 unmodified line | |||
| 357 | */ | 359 | */ |
| 358 | static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) | 360 | static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) |
| 359 | { | 361 | { |
| 360 | /* For receiving */ | 362 | unsigned char addr[ETH_ALEN]; |
| 361 | struct nlattr *na; | ||
| 362 | struct net_device *hsr_dev; | 363 | struct net_device *hsr_dev; |
| 363 | |||
| 364 | /* For sending */ | ||
| 365 | struct sk_buff *skb_out; | 364 | struct sk_buff *skb_out; |
| 366 | void *msg_head; | ||
| 367 | struct hsr_priv *hsr; | 365 | struct hsr_priv *hsr; |
| 368 | void *pos; | 366 | bool restart = false; |
| 369 | unsigned char addr[ETH_ALEN]; | 367 | struct nlattr *na; |
| 368 | void *pos = NULL; | ||
| 369 | void *msg_head; | ||
| 370 | int res; | 370 | int res; |
| 371 | 371 | ||
| 372 | if (!info) | 372 | if (!info) |
| @@ -376,15 +376,17 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) · 3 unmodified lines | |||
| 376 | if (!na) | 376 | if (!na) |
| 377 | goto invalid; | 377 | goto invalid; |
| 378 | 378 | ||
| 379 | hsr_dev = __dev_get_by_index(genl_info_net(info), | 379 | rcu_read_lock(); |
| 380 | nla_get_u32(info->attrs[HSR_A_IFINDEX])); | 380 | hsr_dev = dev_get_by_index_rcu(genl_info_net(info), |
| 381 | nla_get_u32(info->attrs[HSR_A_IFINDEX])); | ||
| 381 | if (!hsr_dev) | 382 | if (!hsr_dev) |
| 382 | goto invalid; | 383 | goto rcu_unlock; |
| 383 | if (!is_hsr_master(hsr_dev)) | 384 | if (!is_hsr_master(hsr_dev)) |
| 384 | goto invalid; | 385 | goto rcu_unlock; |
| 385 | 386 | ||
| 387 | restart: | ||
| 386 | /* Send reply */ | 388 | /* Send reply */ |
| 387 | skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 389 | skb_out = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); |
| 388 | if (!skb_out) { | 390 | if (!skb_out) { |
| 389 | res = -ENOMEM; | 391 | res = -ENOMEM; |
| 390 | goto fail; | 392 | goto fail; |
| @@ -398,18 +400,26 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) · 7 unmodified lines | |||
| 398 | goto nla_put_failure; | 400 | goto nla_put_failure; |
| 399 | } | 401 | } |
| 400 | 402 | ||
| 401 | res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex); | 403 | if (!restart) { |
| 402 | if (res < 0) | 404 | res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex); |
| 403 | goto nla_put_failure; | 405 | if (res < 0) |
| 406 | goto nla_put_failure; | ||
| 407 | } | ||
| 404 | 408 | ||
| 405 | hsr = netdev_priv(hsr_dev); | 409 | hsr = netdev_priv(hsr_dev); |
| 406 | 410 | ||
| 407 | rcu_read_lock(); | 411 | if (!pos) |
| 408 | pos = hsr_get_next_node(hsr, NULL, addr); | 412 | pos = hsr_get_next_node(hsr, NULL, addr); |
| 409 | while (pos) { | 413 | while (pos) { |
| 410 | res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr); | 414 | res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr); |
| 411 | if (res < 0) { | 415 | if (res < 0) { |
| 412 | rcu_read_unlock(); | 416 | if (res == -EMSGSIZE) { |
| 417 | genlmsg_end(skb_out, msg_head); | ||
| 418 | genlmsg_unicast(genl_info_net(info), skb_out, | ||
| 419 | info->snd_portid); | ||
| 420 | restart = true; | ||
| 421 | goto restart; | ||
| 422 | } | ||
| 413 | goto nla_put_failure; | 423 | goto nla_put_failure; |
| 414 | } | 424 | } |
| 415 | pos = hsr_get_next_node(hsr, pos, addr); | 425 | pos = hsr_get_next_node(hsr, pos, addr); |
| @@ -421,15 +431,18 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) · 5 unmodified lines | |||
| 421 | 431 | ||
| 422 | return 0; | 432 | return 0; |
| 423 | 433 | ||
| 434 | rcu_unlock: | ||
| 435 | rcu_read_unlock(); | ||
| 424 | invalid: | 436 | invalid: |
| 425 | netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL); | 437 | netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL); |
| 426 | return 0; | 438 | return 0; |
| 427 | 439 | ||
| 428 | nla_put_failure: | 440 | nla_put_failure: |
| 429 | kfree_skb(skb_out); | 441 | nlmsg_free(skb_out); |
| 430 | /* Fall through */ | 442 | /* Fall through */ |
| 431 | 443 | ||
| 432 | fail: | 444 | fail: |
| 445 | rcu_read_unlock(); | ||
| 433 | return res; | 446 | return res; |
| 434 | } | 447 | } |
| 435 | 448 | ||
| @@ -456,6 +469,7 @@ static struct genl_family hsr_genl_family __ro_after_init = { · 20 unmodified lines | |||
| 456 | .version = 1, | 469 | .version = 1, |
| 457 | .maxattr = HSR_A_MAX, | 470 | .maxattr = HSR_A_MAX, |
| 458 | .policy = hsr_genl_policy, | 471 | .policy = hsr_genl_policy, |
| 472 | .netnsok = true, | ||
| 459 | .module = THIS_MODULE, | 473 | .module = THIS_MODULE, |
| 460 | .ops = hsr_ops, | 474 | .ops = hsr_ops, |
| 461 | .n_ops = ARRAY_SIZE(hsr_ops), | 475 | .n_ops = ARRAY_SIZE(hsr_ops), |
| @@ -151,16 +151,16 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, · 150 unmodified lines | |||
| 151 | if (!port) | 151 | if (!port) |
| 152 | return -ENOMEM; | 152 | return -ENOMEM; |
| 153 | 153 | ||
| 154 | port->hsr = hsr; | ||
| 155 | port->dev = dev; | ||
| 156 | port->type = type; | ||
| 157 | |||
| 154 | if (type != HSR_PT_MASTER) { | 158 | if (type != HSR_PT_MASTER) { |
| 155 | res = hsr_portdev_setup(hsr, dev, port, extack); | 159 | res = hsr_portdev_setup(hsr, dev, port, extack); |
| 156 | if (res) | 160 | if (res) |
| 157 | goto fail_dev_setup; | 161 | goto fail_dev_setup; |
| 158 | } | 162 | } |
| 159 | 163 | ||
| 160 | port->hsr = hsr; | ||
| 161 | port->dev = dev; | ||
| 162 | port->type = type; | ||
| 163 | |||
| 164 | list_add_tail_rcu(&port->port_list, &hsr->ports); | 164 | list_add_tail_rcu(&port->port_list, &hsr->ports); |
| 165 | synchronize_rcu(); | 165 | synchronize_rcu(); |
| 166 | 166 | ||
| @@ -997,7 +997,9 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) · 996 unmodified lines | |||
| 997 | return -ENOENT; | 997 | return -ENOENT; |
| 998 | } | 998 | } |
| 999 | 999 | ||
| 1000 | rcu_read_lock(); | ||
| 1000 | err = fib_table_dump(tb, skb, cb, &filter); | 1001 | err = fib_table_dump(tb, skb, cb, &filter); |
| 1002 | rcu_read_unlock(); | ||
| 1001 | return skb->len ? : err; | 1003 | return skb->len ? : err; |
| 1002 | } | 1004 | } |
| 1003 | 1005 | ||
| @@ -1153,6 +1153,24 @@ static int ipgre_netlink_parms(struct net_device *dev, · 1152 unmodified lines | |||
| 1153 | if (data[IFLA_GRE_FWMARK]) | 1153 | if (data[IFLA_GRE_FWMARK]) |
| 1154 | *fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]); | 1154 | *fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]); |
| 1155 | 1155 | ||
| 1156 | return 0; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | static int erspan_netlink_parms(struct net_device *dev, | ||
| 1160 | struct nlattr *data[], | ||
| 1161 | struct nlattr *tb[], | ||
| 1162 | struct ip_tunnel_parm *parms, | ||
| 1163 | __u32 *fwmark) | ||
| 1164 | { | ||
| 1165 | struct ip_tunnel *t = netdev_priv(dev); | ||
| 1166 | int err; | ||
| 1167 | |||
| 1168 | err = ipgre_netlink_parms(dev, data, tb, parms, fwmark); | ||
| 1169 | if (err) | ||
| 1170 | return err; | ||
| 1171 | if (!data) | ||
| 1172 | return 0; | ||
| 1173 | |||
| 1156 | if (data[IFLA_GRE_ERSPAN_VER]) { | 1174 | if (data[IFLA_GRE_ERSPAN_VER]) { |
| 1157 | t->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); | 1175 | t->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); |
| 1158 | 1176 | ||
| @@ -1276,45 +1294,70 @@ static void ipgre_tap_setup(struct net_device *dev) · 117 unmodified lines | |||
| 1276 | ip_tunnel_setup(dev, gre_tap_net_id); | 1294 | ip_tunnel_setup(dev, gre_tap_net_id); |
| 1277 | } | 1295 | } |
| 1278 | 1296 | ||
| 1279 | static int ipgre_newlink(struct net *src_net, struct net_device *dev, | 1297 | static int |
| 1280 | struct nlattr *tb[], struct nlattr *data[], | 1298 | ipgre_newlink_encap_setup(struct net_device *dev, struct nlattr *data[]) |
| 1281 | struct netlink_ext_ack *extack) | ||
| 1282 | { | 1299 | { |
| 1283 | struct ip_tunnel_parm p; | ||
| 1284 | struct ip_tunnel_encap ipencap; | 1300 | struct ip_tunnel_encap ipencap; |
| 1285 | __u32 fwmark = 0; | ||
| 1286 | int err; | ||
| 1287 | 1301 | ||
| 1288 | if (ipgre_netlink_encap_parms(data, &ipencap)) { | 1302 | if (ipgre_netlink_encap_parms(data, &ipencap)) { |
| 1289 | struct ip_tunnel *t = netdev_priv(dev); | 1303 | struct ip_tunnel *t = netdev_priv(dev); |
| 1290 | err = ip_tunnel_encap_setup(t, &ipencap); | 1304 | int err = ip_tunnel_encap_setup(t, &ipencap); |
| 1291 | 1305 | ||
| 1292 | if (err < 0) | 1306 | if (err < 0) |
| 1293 | return err; | 1307 | return err; |
| 1294 | } | 1308 | } |
| 1295 | 1309 | ||
| 1310 | return 0; | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | static int ipgre_newlink(struct net *src_net, struct net_device *dev, | ||
| 1314 | struct nlattr *tb[], struct nlattr *data[], | ||
| 1315 | struct netlink_ext_ack *extack) | ||
| 1316 | { | ||
| 1317 | struct ip_tunnel_parm p; | ||
| 1318 | __u32 fwmark = 0; | ||
| 1319 | int err; | ||
| 1320 | |||
| 1321 | err = ipgre_newlink_encap_setup(dev, data); | ||
| 1322 | if (err) | ||
| 1323 | return err; | ||
| 1324 | |||
| 1296 | err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); | 1325 | err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); |
| 1297 | if (err < 0) | 1326 | if (err < 0) |
| 1298 | return err; | 1327 | return err; |
| 1299 | return ip_tunnel_newlink(dev, tb, &p, fwmark); | 1328 | return ip_tunnel_newlink(dev, tb, &p, fwmark); |
| 1300 | } | 1329 | } |
| 1301 | 1330 | ||
| 1331 | static int erspan_newlink(struct net *src_net, struct net_device *dev, | ||
| 1332 | struct nlattr *tb[], struct nlattr *data[], | ||
| 1333 | struct netlink_ext_ack *extack) | ||
| 1334 | { | ||
| 1335 | struct ip_tunnel_parm p; | ||
| 1336 | __u32 fwmark = 0; | ||
| 1337 | int err; | ||
| 1338 | |||
| 1339 | err = ipgre_newlink_encap_setup(dev, data); | ||
| 1340 | if (err) | ||
| 1341 | return err; | ||
| 1342 | |||
| 1343 | err = erspan_netlink_parms(dev, data, tb, &p, &fwmark); | ||
| 1344 | if (err) | ||
| 1345 | return err; | ||
| 1346 | return ip_tunnel_newlink(dev, tb, &p, fwmark); | ||
| 1347 | } | ||
| 1348 | |||
| 1302 | static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], | 1349 | static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], |
| 1303 | struct nlattr *data[], | 1350 | struct nlattr *data[], |
| 1304 | struct netlink_ext_ack *extack) | 1351 | struct netlink_ext_ack *extack) |
| 1305 | { | 1352 | { |
| 1306 | struct ip_tunnel *t = netdev_priv(dev); | 1353 | struct ip_tunnel *t = netdev_priv(dev); |
| 1307 | struct ip_tunnel_encap ipencap; | ||
| 1308 | __u32 fwmark = t->fwmark; | 1354 | __u32 fwmark = t->fwmark; |
| 1309 | struct ip_tunnel_parm p; | 1355 | struct ip_tunnel_parm p; |
| 1310 | int err; | 1356 | int err; |
| 1311 | 1357 | ||
| 1312 | if (ipgre_netlink_encap_parms(data, &ipencap)) { | 1358 | err = ipgre_newlink_encap_setup(dev, data); |
| 1313 | err = ip_tunnel_encap_setup(t, &ipencap); | 1359 | if (err) |
| 1314 | 1360 | return err; | |
| 1315 | if (err < 0) | ||
| 1316 | return err; | ||
| 1317 | } | ||
| 1318 | 1361 | ||
| 1319 | err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); | 1362 | err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); |
| 1320 | if (err < 0) | 1363 | if (err < 0) |
| @@ -1327,8 +1370,34 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], · 6 unmodified lines | |||
| 1327 | t->parms.i_flags = p.i_flags; | 1370 | t->parms.i_flags = p.i_flags; |
| 1328 | t->parms.o_flags = p.o_flags; | 1371 | t->parms.o_flags = p.o_flags; |
| 1329 | 1372 | ||
| 1330 | if (strcmp(dev->rtnl_link_ops->kind, "erspan")) | 1373 | ipgre_link_update(dev, !tb[IFLA_MTU]); |
| 1331 | ipgre_link_update(dev, !tb[IFLA_MTU]); | 1374 | |
| 1375 | return 0; | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | static int erspan_changelink(struct net_device *dev, struct nlattr *tb[], | ||
| 1379 | struct nlattr *data[], | ||
| 1380 | struct netlink_ext_ack *extack) | ||
| 1381 | { | ||
| 1382 | struct ip_tunnel *t = netdev_priv(dev); | ||
| 1383 | __u32 fwmark = t->fwmark; | ||
| 1384 | struct ip_tunnel_parm p; | ||
| 1385 | int err; | ||
| 1386 | |||
| 1387 | err = ipgre_newlink_encap_setup(dev, data); | ||
| 1388 | if (err) | ||
| 1389 | return err; | ||
| 1390 | |||
| 1391 | err = erspan_netlink_parms(dev, data, tb, &p, &fwmark); | ||
| 1392 | if (err < 0) | ||
| 1393 | return err; | ||
| 1394 | |||
| 1395 | err = ip_tunnel_changelink(dev, tb, &p, fwmark); | ||
| 1396 | if (err < 0) | ||
| 1397 | return err; | ||
| 1398 | |||
| 1399 | t->parms.i_flags = p.i_flags; | ||
| 1400 | t->parms.o_flags = p.o_flags; | ||
| 1332 | 1401 | ||
| 1333 | return 0; | 1402 | return 0; |
| 1334 | } | 1403 | } |
| @@ -1519,8 +1588,8 @@ static struct rtnl_link_ops erspan_link_ops __read_mostly = { · 184 unmodified lines | |||
| 1519 | .priv_size = sizeof(struct ip_tunnel), | 1588 | .priv_size = sizeof(struct ip_tunnel), |
| 1520 | .setup = erspan_setup, | 1589 | .setup = erspan_setup, |
| 1521 | .validate = erspan_validate, | 1590 | .validate = erspan_validate, |
| 1522 | .newlink = ipgre_newlink, | 1591 | .newlink = erspan_newlink, |
| 1523 | .changelink = ipgre_changelink, | 1592 | .changelink = erspan_changelink, |
| 1524 | .dellink = ip_tunnel_dellink, | 1593 | .dellink = ip_tunnel_dellink, |
| 1525 | .get_size = ipgre_get_size, | 1594 | .get_size = ipgre_get_size, |
| 1526 | .fill_info = ipgre_fill_info, | 1595 | .fill_info = ipgre_fill_info, |
| @@ -2948,8 +2948,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, · 2947 unmodified lines | |||
| 2948 | err = -EPERM; | 2948 | err = -EPERM; |
| 2949 | else if (tp->repair_queue == TCP_SEND_QUEUE) | 2949 | else if (tp->repair_queue == TCP_SEND_QUEUE) |
| 2950 | WRITE_ONCE(tp->write_seq, val); | 2950 | WRITE_ONCE(tp->write_seq, val); |
| 2951 | else if (tp->repair_queue == TCP_RECV_QUEUE) | 2951 | else if (tp->repair_queue == TCP_RECV_QUEUE) { |
| 2952 | WRITE_ONCE(tp->rcv_nxt, val); | 2952 | WRITE_ONCE(tp->rcv_nxt, val); |
| 2953 | WRITE_ONCE(tp->copied_seq, val); | ||
| 2954 | } | ||
| 2953 | else | 2955 | else |
| 2954 | err = -EINVAL; | 2956 | err = -EINVAL; |
| 2955 | break; | 2957 | break; |
| @@ -1109,6 +1109,10 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, · 1108 unmodified lines | |||
| 1109 | 1109 | ||
| 1110 | if (unlikely(!skb)) | 1110 | if (unlikely(!skb)) |
| 1111 | return -ENOBUFS; | 1111 | return -ENOBUFS; |
| 1112 | /* retransmit skbs might have a non zero value in skb->dev | ||
| 1113 | * because skb->dev is aliased with skb->rbnode.rb_left | ||
| 1114 | */ | ||
| 1115 | skb->dev = NULL; | ||
| 1112 | } | 1116 | } |
| 1113 | 1117 | ||
| 1114 | inet = inet_sk(sk); | 1118 | inet = inet_sk(sk); |
| @@ -3037,8 +3041,12 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) · 1922 unmodified lines | |||
| 3037 | 3041 | ||
| 3038 | tcp_skb_tsorted_save(skb) { | 3042 | tcp_skb_tsorted_save(skb) { |
| 3039 | nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC); | 3043 | nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC); |
| 3040 | err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 3044 | if (nskb) { |
| 3041 | -ENOBUFS; | 3045 | nskb->dev = NULL; |
| 3046 | err = tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC); | ||
| 3047 | } else { | ||
| 3048 | err = -ENOBUFS; | ||
| 3049 | } | ||
| 3042 | } tcp_skb_tsorted_restore(skb); | 3050 | } tcp_skb_tsorted_restore(skb); |
| 3043 | 3051 | ||
| 3044 | if (!err) { | 3052 | if (!err) { |
| @@ -613,6 +613,9 @@ void nf_flow_table_free(struct nf_flowtable *flow_table) · 612 unmodified lines | |||
| 613 | nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); | 613 | nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); |
| 614 | nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table); | 614 | nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table); |
| 615 | nf_flow_table_offload_flush(flow_table); | 615 | nf_flow_table_offload_flush(flow_table); |
| 616 | if (nf_flowtable_hw_offload(flow_table)) | ||
| 617 | nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, | ||
| 618 | flow_table); | ||
| 616 | rhashtable_destroy(&flow_table->rhashtable); | 619 | rhashtable_destroy(&flow_table->rhashtable); |
| 617 | mutex_destroy(&flow_table->flow_block_lock); | 620 | mutex_destroy(&flow_table->flow_block_lock); |
| 618 | } | 621 | } |
| @@ -146,11 +146,13 @@ static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb, · 145 unmodified lines | |||
| 146 | 146 | ||
| 147 | if (test_bit(NF_FLOW_SNAT, &flow->flags) && | 147 | if (test_bit(NF_FLOW_SNAT, &flow->flags) && |
| 148 | (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 || | 148 | (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 || |
| 149 | nf_flow_snat_ip(flow, skb, iph, thoff, dir) < 0)) | 149 | nf_flow_snat_ip(flow, skb, ip_hdr(skb), thoff, dir) < 0)) |
| 150 | return -1; | 150 | return -1; |
| 151 | |||
| 152 | iph = ip_hdr(skb); | ||
| 151 | if (test_bit(NF_FLOW_DNAT, &flow->flags) && | 153 | if (test_bit(NF_FLOW_DNAT, &flow->flags) && |
| 152 | (nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 || | 154 | (nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 || |
| 153 | nf_flow_dnat_ip(flow, skb, iph, thoff, dir) < 0)) | 155 | nf_flow_dnat_ip(flow, skb, ip_hdr(skb), thoff, dir) < 0)) |
| 154 | return -1; | 156 | return -1; |
| 155 | 157 | ||
| 156 | return 0; | 158 | return 0; |
| @@ -189,6 +191,7 @@ static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev, · 32 unmodified lines | |||
| 189 | if (!pskb_may_pull(skb, thoff + sizeof(*ports))) | 191 | if (!pskb_may_pull(skb, thoff + sizeof(*ports))) |
| 190 | return -1; | 192 | return -1; |
| 191 | 193 | ||
| 194 | iph = ip_hdr(skb); | ||
| 192 | ports = (struct flow_ports *)(skb_network_header(skb) + thoff); | 195 | ports = (struct flow_ports *)(skb_network_header(skb) + thoff); |
| 193 | 196 | ||
| 194 | tuple->src_v4.s_addr = iph->saddr; | 197 | tuple->src_v4.s_addr = iph->saddr; |
| @@ -417,11 +420,13 @@ static int nf_flow_nat_ipv6(const struct flow_offload *flow, · 222 unmodified lines | |||
| 417 | 420 | ||
| 418 | if (test_bit(NF_FLOW_SNAT, &flow->flags) && | 421 | if (test_bit(NF_FLOW_SNAT, &flow->flags) && |
| 419 | (nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || | 422 | (nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || |
| 420 | nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) | 423 | nf_flow_snat_ipv6(flow, skb, ipv6_hdr(skb), thoff, dir) < 0)) |
| 421 | return -1; | 424 | return -1; |
| 425 | |||
| 426 | ip6h = ipv6_hdr(skb); | ||
| 422 | if (test_bit(NF_FLOW_DNAT, &flow->flags) && | 427 | if (test_bit(NF_FLOW_DNAT, &flow->flags) && |
| 423 | (nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || | 428 | (nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || |
| 424 | nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) | 429 | nf_flow_dnat_ipv6(flow, skb, ipv6_hdr(skb), thoff, dir) < 0)) |
| 425 | return -1; | 430 | return -1; |
| 426 | 431 | ||
| 427 | return 0; | 432 | return 0; |
| @@ -450,6 +455,7 @@ static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev, · 22 unmodified lines | |||
| 450 | if (!pskb_may_pull(skb, thoff + sizeof(*ports))) | 455 | if (!pskb_may_pull(skb, thoff + sizeof(*ports))) |
| 451 | return -1; | 456 | return -1; |
| 452 | 457 | ||
| 458 | ip6h = ipv6_hdr(skb); | ||
| 453 | ports = (struct flow_ports *)(skb_network_header(skb) + thoff); | 459 | ports = (struct flow_ports *)(skb_network_header(skb) + thoff); |
| 454 | 460 | ||
| 455 | tuple->src_v6 = ip6h->saddr; | 461 | tuple->src_v6 = ip6h->saddr; |
| @@ -120,6 +120,7 @@ static int nf_flow_rule_match(struct nf_flow_match *match, · 119 unmodified lines | |||
| 120 | default: | 120 | default: |
| 121 | return -EOPNOTSUPP; | 121 | return -EOPNOTSUPP; |
| 122 | } | 122 | } |
| 123 | mask->control.addr_type = 0xffff; | ||
| 123 | match->dissector.used_keys |= BIT(key->control.addr_type); | 124 | match->dissector.used_keys |= BIT(key->control.addr_type); |
| 124 | mask->basic.n_proto = 0xffff; | 125 | mask->basic.n_proto = 0xffff; |
| 125 | 126 | ||
| @@ -5106,6 +5106,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 5105 unmodified lines | |||
| 5106 | err = -EBUSY; | 5106 | err = -EBUSY; |
| 5107 | else if (!(nlmsg_flags & NLM_F_EXCL)) | 5107 | else if (!(nlmsg_flags & NLM_F_EXCL)) |
| 5108 | err = 0; | 5108 | err = 0; |
| 5109 | } else if (err == -ENOTEMPTY) { | ||
| 5110 | /* ENOTEMPTY reports overlapping between this element | ||
| 5111 | * and an existing one. | ||
| 5112 | */ | ||
| 5113 | err = -EEXIST; | ||
| 5109 | } | 5114 | } |
| 5110 | goto err_element_clash; | 5115 | goto err_element_clash; |
| 5111 | } | 5116 | } |
| @@ -28,6 +28,9 @@ static void nft_fwd_netdev_eval(const struct nft_expr *expr, · 27 unmodified lines | |||
| 28 | struct nft_fwd_netdev *priv = nft_expr_priv(expr); | 28 | struct nft_fwd_netdev *priv = nft_expr_priv(expr); |
| 29 | int oif = regs->data[priv->sreg_dev]; | 29 | int oif = regs->data[priv->sreg_dev]; |
| 30 | 30 | ||
| 31 | /* This is used by ifb only. */ | ||
| 32 | skb_set_redirected(pkt->skb, true); | ||
| 33 | |||
| 31 | nf_fwd_netdev_egress(pkt, oif); | 34 | nf_fwd_netdev_egress(pkt, oif); |
| 32 | regs->verdict.code = NF_STOLEN; | 35 | regs->verdict.code = NF_STOLEN; |
| 33 | } | 36 | } |
| @@ -190,6 +193,13 @@ nla_put_failure: · 156 unmodified lines | |||
| 190 | return -1; | 193 | return -1; |
| 191 | } | 194 | } |
| 192 | 195 | ||
| 196 | static int nft_fwd_validate(const struct nft_ctx *ctx, | ||
| 197 | const struct nft_expr *expr, | ||
| 198 | const struct nft_data **data) | ||
| 199 | { | ||
| 200 | return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS)); | ||
| 201 | } | ||
| 202 | |||
| 193 | static struct nft_expr_type nft_fwd_netdev_type; | 203 | static struct nft_expr_type nft_fwd_netdev_type; |
| 194 | static const struct nft_expr_ops nft_fwd_neigh_netdev_ops = { | 204 | static const struct nft_expr_ops nft_fwd_neigh_netdev_ops = { |
| 195 | .type = &nft_fwd_netdev_type, | 205 | .type = &nft_fwd_netdev_type, |
| @@ -197,6 +207,7 @@ static const struct nft_expr_ops nft_fwd_neigh_netdev_ops = { · 1 unmodified line | |||
| 197 | .eval = nft_fwd_neigh_eval, | 207 | .eval = nft_fwd_neigh_eval, |
| 198 | .init = nft_fwd_neigh_init, | 208 | .init = nft_fwd_neigh_init, |
| 199 | .dump = nft_fwd_neigh_dump, | 209 | .dump = nft_fwd_neigh_dump, |
| 210 | .validate = nft_fwd_validate, | ||
| 200 | }; | 211 | }; |
| 201 | 212 | ||
| 202 | static const struct nft_expr_ops nft_fwd_netdev_ops = { | 213 | static const struct nft_expr_ops nft_fwd_netdev_ops = { |
| @@ -205,6 +216,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = { · 2 unmodified lines | |||
| 205 | .eval = nft_fwd_netdev_eval, | 216 | .eval = nft_fwd_netdev_eval, |
| 206 | .init = nft_fwd_netdev_init, | 217 | .init = nft_fwd_netdev_init, |
| 207 | .dump = nft_fwd_netdev_dump, | 218 | .dump = nft_fwd_netdev_dump, |
| 219 | .validate = nft_fwd_validate, | ||
| 208 | .offload = nft_fwd_netdev_offload, | 220 | .offload = nft_fwd_netdev_offload, |
| 209 | }; | 221 | }; |
| 210 | 222 | ||
| @@ -1164,21 +1164,41 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set, · 1163 unmodified lines | |||
| 1164 | struct nft_pipapo_field *f; | 1164 | struct nft_pipapo_field *f; |
| 1165 | int i, bsize_max, err = 0; | 1165 | int i, bsize_max, err = 0; |
| 1166 | 1166 | ||
| 1167 | if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END)) | ||
| 1168 | end = (const u8 *)nft_set_ext_key_end(ext)->data; | ||
| 1169 | else | ||
| 1170 | end = start; | ||
| 1171 | |||
| 1167 | dup = pipapo_get(net, set, start, genmask); | 1172 | dup = pipapo_get(net, set, start, genmask); |
| 1168 | if (PTR_ERR(dup) == -ENOENT) { | 1173 | if (!IS_ERR(dup)) { |
| 1169 | if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END)) { | 1174 | /* Check if we already have the same exact entry */ |
| 1170 | end = (const u8 *)nft_set_ext_key_end(ext)->data; | 1175 | const struct nft_data *dup_key, *dup_end; |
| 1171 | dup = pipapo_get(net, set, end, nft_genmask_next(net)); | 1176 | |
| 1172 | } else { | 1177 | dup_key = nft_set_ext_key(&dup->ext); |
| 1173 | end = start; | 1178 | if (nft_set_ext_exists(&dup->ext, NFT_SET_EXT_KEY_END)) |
| 1179 | dup_end = nft_set_ext_key_end(&dup->ext); | ||
| 1180 | else | ||
| 1181 | dup_end = dup_key; | ||
| 1182 | |||
| 1183 | if (!memcmp(start, dup_key->data, sizeof(*dup_key->data)) && | ||
| 1184 | !memcmp(end, dup_end->data, sizeof(*dup_end->data))) { | ||
| 1185 | *ext2 = &dup->ext; | ||
| 1186 | return -EEXIST; | ||
| 1174 | } | 1187 | } |
| 1188 | |||
| 1189 | return -ENOTEMPTY; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | if (PTR_ERR(dup) == -ENOENT) { | ||
| 1193 | /* Look for partially overlapping entries */ | ||
| 1194 | dup = pipapo_get(net, set, end, nft_genmask_next(net)); | ||
| 1175 | } | 1195 | } |
| 1176 | 1196 | ||
| 1177 | if (PTR_ERR(dup) != -ENOENT) { | 1197 | if (PTR_ERR(dup) != -ENOENT) { |
| 1178 | if (IS_ERR(dup)) | 1198 | if (IS_ERR(dup)) |
| 1179 | return PTR_ERR(dup); | 1199 | return PTR_ERR(dup); |
| 1180 | *ext2 = &dup->ext; | 1200 | *ext2 = &dup->ext; |
| 1181 | return -EEXIST; | 1201 | return -ENOTEMPTY; |
| 1182 | } | 1202 | } |
| 1183 | 1203 | ||
| 1184 | /* Validate */ | 1204 | /* Validate */ |
| @@ -33,6 +33,11 @@ static bool nft_rbtree_interval_end(const struct nft_rbtree_elem *rbe) · 32 unmodified lines | |||
| 33 | (*nft_set_ext_flags(&rbe->ext) & NFT_SET_ELEM_INTERVAL_END); | 33 | (*nft_set_ext_flags(&rbe->ext) & NFT_SET_ELEM_INTERVAL_END); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static bool nft_rbtree_interval_start(const struct nft_rbtree_elem *rbe) | ||
| 37 | { | ||
| 38 | return !nft_rbtree_interval_end(rbe); | ||
| 39 | } | ||
| 40 | |||
| 36 | static bool nft_rbtree_equal(const struct nft_set *set, const void *this, | 41 | static bool nft_rbtree_equal(const struct nft_set *set, const void *this, |
| 37 | const struct nft_rbtree_elem *interval) | 42 | const struct nft_rbtree_elem *interval) |
| 38 | { | 43 | { |
| @@ -64,7 +69,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set · 25 unmodified lines | |||
| 64 | if (interval && | 69 | if (interval && |
| 65 | nft_rbtree_equal(set, this, interval) && | 70 | nft_rbtree_equal(set, this, interval) && |
| 66 | nft_rbtree_interval_end(rbe) && | 71 | nft_rbtree_interval_end(rbe) && |
| 67 | !nft_rbtree_interval_end(interval)) | 72 | nft_rbtree_interval_start(interval)) |
| 68 | continue; | 73 | continue; |
| 69 | interval = rbe; | 74 | interval = rbe; |
| 70 | } else if (d > 0) | 75 | } else if (d > 0) |
| @@ -89,7 +94,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set · 18 unmodified lines | |||
| 89 | 94 | ||
| 90 | if (set->flags & NFT_SET_INTERVAL && interval != NULL && | 95 | if (set->flags & NFT_SET_INTERVAL && interval != NULL && |
| 91 | nft_set_elem_active(&interval->ext, genmask) && | 96 | nft_set_elem_active(&interval->ext, genmask) && |
| 92 | !nft_rbtree_interval_end(interval)) { | 97 | nft_rbtree_interval_start(interval)) { |
| 93 | *ext = &interval->ext; | 98 | *ext = &interval->ext; |
| 94 | return true; | 99 | return true; |
| 95 | } | 100 | } |
| @@ -208,8 +213,43 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, · 112 unmodified lines | |||
| 208 | u8 genmask = nft_genmask_next(net); | 213 | u8 genmask = nft_genmask_next(net); |
| 209 | struct nft_rbtree_elem *rbe; | 214 | struct nft_rbtree_elem *rbe; |
| 210 | struct rb_node *parent, **p; | 215 | struct rb_node *parent, **p; |
| 216 | bool overlap = false; | ||
| 211 | int d; | 217 | int d; |
| 212 | 218 | ||
| 219 | /* Detect overlaps as we descend the tree. Set the flag in these cases: | ||
| 220 | * | ||
| 221 | * a1. |__ _ _? >|__ _ _ (insert start after existing start) | ||
| 222 | * a2. _ _ __>| ?_ _ __| (insert end before existing end) | ||
| 223 | * a3. _ _ ___| ?_ _ _>| (insert end after existing end) | ||
| 224 | * a4. >|__ _ _ _ _ __| (insert start before existing end) | ||
| 225 | * | ||
| 226 | * and clear it later on, as we eventually reach the points indicated by | ||
| 227 | * '?' above, in the cases described below. We'll always meet these | ||
| 228 | * later, locally, due to tree ordering, and overlaps for the intervals | ||
| 229 | * that are the closest together are always evaluated last. | ||
| 230 | * | ||
| 231 | * b1. |__ _ _! >|__ _ _ (insert start after existing end) | ||
| 232 | * b2. _ _ __>| !_ _ __| (insert end before existing start) | ||
| 233 | * b3. !_____>| (insert end after existing start) | ||
| 234 | * | ||
| 235 | * Case a4. resolves to b1.: | ||
| 236 | * - if the inserted start element is the leftmost, because the '0' | ||
| 237 | * element in the tree serves as end element | ||
| 238 | * - otherwise, if an existing end is found. Note that end elements are | ||
| 239 | * always inserted after corresponding start elements. | ||
| 240 | * | ||
| 241 | * For a new, rightmost pair of elements, we'll hit cases b1. and b3., | ||
| 242 | * in that order. | ||
| 243 | * | ||
| 244 | * The flag is also cleared in two special cases: | ||
| 245 | * | ||
| 246 | * b4. |__ _ _!|<_ _ _ (insert start right before existing end) | ||
| 247 | * b5. |__ _ >|!__ _ _ (insert end right after existing start) | ||
| 248 | * | ||
| 249 | * which always happen as last step and imply that no further | ||
| 250 | * overlapping is possible. | ||
| 251 | */ | ||
| 252 | |||
| 213 | parent = NULL; | 253 | parent = NULL; |
| 214 | p = &priv->root.rb_node; | 254 | p = &priv->root.rb_node; |
| 215 | while (*p != NULL) { | 255 | while (*p != NULL) { |
| @@ -218,17 +258,42 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, · 2 unmodified lines | |||
| 218 | d = memcmp(nft_set_ext_key(&rbe->ext), | 258 | d = memcmp(nft_set_ext_key(&rbe->ext), |
| 219 | nft_set_ext_key(&new->ext), | 259 | nft_set_ext_key(&new->ext), |
| 220 | set->klen); | 260 | set->klen); |
| 221 | if (d < 0) | 261 | if (d < 0) { |
| 222 | p = &parent->rb_left; | 262 | p = &parent->rb_left; |
| 223 | else if (d > 0) | 263 | |
| 264 | if (nft_rbtree_interval_start(new)) { | ||
| 265 | overlap = nft_rbtree_interval_start(rbe) && | ||
| 266 | nft_set_elem_active(&rbe->ext, | ||
| 267 | genmask); | ||
| 268 | } else { | ||
| 269 | overlap = nft_rbtree_interval_end(rbe) && | ||
| 270 | nft_set_elem_active(&rbe->ext, | ||
| 271 | genmask); | ||
| 272 | } | ||
| 273 | } else if (d > 0) { | ||
| 224 | p = &parent->rb_right; | 274 | p = &parent->rb_right; |
| 225 | else { | 275 | |
| 276 | if (nft_rbtree_interval_end(new)) { | ||
| 277 | overlap = nft_rbtree_interval_end(rbe) && | ||
| 278 | nft_set_elem_active(&rbe->ext, | ||
| 279 | genmask); | ||
| 280 | } else if (nft_rbtree_interval_end(rbe) && | ||
| 281 | nft_set_elem_active(&rbe->ext, genmask)) { | ||
| 282 | overlap = true; | ||
| 283 | } | ||
| 284 | } else { | ||
| 226 | if (nft_rbtree_interval_end(rbe) && | 285 | if (nft_rbtree_interval_end(rbe) && |
| 227 | !nft_rbtree_interval_end(new)) { | 286 | nft_rbtree_interval_start(new)) { |
| 228 | p = &parent->rb_left; | 287 | p = &parent->rb_left; |
| 229 | } else if (!nft_rbtree_interval_end(rbe) && | 288 | |
| 289 | if (nft_set_elem_active(&rbe->ext, genmask)) | ||
| 290 | overlap = false; | ||
| 291 | } else if (nft_rbtree_interval_start(rbe) && | ||
| 230 | nft_rbtree_interval_end(new)) { | 292 | nft_rbtree_interval_end(new)) { |
| 231 | p = &parent->rb_right; | 293 | p = &parent->rb_right; |
| 294 | |||
| 295 | if (nft_set_elem_active(&rbe->ext, genmask)) | ||
| 296 | overlap = false; | ||
| 232 | } else if (nft_set_elem_active(&rbe->ext, genmask)) { | 297 | } else if (nft_set_elem_active(&rbe->ext, genmask)) { |
| 233 | *ext = &rbe->ext; | 298 | *ext = &rbe->ext; |
| 234 | return -EEXIST; | 299 | return -EEXIST; |
| @@ -237,6 +302,10 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, · 2 unmodified lines | |||
| 237 | } | 302 | } |
| 238 | } | 303 | } |
| 239 | } | 304 | } |
| 305 | |||
| 306 | if (overlap) | ||
| 307 | return -ENOTEMPTY; | ||
| 308 | |||
| 240 | rb_link_node_rcu(&new->node, parent, p); | 309 | rb_link_node_rcu(&new->node, parent, p); |
| 241 | rb_insert_color(&new->node, &priv->root); | 310 | rb_insert_color(&new->node, &priv->root); |
| 242 | return 0; | 311 | return 0; |
| @@ -317,10 +386,10 @@ static void *nft_rbtree_deactivate(const struct net *net, · 74 unmodified lines | |||
| 317 | parent = parent->rb_right; | 386 | parent = parent->rb_right; |
| 318 | else { | 387 | else { |
| 319 | if (nft_rbtree_interval_end(rbe) && | 388 | if (nft_rbtree_interval_end(rbe) && |
| 320 | !nft_rbtree_interval_end(this)) { | 389 | nft_rbtree_interval_start(this)) { |
| 321 | parent = parent->rb_left; | 390 | parent = parent->rb_left; |
| 322 | continue; | 391 | continue; |
| 323 | } else if (!nft_rbtree_interval_end(rbe) && | 392 | } else if (nft_rbtree_interval_start(rbe) && |
| 324 | nft_rbtree_interval_end(this)) { | 393 | nft_rbtree_interval_end(this)) { |
| 325 | parent = parent->rb_right; | 394 | parent = parent->rb_right; |
| 326 | continue; | 395 | continue; |
| @@ -2392,19 +2392,14 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, · 2391 unmodified lines | |||
| 2392 | if (nlk_has_extack && extack && extack->_msg) | 2392 | if (nlk_has_extack && extack && extack->_msg) |
| 2393 | tlvlen += nla_total_size(strlen(extack->_msg) + 1); | 2393 | tlvlen += nla_total_size(strlen(extack->_msg) + 1); |
| 2394 | 2394 | ||
| 2395 | if (err) { | 2395 | if (err && !(nlk->flags & NETLINK_F_CAP_ACK)) |
| 2396 | if (!(nlk->flags & NETLINK_F_CAP_ACK)) | 2396 | payload += nlmsg_len(nlh); |
| 2397 | payload += nlmsg_len(nlh); | 2397 | else |
| 2398 | else | ||
| 2399 | flags |= NLM_F_CAPPED; | ||
| 2400 | if (nlk_has_extack && extack && extack->bad_attr) | ||
| 2401 | tlvlen += nla_total_size(sizeof(u32)); | ||
| 2402 | } else { | ||
| 2403 | flags |= NLM_F_CAPPED; | 2398 | flags |= NLM_F_CAPPED; |
| 2404 | 2399 | if (err && nlk_has_extack && extack && extack->bad_attr) | |
| 2405 | if (nlk_has_extack && extack && extack->cookie_len) | 2400 | tlvlen += nla_total_size(sizeof(u32)); |
| 2406 | tlvlen += nla_total_size(extack->cookie_len); | 2401 | if (nlk_has_extack && extack && extack->cookie_len) |
| 2407 | } | 2402 | tlvlen += nla_total_size(extack->cookie_len); |
| 2408 | 2403 | ||
| 2409 | if (tlvlen) | 2404 | if (tlvlen) |
| 2410 | flags |= NLM_F_ACK_TLVS; | 2405 | flags |= NLM_F_ACK_TLVS; |
| @@ -2427,20 +2422,16 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, · 16 unmodified lines | |||
| 2427 | WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, | 2422 | WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, |
| 2428 | extack->_msg)); | 2423 | extack->_msg)); |
| 2429 | } | 2424 | } |
| 2430 | if (err) { | 2425 | if (err && extack->bad_attr && |
| 2431 | if (extack->bad_attr && | 2426 | !WARN_ON((u8 *)extack->bad_attr < in_skb->data || |
| 2432 | !WARN_ON((u8 *)extack->bad_attr < in_skb->data || | 2427 | (u8 *)extack->bad_attr >= in_skb->data + |
| 2433 | (u8 *)extack->bad_attr >= in_skb->data + | 2428 | in_skb->len)) |
| 2434 | in_skb->len)) | 2429 | WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, |
| 2435 | WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, | 2430 | (u8 *)extack->bad_attr - |
| 2436 | (u8 *)extack->bad_attr - | 2431 | (u8 *)nlh)); |
| 2437 | (u8 *)nlh)); | 2432 | if (extack->cookie_len) |
| 2438 | } else { | 2433 | WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, |
| 2439 | if (extack->cookie_len) | 2434 | extack->cookie_len, extack->cookie)); |
| 2440 | WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, | ||
| 2441 | extack->cookie_len, | ||
| 2442 | extack->cookie)); | ||
| 2443 | } | ||
| 2444 | } | 2435 | } |
| 2445 | 2436 | ||
| 2446 | nlmsg_end(skb, rep); | 2437 | nlmsg_end(skb, rep); |
| @@ -2173,6 +2173,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, · 2172 unmodified lines | |||
| 2173 | struct timespec64 ts; | 2173 | struct timespec64 ts; |
| 2174 | __u32 ts_status; | 2174 | __u32 ts_status; |
| 2175 | bool is_drop_n_account = false; | 2175 | bool is_drop_n_account = false; |
| 2176 | unsigned int slot_id = 0; | ||
| 2176 | bool do_vnet = false; | 2177 | bool do_vnet = false; |
| 2177 | 2178 | ||
| 2178 | /* struct tpacket{2,3}_hdr is aligned to a multiple of TPACKET_ALIGNMENT. | 2179 | /* struct tpacket{2,3}_hdr is aligned to a multiple of TPACKET_ALIGNMENT. |
| @@ -2275,6 +2276,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, · 96 unmodified lines | |||
| 2275 | if (!h.raw) | 2276 | if (!h.raw) |
| 2276 | goto drop_n_account; | 2277 | goto drop_n_account; |
| 2277 | 2278 | ||
| 2279 | if (po->tp_version <= TPACKET_V2) { | ||
| 2280 | slot_id = po->rx_ring.head; | ||
| 2281 | if (test_bit(slot_id, po->rx_ring.rx_owner_map)) | ||
| 2282 | goto drop_n_account; | ||
| 2283 | __set_bit(slot_id, po->rx_ring.rx_owner_map); | ||
| 2284 | } | ||
| 2285 | |||
| 2278 | if (do_vnet && | 2286 | if (do_vnet && |
| 2279 | virtio_net_hdr_from_skb(skb, h.raw + macoff - | 2287 | virtio_net_hdr_from_skb(skb, h.raw + macoff - |
| 2280 | sizeof(struct virtio_net_hdr), | 2288 | sizeof(struct virtio_net_hdr), |
| @@ -2380,7 +2388,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, · 99 unmodified lines | |||
| 2380 | #endif | 2388 | #endif |
| 2381 | 2389 | ||
| 2382 | if (po->tp_version <= TPACKET_V2) { | 2390 | if (po->tp_version <= TPACKET_V2) { |
| 2391 | spin_lock(&sk->sk_receive_queue.lock); | ||
| 2383 | __packet_set_status(po, h.raw, status); | 2392 | __packet_set_status(po, h.raw, status); |
| 2393 | __clear_bit(slot_id, po->rx_ring.rx_owner_map); | ||
| 2394 | spin_unlock(&sk->sk_receive_queue.lock); | ||
| 2384 | sk->sk_data_ready(sk); | 2395 | sk->sk_data_ready(sk); |
| 2385 | } else { | 2396 | } else { |
| 2386 | prb_clear_blk_fill_status(&po->rx_ring); | 2397 | prb_clear_blk_fill_status(&po->rx_ring); |
| @@ -4277,6 +4288,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, · 1890 unmodified lines | |||
| 4277 | { | 4288 | { |
| 4278 | struct pgv *pg_vec = NULL; | 4289 | struct pgv *pg_vec = NULL; |
| 4279 | struct packet_sock *po = pkt_sk(sk); | 4290 | struct packet_sock *po = pkt_sk(sk); |
| 4291 | unsigned long *rx_owner_map = NULL; | ||
| 4280 | int was_running, order = 0; | 4292 | int was_running, order = 0; |
| 4281 | struct packet_ring_buffer *rb; | 4293 | struct packet_ring_buffer *rb; |
| 4282 | struct sk_buff_head *rb_queue; | 4294 | struct sk_buff_head *rb_queue; |
| @@ -4362,6 +4374,12 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, · 79 unmodified lines | |||
| 4362 | } | 4374 | } |
| 4363 | break; | 4375 | break; |
| 4364 | default: | 4376 | default: |
| 4377 | if (!tx_ring) { | ||
| 4378 | rx_owner_map = bitmap_alloc(req->tp_frame_nr, | ||
| 4379 | GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); | ||
| 4380 | if (!rx_owner_map) | ||
| 4381 | goto out_free_pg_vec; | ||
| 4382 | } | ||
| 4365 | break; | 4383 | break; |
| 4366 | } | 4384 | } |
| 4367 | } | 4385 | } |
| @@ -4391,6 +4409,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, · 23 unmodified lines | |||
| 4391 | err = 0; | 4409 | err = 0; |
| 4392 | spin_lock_bh(&rb_queue->lock); | 4410 | spin_lock_bh(&rb_queue->lock); |
| 4393 | swap(rb->pg_vec, pg_vec); | 4411 | swap(rb->pg_vec, pg_vec); |
| 4412 | if (po->tp_version <= TPACKET_V2) | ||
| 4413 | swap(rb->rx_owner_map, rx_owner_map); | ||
| 4394 | rb->frame_max = (req->tp_frame_nr - 1); | 4414 | rb->frame_max = (req->tp_frame_nr - 1); |
| 4395 | rb->head = 0; | 4415 | rb->head = 0; |
| 4396 | rb->frame_size = req->tp_frame_size; | 4416 | rb->frame_size = req->tp_frame_size; |
| @@ -4422,6 +4442,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, · 25 unmodified lines | |||
| 4422 | } | 4442 | } |
| 4423 | 4443 | ||
| 4424 | out_free_pg_vec: | 4444 | out_free_pg_vec: |
| 4445 | bitmap_free(rx_owner_map); | ||
| 4425 | if (pg_vec) | 4446 | if (pg_vec) |
| 4426 | free_pg_vec(pg_vec, order, req->tp_block_nr); | 4447 | free_pg_vec(pg_vec, order, req->tp_block_nr); |
| 4427 | out: | 4448 | out: |
| @@ -70,7 +70,10 @@ struct packet_ring_buffer { · 69 unmodified lines | |||
| 70 | 70 | ||
| 71 | unsigned int __percpu *pending_refcnt; | 71 | unsigned int __percpu *pending_refcnt; |
| 72 | 72 | ||
| 73 | struct tpacket_kbdq_core prb_bdqc; | 73 | union { |
| 74 | unsigned long *rx_owner_map; | ||
| 75 | struct tpacket_kbdq_core prb_bdqc; | ||
| 76 | }; | ||
| 74 | }; | 77 | }; |
| 75 | 78 | ||
| 76 | extern struct mutex fanout_mutex; | 79 | extern struct mutex fanout_mutex; |
| @@ -285,7 +285,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, · 284 unmodified lines | |||
| 285 | gfp_t gfp, | 285 | gfp_t gfp, |
| 286 | rxrpc_notify_rx_t notify_rx, | 286 | rxrpc_notify_rx_t notify_rx, |
| 287 | bool upgrade, | 287 | bool upgrade, |
| 288 | bool intr, | 288 | enum rxrpc_interruptibility interruptibility, |
| 289 | unsigned int debug_id) | 289 | unsigned int debug_id) |
| 290 | { | 290 | { |
| 291 | struct rxrpc_conn_parameters cp; | 291 | struct rxrpc_conn_parameters cp; |
| @@ -310,7 +310,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, · 18 unmodified lines | |||
| 310 | memset(&p, 0, sizeof(p)); | 310 | memset(&p, 0, sizeof(p)); |
| 311 | p.user_call_ID = user_call_ID; | 311 | p.user_call_ID = user_call_ID; |
| 312 | p.tx_total_len = tx_total_len; | 312 | p.tx_total_len = tx_total_len; |
| 313 | p.intr = intr; | 313 | p.interruptibility = interruptibility; |
| 314 | 314 | ||
| 315 | memset(&cp, 0, sizeof(cp)); | 315 | memset(&cp, 0, sizeof(cp)); |
| 316 | cp.local = rx->local; | 316 | cp.local = rx->local; |
| @@ -371,44 +371,17 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call); · 54 unmodified lines | |||
| 371 | * rxrpc_kernel_check_life - Check to see whether a call is still alive | 371 | * rxrpc_kernel_check_life - Check to see whether a call is still alive |
| 372 | * @sock: The socket the call is on | 372 | * @sock: The socket the call is on |
| 373 | * @call: The call to check | 373 | * @call: The call to check |
| 374 | * @_life: Where to store the life value | ||
| 375 | * | 374 | * |
| 376 | * Allow a kernel service to find out whether a call is still alive - ie. we're | 375 | * Allow a kernel service to find out whether a call is still alive - |
| 377 | * getting ACKs from the server. Passes back in *_life a number representing | 376 | * ie. whether it has completed. |
| 378 | * the life state which can be compared to that returned by a previous call and | ||
| 379 | * return true if the call is still alive. | ||
| 380 | * | ||
| 381 | * If the life state stalls, rxrpc_kernel_probe_life() should be called and | ||
| 382 | * then 2RTT waited. | ||
| 383 | */ | 377 | */ |
| 384 | bool rxrpc_kernel_check_life(const struct socket *sock, | 378 | bool rxrpc_kernel_check_life(const struct socket *sock, |
| 385 | const struct rxrpc_call *call, | 379 | const struct rxrpc_call *call) |
| 386 | u32 *_life) | ||
| 387 | { | 380 | { |
| 388 | *_life = call->acks_latest; | ||
| 389 | return call->state != RXRPC_CALL_COMPLETE; | 381 | return call->state != RXRPC_CALL_COMPLETE; |
| 390 | } | 382 | } |
| 391 | EXPORT_SYMBOL(rxrpc_kernel_check_life); | 383 | EXPORT_SYMBOL(rxrpc_kernel_check_life); |
| 392 | 384 | ||
| 393 | /** | ||
| 394 | * rxrpc_kernel_probe_life - Poke the peer to see if it's still alive | ||
| 395 | * @sock: The socket the call is on | ||
| 396 | * @call: The call to check | ||
| 397 | * | ||
| 398 | * In conjunction with rxrpc_kernel_check_life(), allow a kernel service to | ||
| 399 | * find out whether a call is still alive by pinging it. This should cause the | ||
| 400 | * life state to be bumped in about 2*RTT. | ||
| 401 | * | ||
| 402 | * The must be called in TASK_RUNNING state on pain of might_sleep() objecting. | ||
| 403 | */ | ||
| 404 | void rxrpc_kernel_probe_life(struct socket *sock, struct rxrpc_call *call) | ||
| 405 | { | ||
| 406 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, | ||
| 407 | rxrpc_propose_ack_ping_for_check_life); | ||
| 408 | rxrpc_send_ack_packet(call, true, NULL); | ||
| 409 | } | ||
| 410 | EXPORT_SYMBOL(rxrpc_kernel_probe_life); | ||
| 411 | |||
| 412 | /** | 385 | /** |
| 413 | * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. | 386 | * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. |
| 414 | * @sock: The socket the call is on | 387 | * @sock: The socket the call is on |
| @@ -489,7 +489,6 @@ enum rxrpc_call_flag { · 488 unmodified lines | |||
| 489 | RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */ | 489 | RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */ |
| 490 | RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */ | 490 | RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */ |
| 491 | RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */ | 491 | RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */ |
| 492 | RXRPC_CALL_IS_INTR, /* The call is interruptible */ | ||
| 493 | RXRPC_CALL_DISCONNECTED, /* The call has been disconnected */ | 492 | RXRPC_CALL_DISCONNECTED, /* The call has been disconnected */ |
| 494 | }; | 493 | }; |
| 495 | 494 | ||
| @@ -598,6 +597,7 @@ struct rxrpc_call { · 102 unmodified lines | |||
| 598 | atomic_t usage; | 597 | atomic_t usage; |
| 599 | u16 service_id; /* service ID */ | 598 | u16 service_id; /* service ID */ |
| 600 | u8 security_ix; /* Security type */ | 599 | u8 security_ix; /* Security type */ |
| 600 | enum rxrpc_interruptibility interruptibility; /* At what point call may be interrupted */ | ||
| 601 | u32 call_id; /* call ID on connection */ | 601 | u32 call_id; /* call ID on connection */ |
| 602 | u32 cid; /* connection ID plus channel index */ | 602 | u32 cid; /* connection ID plus channel index */ |
| 603 | int debug_id; /* debug ID for printks */ | 603 | int debug_id; /* debug ID for printks */ |
| @@ -675,7 +675,6 @@ struct rxrpc_call { · 71 unmodified lines | |||
| 675 | 675 | ||
| 676 | /* transmission-phase ACK management */ | 676 | /* transmission-phase ACK management */ |
| 677 | ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ | 677 | ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ |
| 678 | rxrpc_serial_t acks_latest; /* serial number of latest ACK received */ | ||
| 679 | rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ | 678 | rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ |
| 680 | rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */ | 679 | rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */ |
| 681 | rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */ | 680 | rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */ |
| @@ -721,7 +720,7 @@ struct rxrpc_call_params { · 39 unmodified lines | |||
| 721 | u32 normal; /* Max time since last call packet (msec) */ | 720 | u32 normal; /* Max time since last call packet (msec) */ |
| 722 | } timeouts; | 721 | } timeouts; |
| 723 | u8 nr_timeouts; /* Number of timeouts specified */ | 722 | u8 nr_timeouts; /* Number of timeouts specified */ |
| 724 | bool intr; /* The call is interruptible */ | 723 | enum rxrpc_interruptibility interruptibility; /* How is interruptible is the call? */ |
| 725 | }; | 724 | }; |
| 726 | 725 | ||
| 727 | struct rxrpc_send_params { | 726 | struct rxrpc_send_params { |
| @@ -237,8 +237,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, · 236 unmodified lines | |||
| 237 | return call; | 237 | return call; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | if (p->intr) | 240 | call->interruptibility = p->interruptibility; |
| 241 | __set_bit(RXRPC_CALL_IS_INTR, &call->flags); | ||
| 242 | call->tx_total_len = p->tx_total_len; | 241 | call->tx_total_len = p->tx_total_len; |
| 243 | trace_rxrpc_call(call->debug_id, rxrpc_call_new_client, | 242 | trace_rxrpc_call(call->debug_id, rxrpc_call_new_client, |
| 244 | atomic_read(&call->usage), | 243 | atomic_read(&call->usage), |
| @@ -655,13 +655,20 @@ static int rxrpc_wait_for_channel(struct rxrpc_call *call, gfp_t gfp) · 654 unmodified lines | |||
| 655 | 655 | ||
| 656 | add_wait_queue_exclusive(&call->waitq, &myself); | 656 | add_wait_queue_exclusive(&call->waitq, &myself); |
| 657 | for (;;) { | 657 | for (;;) { |
| 658 | if (test_bit(RXRPC_CALL_IS_INTR, &call->flags)) | 658 | switch (call->interruptibility) { |
| 659 | case RXRPC_INTERRUPTIBLE: | ||
| 660 | case RXRPC_PREINTERRUPTIBLE: | ||
| 659 | set_current_state(TASK_INTERRUPTIBLE); | 661 | set_current_state(TASK_INTERRUPTIBLE); |
| 660 | else | 662 | break; |
| 663 | case RXRPC_UNINTERRUPTIBLE: | ||
| 664 | default: | ||
| 661 | set_current_state(TASK_UNINTERRUPTIBLE); | 665 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 666 | break; | ||
| 667 | } | ||
| 662 | if (call->call_id) | 668 | if (call->call_id) |
| 663 | break; | 669 | break; |
| 664 | if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) && | 670 | if ((call->interruptibility == RXRPC_INTERRUPTIBLE || |
| 671 | call->interruptibility == RXRPC_PREINTERRUPTIBLE) && | ||
| 665 | signal_pending(current)) { | 672 | signal_pending(current)) { |
| 666 | ret = -ERESTARTSYS; | 673 | ret = -ERESTARTSYS; |
| 667 | break; | 674 | break; |
| @@ -882,7 +882,6 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) · 881 unmodified lines | |||
| 882 | before(prev_pkt, call->ackr_prev_seq)) | 882 | before(prev_pkt, call->ackr_prev_seq)) |
| 883 | goto out; | 883 | goto out; |
| 884 | call->acks_latest_ts = skb->tstamp; | 884 | call->acks_latest_ts = skb->tstamp; |
| 885 | call->acks_latest = sp->hdr.serial; | ||
| 886 | 885 | ||
| 887 | call->ackr_first_seq = first_soft_ack; | 886 | call->ackr_first_seq = first_soft_ack; |
| 888 | call->ackr_prev_seq = prev_pkt; | 887 | call->ackr_prev_seq = prev_pkt; |
| @@ -17,6 +17,21 @@ · 16 unmodified lines | |||
| 17 | #include <net/af_rxrpc.h> | 17 | #include <net/af_rxrpc.h> |
| 18 | #include "ar-internal.h" | 18 | #include "ar-internal.h" |
| 19 | 19 | ||
| 20 | /* | ||
| 21 | * Return true if there's sufficient Tx queue space. | ||
| 22 | */ | ||
| 23 | static bool rxrpc_check_tx_space(struct rxrpc_call *call, rxrpc_seq_t *_tx_win) | ||
| 24 | { | ||
| 25 | unsigned int win_size = | ||
| 26 | min_t(unsigned int, call->tx_winsize, | ||
| 27 | call->cong_cwnd + call->cong_extra); | ||
| 28 | rxrpc_seq_t tx_win = READ_ONCE(call->tx_hard_ack); | ||
| 29 | |||
| 30 | if (_tx_win) | ||
| 31 | *_tx_win = tx_win; | ||
| 32 | return call->tx_top - tx_win < win_size; | ||
| 33 | } | ||
| 34 | |||
| 20 | /* | 35 | /* |
| 21 | * Wait for space to appear in the Tx queue or a signal to occur. | 36 | * Wait for space to appear in the Tx queue or a signal to occur. |
| 22 | */ | 37 | */ |
| @@ -26,9 +41,7 @@ static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx, · 3 unmodified lines | |||
| 26 | { | 41 | { |
| 27 | for (;;) { | 42 | for (;;) { |
| 28 | set_current_state(TASK_INTERRUPTIBLE); | 43 | set_current_state(TASK_INTERRUPTIBLE); |
| 29 | if (call->tx_top - call->tx_hard_ack < | 44 | if (rxrpc_check_tx_space(call, NULL)) |
| 30 | min_t(unsigned int, call->tx_winsize, | ||
| 31 | call->cong_cwnd + call->cong_extra)) | ||
| 32 | return 0; | 45 | return 0; |
| 33 | 46 | ||
| 34 | if (call->state >= RXRPC_CALL_COMPLETE) | 47 | if (call->state >= RXRPC_CALL_COMPLETE) |
| @@ -49,7 +62,7 @@ static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx, · 14 unmodified lines | |||
| 49 | * Wait for space to appear in the Tx queue uninterruptibly, but with | 62 | * Wait for space to appear in the Tx queue uninterruptibly, but with |
| 50 | * a timeout of 2*RTT if no progress was made and a signal occurred. | 63 | * a timeout of 2*RTT if no progress was made and a signal occurred. |
| 51 | */ | 64 | */ |
| 52 | static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, | 65 | static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx, |
| 53 | struct rxrpc_call *call) | 66 | struct rxrpc_call *call) |
| 54 | { | 67 | { |
| 55 | rxrpc_seq_t tx_start, tx_win; | 68 | rxrpc_seq_t tx_start, tx_win; |
| @@ -58,8 +71,8 @@ static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, · 2 unmodified lines | |||
| 58 | 71 | ||
| 59 | rtt = READ_ONCE(call->peer->rtt); | 72 | rtt = READ_ONCE(call->peer->rtt); |
| 60 | rtt2 = nsecs_to_jiffies64(rtt) * 2; | 73 | rtt2 = nsecs_to_jiffies64(rtt) * 2; |
| 61 | if (rtt2 < 1) | 74 | if (rtt2 < 2) |
| 62 | rtt2 = 1; | 75 | rtt2 = 2; |
| 63 | 76 | ||
| 64 | timeout = rtt2; | 77 | timeout = rtt2; |
| 65 | tx_start = READ_ONCE(call->tx_hard_ack); | 78 | tx_start = READ_ONCE(call->tx_hard_ack); |
| @@ -68,16 +81,13 @@ static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, · 2 unmodified lines | |||
| 68 | set_current_state(TASK_UNINTERRUPTIBLE); | 81 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 69 | 82 | ||
| 70 | tx_win = READ_ONCE(call->tx_hard_ack); | 83 | tx_win = READ_ONCE(call->tx_hard_ack); |
| 71 | if (call->tx_top - tx_win < | 84 | if (rxrpc_check_tx_space(call, &tx_win)) |
| 72 | min_t(unsigned int, call->tx_winsize, | ||
| 73 | call->cong_cwnd + call->cong_extra)) | ||
| 74 | return 0; | 85 | return 0; |
| 75 | 86 | ||
| 76 | if (call->state >= RXRPC_CALL_COMPLETE) | 87 | if (call->state >= RXRPC_CALL_COMPLETE) |
| 77 | return call->error; | 88 | return call->error; |
| 78 | 89 | ||
| 79 | if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) && | 90 | if (timeout == 0 && |
| 80 | timeout == 0 && | ||
| 81 | tx_win == tx_start && signal_pending(current)) | 91 | tx_win == tx_start && signal_pending(current)) |
| 82 | return -EINTR; | 92 | return -EINTR; |
| 83 | 93 | ||
| @@ -91,6 +101,26 @@ static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, · 7 unmodified lines | |||
| 91 | } | 101 | } |
| 92 | } | 102 | } |
| 93 | 103 | ||
| 104 | /* | ||
| 105 | * Wait for space to appear in the Tx queue uninterruptibly. | ||
| 106 | */ | ||
| 107 | static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, | ||
| 108 | struct rxrpc_call *call, | ||
| 109 | long *timeo) | ||
| 110 | { | ||
| 111 | for (;;) { | ||
| 112 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 113 | if (rxrpc_check_tx_space(call, NULL)) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | if (call->state >= RXRPC_CALL_COMPLETE) | ||
| 117 | return call->error; | ||
| 118 | |||
| 119 | trace_rxrpc_transmit(call, rxrpc_transmit_wait); | ||
| 120 | *timeo = schedule_timeout(*timeo); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 94 | /* | 124 | /* |
| 95 | * wait for space to appear in the transmit/ACK window | 125 | * wait for space to appear in the transmit/ACK window |
| 96 | * - caller holds the socket locked | 126 | * - caller holds the socket locked |
| @@ -108,10 +138,19 @@ static int rxrpc_wait_for_tx_window(struct rxrpc_sock *rx, · 11 unmodified lines | |||
| 108 | 138 | ||
| 109 | add_wait_queue(&call->waitq, &myself); | 139 | add_wait_queue(&call->waitq, &myself); |
| 110 | 140 | ||
| 111 | if (waitall) | 141 | switch (call->interruptibility) { |
| 112 | ret = rxrpc_wait_for_tx_window_nonintr(rx, call); | 142 | case RXRPC_INTERRUPTIBLE: |
| 113 | else | 143 | if (waitall) |
| 114 | ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo); | 144 | ret = rxrpc_wait_for_tx_window_waitall(rx, call); |
| 145 | else | ||
| 146 | ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo); | ||
| 147 | break; | ||
| 148 | case RXRPC_PREINTERRUPTIBLE: | ||
| 149 | case RXRPC_UNINTERRUPTIBLE: | ||
| 150 | default: | ||
| 151 | ret = rxrpc_wait_for_tx_window_nonintr(rx, call, timeo); | ||
| 152 | break; | ||
| 153 | } | ||
| 115 | 154 | ||
| 116 | remove_wait_queue(&call->waitq, &myself); | 155 | remove_wait_queue(&call->waitq, &myself); |
| 117 | set_current_state(TASK_RUNNING); | 156 | set_current_state(TASK_RUNNING); |
| @@ -302,9 +341,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, · 184 unmodified lines | |||
| 302 | 341 | ||
| 303 | _debug("alloc"); | 342 | _debug("alloc"); |
| 304 | 343 | ||
| 305 | if (call->tx_top - call->tx_hard_ack >= | 344 | if (!rxrpc_check_tx_space(call, NULL)) { |
| 306 | min_t(unsigned int, call->tx_winsize, | ||
| 307 | call->cong_cwnd + call->cong_extra)) { | ||
| 308 | ret = -EAGAIN; | 345 | ret = -EAGAIN; |
| 309 | if (msg->msg_flags & MSG_DONTWAIT) | 346 | if (msg->msg_flags & MSG_DONTWAIT) |
| 310 | goto maybe_error; | 347 | goto maybe_error; |
| @@ -619,7 +656,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) · 308 unmodified lines | |||
| 619 | .call.tx_total_len = -1, | 656 | .call.tx_total_len = -1, |
| 620 | .call.user_call_ID = 0, | 657 | .call.user_call_ID = 0, |
| 621 | .call.nr_timeouts = 0, | 658 | .call.nr_timeouts = 0, |
| 622 | .call.intr = true, | 659 | .call.interruptibility = RXRPC_INTERRUPTIBLE, |
| 623 | .abort_code = 0, | 660 | .abort_code = 0, |
| 624 | .command = RXRPC_CMD_SEND_DATA, | 661 | .command = RXRPC_CMD_SEND_DATA, |
| 625 | .exclusive = false, | 662 | .exclusive = false, |
| @@ -1273,7 +1273,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, · 1272 unmodified lines | |||
| 1273 | if (goto_ch) | 1273 | if (goto_ch) |
| 1274 | tcf_chain_put_by_act(goto_ch); | 1274 | tcf_chain_put_by_act(goto_ch); |
| 1275 | if (params) | 1275 | if (params) |
| 1276 | kfree_rcu(params, rcu); | 1276 | call_rcu(¶ms->rcu, tcf_ct_params_free); |
| 1277 | if (res == ACT_P_CREATED) | 1277 | if (res == ACT_P_CREATED) |
| 1278 | tcf_idr_insert(tn, *a); | 1278 | tcf_idr_insert(tn, *a); |
| 1279 | 1279 | ||
| @@ -284,10 +284,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, · 283 unmodified lines | |||
| 284 | 284 | ||
| 285 | /* mirror is always swallowed */ | 285 | /* mirror is always swallowed */ |
| 286 | if (is_redirect) { | 286 | if (is_redirect) { |
| 287 | skb2->tc_redirected = 1; | 287 | skb_set_redirected(skb2, skb2->tc_at_ingress); |
| 288 | skb2->tc_from_ingress = skb2->tc_at_ingress; | 288 | |
| 289 | if (skb2->tc_from_ingress) | ||
| 290 | skb2->tstamp = 0; | ||
| 291 | /* let's the caller reinsert the packet, if possible */ | 289 | /* let's the caller reinsert the packet, if possible */ |
| 292 | if (use_reinsert) { | 290 | if (use_reinsert) { |
| 293 | res->ingress = want_ingress; | 291 | res->ingress = want_ingress; |
| @@ -534,8 +534,8 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, · 533 unmodified lines | |||
| 534 | fp = &b->ht[h]; | 534 | fp = &b->ht[h]; |
| 535 | for (pfp = rtnl_dereference(*fp); pfp; | 535 | for (pfp = rtnl_dereference(*fp); pfp; |
| 536 | fp = &pfp->next, pfp = rtnl_dereference(*fp)) { | 536 | fp = &pfp->next, pfp = rtnl_dereference(*fp)) { |
| 537 | if (pfp == f) { | 537 | if (pfp == fold) { |
| 538 | *fp = f->next; | 538 | rcu_assign_pointer(*fp, fold->next); |
| 539 | break; | 539 | break; |
| 540 | } | 540 | } |
| 541 | } | 541 | } |
| @@ -261,8 +261,10 @@ static void tcindex_partial_destroy_work(struct work_struct *work) · 260 unmodified lines | |||
| 261 | struct tcindex_data, | 261 | struct tcindex_data, |
| 262 | rwork); | 262 | rwork); |
| 263 | 263 | ||
| 264 | rtnl_lock(); | ||
| 264 | kfree(p->perfect); | 265 | kfree(p->perfect); |
| 265 | kfree(p); | 266 | kfree(p); |
| 267 | rtnl_unlock(); | ||
| 266 | } | 268 | } |
| 267 | 269 | ||
| 268 | static void tcindex_free_perfect_hash(struct tcindex_data *cp) | 270 | static void tcindex_free_perfect_hash(struct tcindex_data *cp) |
| @@ -357,6 +359,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, · 88 unmodified lines | |||
| 357 | 359 | ||
| 358 | if (tcindex_alloc_perfect_hash(net, cp) < 0) | 360 | if (tcindex_alloc_perfect_hash(net, cp) < 0) |
| 359 | goto errout; | 361 | goto errout; |
| 362 | cp->alloc_hash = cp->hash; | ||
| 360 | for (i = 0; i < min(cp->hash, p->hash); i++) | 363 | for (i = 0; i < min(cp->hash, p->hash); i++) |
| 361 | cp->perfect[i].res = p->perfect[i].res; | 364 | cp->perfect[i].res = p->perfect[i].res; |
| 362 | balloc = 1; | 365 | balloc = 1; |
| @@ -181,6 +181,11 @@ static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch) · 180 unmodified lines | |||
| 181 | s64 credits; | 181 | s64 credits; |
| 182 | int len; | 182 | int len; |
| 183 | 183 | ||
| 184 | /* The previous packet is still being sent */ | ||
| 185 | if (now < q->last) { | ||
| 186 | qdisc_watchdog_schedule_ns(&q->watchdog, q->last); | ||
| 187 | return NULL; | ||
| 188 | } | ||
| 184 | if (q->credits < 0) { | 189 | if (q->credits < 0) { |
| 185 | credits = timediff_to_credits(now - q->last, q->idleslope); | 190 | credits = timediff_to_credits(now - q->last, q->idleslope); |
| 186 | 191 | ||
| @@ -212,7 +217,12 @@ static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch) · 25 unmodified lines | |||
| 212 | credits += q->credits; | 217 | credits += q->credits; |
| 213 | 218 | ||
| 214 | q->credits = max_t(s64, credits, q->locredit); | 219 | q->credits = max_t(s64, credits, q->locredit); |
| 215 | q->last = now; | 220 | /* Estimate of the transmission of the last byte of the packet in ns */ |
| 221 | if (unlikely(atomic64_read(&q->port_rate) == 0)) | ||
| 222 | q->last = now; | ||
| 223 | else | ||
| 224 | q->last = now + div64_s64(len * NSEC_PER_SEC, | ||
| 225 | atomic64_read(&q->port_rate)); | ||
| 216 | 226 | ||
| 217 | return skb; | 227 | return skb; |
| 218 | } | 228 | } |
| @@ -1707,7 +1707,8 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) · 1706 unmodified lines | |||
| 1707 | 1707 | ||
| 1708 | int __sys_accept4_file(struct file *file, unsigned file_flags, | 1708 | int __sys_accept4_file(struct file *file, unsigned file_flags, |
| 1709 | struct sockaddr __user *upeer_sockaddr, | 1709 | struct sockaddr __user *upeer_sockaddr, |
| 1710 | int __user *upeer_addrlen, int flags) | 1710 | int __user *upeer_addrlen, int flags, |
| 1711 | unsigned long nofile) | ||
| 1711 | { | 1712 | { |
| 1712 | struct socket *sock, *newsock; | 1713 | struct socket *sock, *newsock; |
| 1713 | struct file *newfile; | 1714 | struct file *newfile; |
| @@ -1738,7 +1739,7 @@ int __sys_accept4_file(struct file *file, unsigned file_flags, · 24 unmodified lines | |||
| 1738 | */ | 1739 | */ |
| 1739 | __module_get(newsock->ops->owner); | 1740 | __module_get(newsock->ops->owner); |
| 1740 | 1741 | ||
| 1741 | newfd = get_unused_fd_flags(flags); | 1742 | newfd = __get_unused_fd_flags(flags, nofile); |
| 1742 | if (unlikely(newfd < 0)) { | 1743 | if (unlikely(newfd < 0)) { |
| 1743 | err = newfd; | 1744 | err = newfd; |
| 1744 | sock_release(newsock); | 1745 | sock_release(newsock); |
| @@ -1807,7 +1808,8 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, · 62 unmodified lines | |||
| 1807 | f = fdget(fd); | 1808 | f = fdget(fd); |
| 1808 | if (f.file) { | 1809 | if (f.file) { |
| 1809 | ret = __sys_accept4_file(f.file, 0, upeer_sockaddr, | 1810 | ret = __sys_accept4_file(f.file, 0, upeer_sockaddr, |
| 1810 | upeer_addrlen, flags); | 1811 | upeer_addrlen, flags, |
| 1812 | rlimit(RLIMIT_NOFILE)); | ||
| 1811 | if (f.flags) | 1813 | if (f.flags) |
| 1812 | fput(f.file); | 1814 | fput(f.file); |
| 1813 | } | 1815 | } |
| @@ -44,3 +44,10 @@ $(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supporte · 43 unmodified lines | |||
| 44 | 44 | ||
| 45 | # gcc version including patch level | 45 | # gcc version including patch level |
| 46 | gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) | 46 | gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) |
| 47 | |||
| 48 | # machine bit flags | ||
| 49 | # $(m32-flag): -m32 if the compiler supports it, or an empty string otherwise. | ||
| 50 | # $(m64-flag): -m64 if the compiler supports it, or an empty string otherwise. | ||
| 51 | cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$(1)) | ||
| 52 | m32-flag := $(cc-option-bit,-m32) | ||
| 53 | m64-flag := $(cc-option-bit,-m64) | ||
| @@ -48,6 +48,7 @@ KBUILD_CFLAGS += -Wno-initializer-overrides · 47 unmodified lines | |||
| 48 | KBUILD_CFLAGS += -Wno-format | 48 | KBUILD_CFLAGS += -Wno-format |
| 49 | KBUILD_CFLAGS += -Wno-sign-compare | 49 | KBUILD_CFLAGS += -Wno-sign-compare |
| 50 | KBUILD_CFLAGS += -Wno-format-zero-length | 50 | KBUILD_CFLAGS += -Wno-format-zero-length |
| 51 | KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) | ||
| 51 | endif | 52 | endif |
| 52 | 53 | ||
| 53 | endif | 54 | endif |
| @@ -94,7 +94,7 @@ if (defined $opt{'o'}) { · 93 unmodified lines | |||
| 94 | # | 94 | # |
| 95 | while ( <$module_symvers> ) { | 95 | while ( <$module_symvers> ) { |
| 96 | chomp; | 96 | chomp; |
| 97 | my (undef, $symbol, $namespace, $module, $gpl) = split('\t'); | 97 | my (undef, $symbol, $module, $gpl, $namespace) = split('\t'); |
| 98 | $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; | 98 | $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; |
| 99 | } | 99 | } |
| 100 | close($module_symvers); | 100 | close($module_symvers); |
| @@ -195,13 +195,13 @@ static struct sym_entry *read_symbol(FILE *in) · 194 unmodified lines | |||
| 195 | return NULL; | 195 | return NULL; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | if (is_ignored_symbol(name, type)) | ||
| 199 | return NULL; | ||
| 200 | |||
| 201 | /* Ignore most absolute/undefined (?) symbols. */ | ||
| 202 | if (strcmp(name, "_text") == 0) | 198 | if (strcmp(name, "_text") == 0) |
| 203 | _text = addr; | 199 | _text = addr; |
| 204 | 200 | ||
| 201 | /* Ignore most absolute/undefined (?) symbols. */ | ||
| 202 | if (is_ignored_symbol(name, type)) | ||
| 203 | return NULL; | ||
| 204 | |||
| 205 | check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges)); | 205 | check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges)); |
| 206 | check_symbol_range(name, addr, &percpu_range, 1); | 206 | check_symbol_range(name, addr, &percpu_range, 1); |
| 207 | 207 | ||
| @@ -308,7 +308,8 @@ static const char *sec_name(struct elf_info *elf, int secindex) · 307 unmodified lines | |||
| 308 | 308 | ||
| 309 | static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) | 309 | static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) |
| 310 | { | 310 | { |
| 311 | Elf_Shdr *sechdr = &info->sechdrs[sym->st_shndx]; | 311 | unsigned int secindex = get_secindex(info, sym); |
| 312 | Elf_Shdr *sechdr = &info->sechdrs[secindex]; | ||
| 312 | unsigned long offset; | 313 | unsigned long offset; |
| 313 | 314 | ||
| 314 | offset = sym->st_value; | 315 | offset = sym->st_value; |
| @@ -2427,7 +2428,7 @@ static void write_if_changed(struct buffer *b, const char *fname) · 2112 unmodified lines | |||
| 2427 | } | 2428 | } |
| 2428 | 2429 | ||
| 2429 | /* parse Module.symvers file. line format: | 2430 | /* parse Module.symvers file. line format: |
| 2430 | * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something] | 2431 | * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace |
| 2431 | **/ | 2432 | **/ |
| 2432 | static void read_dump(const char *fname, unsigned int kernel) | 2433 | static void read_dump(const char *fname, unsigned int kernel) |
| 2433 | { | 2434 | { |
| @@ -2440,7 +2441,7 @@ static void read_dump(const char *fname, unsigned int kernel) · 6 unmodified lines | |||
| 2440 | return; | 2441 | return; |
| 2441 | 2442 | ||
| 2442 | while ((line = get_next_line(&pos, file, size))) { | 2443 | while ((line = get_next_line(&pos, file, size))) { |
| 2443 | char *symname, *namespace, *modname, *d, *export, *end; | 2444 | char *symname, *namespace, *modname, *d, *export; |
| 2444 | unsigned int crc; | 2445 | unsigned int crc; |
| 2445 | struct module *mod; | 2446 | struct module *mod; |
| 2446 | struct symbol *s; | 2447 | struct symbol *s; |
| @@ -2448,16 +2449,16 @@ static void read_dump(const char *fname, unsigned int kernel) · 1 unmodified line | |||
| 2448 | if (!(symname = strchr(line, '\t'))) | 2449 | if (!(symname = strchr(line, '\t'))) |
| 2449 | goto fail; | 2450 | goto fail; |
| 2450 | *symname++ = '\0'; | 2451 | *symname++ = '\0'; |
| 2451 | if (!(namespace = strchr(symname, '\t'))) | 2452 | if (!(modname = strchr(symname, '\t'))) |
| 2452 | goto fail; | ||
| 2453 | *namespace++ = '\0'; | ||
| 2454 | if (!(modname = strchr(namespace, '\t'))) | ||
| 2455 | goto fail; | 2453 | goto fail; |
| 2456 | *modname++ = '\0'; | 2454 | *modname++ = '\0'; |
| 2457 | if ((export = strchr(modname, '\t')) != NULL) | 2455 | if (!(export = strchr(modname, '\t'))) |
| 2458 | *export++ = '\0'; | 2456 | goto fail; |
| 2459 | if (export && ((end = strchr(export, '\t')) != NULL)) | 2457 | *export++ = '\0'; |
| 2460 | *end = '\0'; | 2458 | if (!(namespace = strchr(export, '\t'))) |
| 2459 | goto fail; | ||
| 2460 | *namespace++ = '\0'; | ||
| 2461 | |||
| 2461 | crc = strtoul(line, &d, 16); | 2462 | crc = strtoul(line, &d, 16); |
| 2462 | if (*symname == '\0' || *modname == '\0' || *d != '\0') | 2463 | if (*symname == '\0' || *modname == '\0' || *d != '\0') |
| 2463 | goto fail; | 2464 | goto fail; |
| @@ -2508,9 +2509,9 @@ static void write_dump(const char *fname) · 44 unmodified lines | |||
| 2508 | namespace = symbol->namespace; | 2509 | namespace = symbol->namespace; |
| 2509 | buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", | 2510 | buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", |
| 2510 | symbol->crc, symbol->name, | 2511 | symbol->crc, symbol->name, |
| 2511 | namespace ? namespace : "", | ||
| 2512 | symbol->module->name, | 2512 | symbol->module->name, |
| 2513 | export_str(symbol->export)); | 2513 | export_str(symbol->export), |
| 2514 | namespace ? namespace : ""); | ||
| 2514 | } | 2515 | } |
| 2515 | symbol = symbol->next; | 2516 | symbol = symbol->next; |
| 2516 | } | 2517 | } |
| @@ -111,7 +111,7 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames) · 110 unmodified lines | |||
| 111 | while (plugin->next) { | 111 | while (plugin->next) { |
| 112 | if (plugin->dst_frames) | 112 | if (plugin->dst_frames) |
| 113 | frames = plugin->dst_frames(plugin, frames); | 113 | frames = plugin->dst_frames(plugin, frames); |
| 114 | if (snd_BUG_ON((snd_pcm_sframes_t)frames <= 0)) | 114 | if ((snd_pcm_sframes_t)frames <= 0) |
| 115 | return -ENXIO; | 115 | return -ENXIO; |
| 116 | plugin = plugin->next; | 116 | plugin = plugin->next; |
| 117 | err = snd_pcm_plugin_alloc(plugin, frames); | 117 | err = snd_pcm_plugin_alloc(plugin, frames); |
| @@ -123,7 +123,7 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames) · 5 unmodified lines | |||
| 123 | while (plugin->prev) { | 123 | while (plugin->prev) { |
| 124 | if (plugin->src_frames) | 124 | if (plugin->src_frames) |
| 125 | frames = plugin->src_frames(plugin, frames); | 125 | frames = plugin->src_frames(plugin, frames); |
| 126 | if (snd_BUG_ON((snd_pcm_sframes_t)frames <= 0)) | 126 | if ((snd_pcm_sframes_t)frames <= 0) |
| 127 | return -ENXIO; | 127 | return -ENXIO; |
| 128 | plugin = plugin->prev; | 128 | plugin = plugin->prev; |
| 129 | err = snd_pcm_plugin_alloc(plugin, frames); | 129 | err = snd_pcm_plugin_alloc(plugin, frames); |
| @@ -209,6 +209,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p · 79 unmodified lines | |||
| 209 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 209 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 210 | plugin = snd_pcm_plug_last(plug); | 210 | plugin = snd_pcm_plug_last(plug); |
| 211 | while (plugin && drv_frames > 0) { | 211 | while (plugin && drv_frames > 0) { |
| 212 | if (drv_frames > plugin->buf_frames) | ||
| 213 | drv_frames = plugin->buf_frames; | ||
| 212 | plugin_prev = plugin->prev; | 214 | plugin_prev = plugin->prev; |
| 213 | if (plugin->src_frames) | 215 | if (plugin->src_frames) |
| 214 | drv_frames = plugin->src_frames(plugin, drv_frames); | 216 | drv_frames = plugin->src_frames(plugin, drv_frames); |
| @@ -220,6 +222,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p · 5 unmodified lines | |||
| 220 | plugin_next = plugin->next; | 222 | plugin_next = plugin->next; |
| 221 | if (plugin->dst_frames) | 223 | if (plugin->dst_frames) |
| 222 | drv_frames = plugin->dst_frames(plugin, drv_frames); | 224 | drv_frames = plugin->dst_frames(plugin, drv_frames); |
| 225 | if (drv_frames > plugin->buf_frames) | ||
| 226 | drv_frames = plugin->buf_frames; | ||
| 223 | plugin = plugin_next; | 227 | plugin = plugin_next; |
| 224 | } | 228 | } |
| 225 | } else | 229 | } else |
| @@ -248,11 +252,15 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc · 22 unmodified lines | |||
| 248 | if (frames < 0) | 252 | if (frames < 0) |
| 249 | return frames; | 253 | return frames; |
| 250 | } | 254 | } |
| 255 | if (frames > plugin->buf_frames) | ||
| 256 | frames = plugin->buf_frames; | ||
| 251 | plugin = plugin_next; | 257 | plugin = plugin_next; |
| 252 | } | 258 | } |
| 253 | } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { | 259 | } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { |
| 254 | plugin = snd_pcm_plug_last(plug); | 260 | plugin = snd_pcm_plug_last(plug); |
| 255 | while (plugin) { | 261 | while (plugin) { |
| 262 | if (frames > plugin->buf_frames) | ||
| 263 | frames = plugin->buf_frames; | ||
| 256 | plugin_prev = plugin->prev; | 264 | plugin_prev = plugin->prev; |
| 257 | if (plugin->src_frames) { | 265 | if (plugin->src_frames) { |
| 258 | frames = plugin->src_frames(plugin, frames); | 266 | frames = plugin->src_frames(plugin, frames); |
| @@ -602,6 +602,7 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq · 601 unmodified lines | |||
| 602 | len = snd_seq_oss_timer_start(dp->timer); | 602 | len = snd_seq_oss_timer_start(dp->timer); |
| 603 | if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { | 603 | if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { |
| 604 | snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); | 604 | snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); |
| 605 | snd_midi_event_reset_decode(mdev->coder); | ||
| 605 | } else { | 606 | } else { |
| 606 | len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); | 607 | len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); |
| 607 | if (len > 0) | 608 | if (len > 0) |
| @@ -81,6 +81,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, · 80 unmodified lines | |||
| 81 | if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) | 81 | if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) |
| 82 | continue; | 82 | continue; |
| 83 | snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream); | 83 | snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream); |
| 84 | snd_midi_event_reset_decode(vmidi->parser); | ||
| 84 | } else { | 85 | } else { |
| 85 | len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); | 86 | len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); |
| 86 | if (len > 0) | 87 | if (len > 0) |
| @@ -8051,6 +8051,8 @@ static int patch_alc269(struct hda_codec *codec) · 8050 unmodified lines | |||
| 8051 | spec->gen.mixer_nid = 0; | 8051 | spec->gen.mixer_nid = 0; |
| 8052 | break; | 8052 | break; |
| 8053 | case 0x10ec0225: | 8053 | case 0x10ec0225: |
| 8054 | codec->power_save_node = 1; | ||
| 8055 | /* fall through */ | ||
| 8054 | case 0x10ec0295: | 8056 | case 0x10ec0295: |
| 8055 | case 0x10ec0299: | 8057 | case 0x10ec0299: |
| 8056 | spec->codec_variant = ALC269_TYPE_ALC225; | 8058 | spec->codec_variant = ALC269_TYPE_ALC225; |
| @@ -8610,6 +8612,8 @@ enum { · 553 unmodified lines | |||
| 8610 | ALC669_FIXUP_ACER_ASPIRE_ETHOS, | 8612 | ALC669_FIXUP_ACER_ASPIRE_ETHOS, |
| 8611 | ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET, | 8613 | ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET, |
| 8612 | ALC671_FIXUP_HP_HEADSET_MIC2, | 8614 | ALC671_FIXUP_HP_HEADSET_MIC2, |
| 8615 | ALC662_FIXUP_ACER_X2660G_HEADSET_MODE, | ||
| 8616 | ALC662_FIXUP_ACER_NITRO_HEADSET_MODE, | ||
| 8613 | }; | 8617 | }; |
| 8614 | 8618 | ||
| 8615 | static const struct hda_fixup alc662_fixups[] = { | 8619 | static const struct hda_fixup alc662_fixups[] = { |
| @@ -8955,6 +8959,25 @@ static const struct hda_fixup alc662_fixups[] = { · 339 unmodified lines | |||
| 8955 | .type = HDA_FIXUP_FUNC, | 8959 | .type = HDA_FIXUP_FUNC, |
| 8956 | .v.func = alc671_fixup_hp_headset_mic2, | 8960 | .v.func = alc671_fixup_hp_headset_mic2, |
| 8957 | }, | 8961 | }, |
| 8962 | [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = { | ||
| 8963 | .type = HDA_FIXUP_PINS, | ||
| 8964 | .v.pins = (const struct hda_pintbl[]) { | ||
| 8965 | { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */ | ||
| 8966 | { } | ||
| 8967 | }, | ||
| 8968 | .chained = true, | ||
| 8969 | .chain_id = ALC662_FIXUP_USI_FUNC | ||
| 8970 | }, | ||
| 8971 | [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = { | ||
| 8972 | .type = HDA_FIXUP_PINS, | ||
| 8973 | .v.pins = (const struct hda_pintbl[]) { | ||
| 8974 | { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */ | ||
| 8975 | { 0x1b, 0x0221144f }, | ||
| 8976 | { } | ||
| 8977 | }, | ||
| 8978 | .chained = true, | ||
| 8979 | .chain_id = ALC662_FIXUP_USI_FUNC | ||
| 8980 | }, | ||
| 8958 | }; | 8981 | }; |
| 8959 | 8982 | ||
| 8960 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 8983 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
| @@ -8966,6 +8989,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { · 5 unmodified lines | |||
| 8966 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | 8989 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
| 8967 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), | 8990 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), |
| 8968 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 8991 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
| 8992 | SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE), | ||
| 8993 | SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE), | ||
| 8969 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 8994 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
| 8970 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 8995 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
| 8971 | SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13), | 8996 | SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13), |
| @@ -305,7 +305,7 @@ static void line6_data_received(struct urb *urb) · 304 unmodified lines | |||
| 305 | line6_midibuf_read(mb, line6->buffer_message, | 305 | line6_midibuf_read(mb, line6->buffer_message, |
| 306 | LINE6_MIDI_MESSAGE_MAXLEN); | 306 | LINE6_MIDI_MESSAGE_MAXLEN); |
| 307 | 307 | ||
| 308 | if (done == 0) | 308 | if (done <= 0) |
| 309 | break; | 309 | break; |
| 310 | 310 | ||
| 311 | line6->message_length = done; | 311 | line6->message_length = done; |
| @@ -159,7 +159,7 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data, · 158 unmodified lines | |||
| 159 | int midi_length_prev = | 159 | int midi_length_prev = |
| 160 | midibuf_message_length(this->command_prev); | 160 | midibuf_message_length(this->command_prev); |
| 161 | 161 | ||
| 162 | if (midi_length_prev > 0) { | 162 | if (midi_length_prev > 1) { |
| 163 | midi_length = midi_length_prev - 1; | 163 | midi_length = midi_length_prev - 1; |
| 164 | repeat = 1; | 164 | repeat = 1; |
| 165 | } else | 165 | } else |
| @@ -1,18 +1,18 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | #if defined(__i386__) || defined(__x86_64__) | 2 | #if defined(__i386__) || defined(__x86_64__) |
| 3 | #include "../../arch/x86/include/uapi/asm/errno.h" | 3 | #include "../../../arch/x86/include/uapi/asm/errno.h" |
| 4 | #elif defined(__powerpc__) | 4 | #elif defined(__powerpc__) |
| 5 | #include "../../arch/powerpc/include/uapi/asm/errno.h" | 5 | #include "../../../arch/powerpc/include/uapi/asm/errno.h" |
| 6 | #elif defined(__sparc__) | 6 | #elif defined(__sparc__) |
| 7 | #include "../../arch/sparc/include/uapi/asm/errno.h" | 7 | #include "../../../arch/sparc/include/uapi/asm/errno.h" |
| 8 | #elif defined(__alpha__) | 8 | #elif defined(__alpha__) |
| 9 | #include "../../arch/alpha/include/uapi/asm/errno.h" | 9 | #include "../../../arch/alpha/include/uapi/asm/errno.h" |
| 10 | #elif defined(__mips__) | 10 | #elif defined(__mips__) |
| 11 | #include "../../arch/mips/include/uapi/asm/errno.h" | 11 | #include "../../../arch/mips/include/uapi/asm/errno.h" |
| 12 | #elif defined(__ia64__) | 12 | #elif defined(__ia64__) |
| 13 | #include "../../arch/ia64/include/uapi/asm/errno.h" | 13 | #include "../../../arch/ia64/include/uapi/asm/errno.h" |
| 14 | #elif defined(__xtensa__) | 14 | #elif defined(__xtensa__) |
| 15 | #include "../../arch/xtensa/include/uapi/asm/errno.h" | 15 | #include "../../../arch/xtensa/include/uapi/asm/errno.h" |
| 16 | #else | 16 | #else |
| 17 | #include <asm-generic/errno.h> | 17 | #include <asm-generic/errno.h> |
| 18 | #endif | 18 | #endif |
| @@ -74,6 +74,8 @@ enum { · 73 unmodified lines | |||
| 74 | #define IPPROTO_UDPLITE IPPROTO_UDPLITE | 74 | #define IPPROTO_UDPLITE IPPROTO_UDPLITE |
| 75 | IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */ | 75 | IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */ |
| 76 | #define IPPROTO_MPLS IPPROTO_MPLS | 76 | #define IPPROTO_MPLS IPPROTO_MPLS |
| 77 | IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation */ | ||
| 78 | #define IPPROTO_ETHERNET IPPROTO_ETHERNET | ||
| 77 | IPPROTO_RAW = 255, /* Raw IP packets */ | 79 | IPPROTO_RAW = 255, /* Raw IP packets */ |
| 78 | #define IPPROTO_RAW IPPROTO_RAW | 80 | #define IPPROTO_RAW IPPROTO_RAW |
| 79 | IPPROTO_MPTCP = 262, /* Multipath TCP connection */ | 81 | IPPROTO_MPTCP = 262, /* Multipath TCP connection */ |
| @@ -35,7 +35,7 @@ endif · 34 unmodified lines | |||
| 35 | # Only pass canonical directory names as the output directory: | 35 | # Only pass canonical directory names as the output directory: |
| 36 | # | 36 | # |
| 37 | ifneq ($(O),) | 37 | ifneq ($(O),) |
| 38 | FULL_O := $(shell readlink -f $(O) || echo $(O)) | 38 | FULL_O := $(shell cd $(PWD); readlink -f $(O) || echo $(O)) |
| 39 | endif | 39 | endif |
| 40 | 40 | ||
| 41 | # | 41 | # |
| @@ -11,17 +11,17 @@ · 10 unmodified lines | |||
| 11 | #include <linux/zalloc.h> | 11 | #include <linux/zalloc.h> |
| 12 | #include <time.h> | 12 | #include <time.h> |
| 13 | 13 | ||
| 14 | #include "../../util/cpumap.h" | 14 | #include "../../../util/cpumap.h" |
| 15 | #include "../../util/event.h" | 15 | #include "../../../util/event.h" |
| 16 | #include "../../util/evsel.h" | 16 | #include "../../../util/evsel.h" |
| 17 | #include "../../util/evlist.h" | 17 | #include "../../../util/evlist.h" |
| 18 | #include "../../util/session.h" | 18 | #include "../../../util/session.h" |
| 19 | #include <internal/lib.h> // page_size | 19 | #include <internal/lib.h> // page_size |
| 20 | #include "../../util/pmu.h" | 20 | #include "../../../util/pmu.h" |
| 21 | #include "../../util/debug.h" | 21 | #include "../../../util/debug.h" |
| 22 | #include "../../util/auxtrace.h" | 22 | #include "../../../util/auxtrace.h" |
| 23 | #include "../../util/record.h" | 23 | #include "../../../util/record.h" |
| 24 | #include "../../util/arm-spe.h" | 24 | #include "../../../util/arm-spe.h" |
| 25 | 25 | ||
| 26 | #define KiB(x) ((x) * 1024) | 26 | #define KiB(x) ((x) * 1024) |
| 27 | #define MiB(x) ((x) * 1024 * 1024) | 27 | #define MiB(x) ((x) * 1024 * 1024) |
| @@ -1,5 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include "../../util/perf_regs.h" | 2 | #include "../../../util/perf_regs.h" |
| 3 | 3 | ||
| 4 | const struct sample_reg sample_reg_masks[] = { | 4 | const struct sample_reg sample_reg_masks[] = { |
| 5 | SMPL_REG_END | 5 | SMPL_REG_END |
| @@ -4,8 +4,8 @@ · 3 unmodified lines | |||
| 4 | #include <regex.h> | 4 | #include <regex.h> |
| 5 | #include <linux/zalloc.h> | 5 | #include <linux/zalloc.h> |
| 6 | 6 | ||
| 7 | #include "../../util/perf_regs.h" | 7 | #include "../../../util/perf_regs.h" |
| 8 | #include "../../util/debug.h" | 8 | #include "../../../util/debug.h" |
| 9 | 9 | ||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | 11 | ||
| @@ -7,13 +7,13 @@ · 6 unmodified lines | |||
| 7 | #include <errno.h> | 7 | #include <errno.h> |
| 8 | #include <stdbool.h> | 8 | #include <stdbool.h> |
| 9 | 9 | ||
| 10 | #include "../../util/header.h" | 10 | #include "../../../util/header.h" |
| 11 | #include "../../util/debug.h" | 11 | #include "../../../util/debug.h" |
| 12 | #include "../../util/pmu.h" | 12 | #include "../../../util/pmu.h" |
| 13 | #include "../../util/auxtrace.h" | 13 | #include "../../../util/auxtrace.h" |
| 14 | #include "../../util/intel-pt.h" | 14 | #include "../../../util/intel-pt.h" |
| 15 | #include "../../util/intel-bts.h" | 15 | #include "../../../util/intel-bts.h" |
| 16 | #include "../../util/evlist.h" | 16 | #include "../../../util/evlist.h" |
| 17 | 17 | ||
| 18 | static | 18 | static |
| 19 | struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist, | 19 | struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist, |
| @@ -3,12 +3,12 @@ · 2 unmodified lines | |||
| 3 | #include <linux/string.h> | 3 | #include <linux/string.h> |
| 4 | #include <linux/zalloc.h> | 4 | #include <linux/zalloc.h> |
| 5 | 5 | ||
| 6 | #include "../../util/event.h" | 6 | #include "../../../util/event.h" |
| 7 | #include "../../util/synthetic-events.h" | 7 | #include "../../../util/synthetic-events.h" |
| 8 | #include "../../util/machine.h" | 8 | #include "../../../util/machine.h" |
| 9 | #include "../../util/tool.h" | 9 | #include "../../../util/tool.h" |
| 10 | #include "../../util/map.h" | 10 | #include "../../../util/map.h" |
| 11 | #include "../../util/debug.h" | 11 | #include "../../../util/debug.h" |
| 12 | 12 | ||
| 13 | #if defined(__x86_64__) | 13 | #if defined(__x86_64__) |
| 14 | 14 | ||
| @@ -7,8 +7,8 @@ · 6 unmodified lines | |||
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | #include <regex.h> | 8 | #include <regex.h> |
| 9 | 9 | ||
| 10 | #include "../../util/debug.h" | 10 | #include "../../../util/debug.h" |
| 11 | #include "../../util/header.h" | 11 | #include "../../../util/header.h" |
| 12 | 12 | ||
| 13 | static inline void | 13 | static inline void |
| 14 | cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, | 14 | cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, |
| @@ -11,18 +11,18 @@ · 10 unmodified lines | |||
| 11 | #include <linux/log2.h> | 11 | #include <linux/log2.h> |
| 12 | #include <linux/zalloc.h> | 12 | #include <linux/zalloc.h> |
| 13 | 13 | ||
| 14 | #include "../../util/cpumap.h" | 14 | #include "../../../util/cpumap.h" |
| 15 | #include "../../util/event.h" | 15 | #include "../../../util/event.h" |
| 16 | #include "../../util/evsel.h" | 16 | #include "../../../util/evsel.h" |
| 17 | #include "../../util/evlist.h" | 17 | #include "../../../util/evlist.h" |
| 18 | #include "../../util/mmap.h" | 18 | #include "../../../util/mmap.h" |
| 19 | #include "../../util/session.h" | 19 | #include "../../../util/session.h" |
| 20 | #include "../../util/pmu.h" | 20 | #include "../../../util/pmu.h" |
| 21 | #include "../../util/debug.h" | 21 | #include "../../../util/debug.h" |
| 22 | #include "../../util/record.h" | 22 | #include "../../../util/record.h" |
| 23 | #include "../../util/tsc.h" | 23 | #include "../../../util/tsc.h" |
| 24 | #include "../../util/auxtrace.h" | 24 | #include "../../../util/auxtrace.h" |
| 25 | #include "../../util/intel-bts.h" | 25 | #include "../../../util/intel-bts.h" |
| 26 | #include <internal/lib.h> // page_size | 26 | #include <internal/lib.h> // page_size |
| 27 | 27 | ||
| 28 | #define KiB(x) ((x) * 1024) | 28 | #define KiB(x) ((x) * 1024) |
| @@ -13,23 +13,23 @@ · 12 unmodified lines | |||
| 13 | #include <linux/zalloc.h> | 13 | #include <linux/zalloc.h> |
| 14 | #include <cpuid.h> | 14 | #include <cpuid.h> |
| 15 | 15 | ||
| 16 | #include "../../util/session.h" | 16 | #include "../../../util/session.h" |
| 17 | #include "../../util/event.h" | 17 | #include "../../../util/event.h" |
| 18 | #include "../../util/evlist.h" | 18 | #include "../../../util/evlist.h" |
| 19 | #include "../../util/evsel.h" | 19 | #include "../../../util/evsel.h" |
| 20 | #include "../../util/evsel_config.h" | 20 | #include "../../../util/evsel_config.h" |
| 21 | #include "../../util/cpumap.h" | 21 | #include "../../../util/cpumap.h" |
| 22 | #include "../../util/mmap.h" | 22 | #include "../../../util/mmap.h" |
| 23 | #include <subcmd/parse-options.h> | 23 | #include <subcmd/parse-options.h> |
| 24 | #include "../../util/parse-events.h" | 24 | #include "../../../util/parse-events.h" |
| 25 | #include "../../util/pmu.h" | 25 | #include "../../../util/pmu.h" |
| 26 | #include "../../util/debug.h" | 26 | #include "../../../util/debug.h" |
| 27 | #include "../../util/auxtrace.h" | 27 | #include "../../../util/auxtrace.h" |
| 28 | #include "../../util/record.h" | 28 | #include "../../../util/record.h" |
| 29 | #include "../../util/target.h" | 29 | #include "../../../util/target.h" |
| 30 | #include "../../util/tsc.h" | 30 | #include "../../../util/tsc.h" |
| 31 | #include <internal/lib.h> // page_size | 31 | #include <internal/lib.h> // page_size |
| 32 | #include "../../util/intel-pt.h" | 32 | #include "../../../util/intel-pt.h" |
| 33 | 33 | ||
| 34 | #define KiB(x) ((x) * 1024) | 34 | #define KiB(x) ((x) * 1024) |
| 35 | #define MiB(x) ((x) * 1024 * 1024) | 35 | #define MiB(x) ((x) * 1024 * 1024) |
| @@ -5,9 +5,9 @@ · 4 unmodified lines | |||
| 5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
| 6 | 6 | ||
| 7 | #include <internal/lib.h> // page_size | 7 | #include <internal/lib.h> // page_size |
| 8 | #include "../../util/machine.h" | 8 | #include "../../../util/machine.h" |
| 9 | #include "../../util/map.h" | 9 | #include "../../../util/map.h" |
| 10 | #include "../../util/symbol.h" | 10 | #include "../../../util/symbol.h" |
| 11 | #include <linux/ctype.h> | 11 | #include <linux/ctype.h> |
| 12 | 12 | ||
| 13 | #include <symbol/kallsyms.h> | 13 | #include <symbol/kallsyms.h> |
| @@ -5,10 +5,10 @@ · 4 unmodified lines | |||
| 5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
| 6 | #include <linux/zalloc.h> | 6 | #include <linux/zalloc.h> |
| 7 | 7 | ||
| 8 | #include "../../perf-sys.h" | 8 | #include "../../../perf-sys.h" |
| 9 | #include "../../util/perf_regs.h" | 9 | #include "../../../util/perf_regs.h" |
| 10 | #include "../../util/debug.h" | 10 | #include "../../../util/debug.h" |
| 11 | #include "../../util/event.h" | 11 | #include "../../../util/event.h" |
| 12 | 12 | ||
| 13 | const struct sample_reg sample_reg_masks[] = { | 13 | const struct sample_reg sample_reg_masks[] = { |
| 14 | SMPL_REG(AX, PERF_REG_X86_AX), | 14 | SMPL_REG(AX, PERF_REG_X86_AX), |
| @@ -4,9 +4,9 @@ · 3 unmodified lines | |||
| 4 | #include <linux/stddef.h> | 4 | #include <linux/stddef.h> |
| 5 | #include <linux/perf_event.h> | 5 | #include <linux/perf_event.h> |
| 6 | 6 | ||
| 7 | #include "../../util/intel-pt.h" | 7 | #include "../../../util/intel-pt.h" |
| 8 | #include "../../util/intel-bts.h" | 8 | #include "../../../util/intel-bts.h" |
| 9 | #include "../../util/pmu.h" | 9 | #include "../../../util/pmu.h" |
| 10 | 10 | ||
| 11 | struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused) | 11 | struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused) |
| 12 | { | 12 | { |
| @@ -2,6 +2,10 @@ · 1 unmodified line | |||
| 2 | #ifndef BENCH_H | 2 | #ifndef BENCH_H |
| 3 | #define BENCH_H | 3 | #define BENCH_H |
| 4 | 4 | ||
| 5 | #include <sys/time.h> | ||
| 6 | |||
| 7 | extern struct timeval bench__start, bench__end, bench__runtime; | ||
| 8 | |||
| 5 | /* | 9 | /* |
| 6 | * The madvise transparent hugepage constants were added in glibc | 10 | * The madvise transparent hugepage constants were added in glibc |
| 7 | * 2.13. For compatibility with older versions of glibc, define these | 11 | * 2.13. For compatibility with older versions of glibc, define these |
| @@ -35,7 +35,6 @@ · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | static unsigned int nthreads = 0; | 36 | static unsigned int nthreads = 0; |
| 37 | static unsigned int nsecs = 8; | 37 | static unsigned int nsecs = 8; |
| 38 | struct timeval start, end, runtime; | ||
| 39 | static bool done, __verbose, randomize; | 38 | static bool done, __verbose, randomize; |
| 40 | 39 | ||
| 41 | /* | 40 | /* |
| @@ -94,8 +93,8 @@ static void toggle_done(int sig __maybe_unused, · 52 unmodified lines | |||
| 94 | { | 93 | { |
| 95 | /* inform all threads that we're done for the day */ | 94 | /* inform all threads that we're done for the day */ |
| 96 | done = true; | 95 | done = true; |
| 97 | gettimeofday(&end, NULL); | 96 | gettimeofday(&bench__end, NULL); |
| 98 | timersub(&end, &start, &runtime); | 97 | timersub(&bench__end, &bench__start, &bench__runtime); |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | static void nest_epollfd(void) | 100 | static void nest_epollfd(void) |
| @@ -313,6 +312,7 @@ int bench_epoll_ctl(int argc, const char **argv) · 211 unmodified lines | |||
| 313 | exit(EXIT_FAILURE); | 312 | exit(EXIT_FAILURE); |
| 314 | } | 313 | } |
| 315 | 314 | ||
| 315 | memset(&act, 0, sizeof(act)); | ||
| 316 | sigfillset(&act.sa_mask); | 316 | sigfillset(&act.sa_mask); |
| 317 | act.sa_sigaction = toggle_done; | 317 | act.sa_sigaction = toggle_done; |
| 318 | sigaction(SIGINT, &act, NULL); | 318 | sigaction(SIGINT, &act, NULL); |
| @@ -361,7 +361,7 @@ int bench_epoll_ctl(int argc, const char **argv) · 42 unmodified lines | |||
| 361 | 361 | ||
| 362 | threads_starting = nthreads; | 362 | threads_starting = nthreads; |
| 363 | 363 | ||
| 364 | gettimeofday(&start, NULL); | 364 | gettimeofday(&bench__start, NULL); |
| 365 | 365 | ||
| 366 | do_threads(worker, cpu); | 366 | do_threads(worker, cpu); |
| 367 | 367 | ||
| @@ -90,7 +90,6 @@ · 89 unmodified lines | |||
| 90 | 90 | ||
| 91 | static unsigned int nthreads = 0; | 91 | static unsigned int nthreads = 0; |
| 92 | static unsigned int nsecs = 8; | 92 | static unsigned int nsecs = 8; |
| 93 | struct timeval start, end, runtime; | ||
| 94 | static bool wdone, done, __verbose, randomize, nonblocking; | 93 | static bool wdone, done, __verbose, randomize, nonblocking; |
| 95 | 94 | ||
| 96 | /* | 95 | /* |
| @@ -276,8 +275,8 @@ static void toggle_done(int sig __maybe_unused, · 179 unmodified lines | |||
| 276 | { | 275 | { |
| 277 | /* inform all threads that we're done for the day */ | 276 | /* inform all threads that we're done for the day */ |
| 278 | done = true; | 277 | done = true; |
| 279 | gettimeofday(&end, NULL); | 278 | gettimeofday(&bench__end, NULL); |
| 280 | timersub(&end, &start, &runtime); | 279 | timersub(&bench__end, &bench__start, &bench__runtime); |
| 281 | } | 280 | } |
| 282 | 281 | ||
| 283 | static void print_summary(void) | 282 | static void print_summary(void) |
| @@ -287,7 +286,7 @@ static void print_summary(void) · 3 unmodified lines | |||
| 287 | 286 | ||
| 288 | printf("\nAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", | 287 | printf("\nAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", |
| 289 | avg, rel_stddev_stats(stddev, avg), | 288 | avg, rel_stddev_stats(stddev, avg), |
| 290 | (int) runtime.tv_sec); | 289 | (int)bench__runtime.tv_sec); |
| 291 | } | 290 | } |
| 292 | 291 | ||
| 293 | static int do_threads(struct worker *worker, struct perf_cpu_map *cpu) | 292 | static int do_threads(struct worker *worker, struct perf_cpu_map *cpu) |
| @@ -427,6 +426,7 @@ int bench_epoll_wait(int argc, const char **argv) · 133 unmodified lines | |||
| 427 | exit(EXIT_FAILURE); | 426 | exit(EXIT_FAILURE); |
| 428 | } | 427 | } |
| 429 | 428 | ||
| 429 | memset(&act, 0, sizeof(act)); | ||
| 430 | sigfillset(&act.sa_mask); | 430 | sigfillset(&act.sa_mask); |
| 431 | act.sa_sigaction = toggle_done; | 431 | act.sa_sigaction = toggle_done; |
| 432 | sigaction(SIGINT, &act, NULL); | 432 | sigaction(SIGINT, &act, NULL); |
| @@ -479,7 +479,7 @@ int bench_epoll_wait(int argc, const char **argv) · 46 unmodified lines | |||
| 479 | 479 | ||
| 480 | threads_starting = nthreads; | 480 | threads_starting = nthreads; |
| 481 | 481 | ||
| 482 | gettimeofday(&start, NULL); | 482 | gettimeofday(&bench__start, NULL); |
| 483 | 483 | ||
| 484 | do_threads(worker, cpu); | 484 | do_threads(worker, cpu); |
| 485 | 485 | ||
| @@ -519,7 +519,7 @@ int bench_epoll_wait(int argc, const char **argv) · 33 unmodified lines | |||
| 519 | qsort(worker, nthreads, sizeof(struct worker), cmpworker); | 519 | qsort(worker, nthreads, sizeof(struct worker), cmpworker); |
| 520 | 520 | ||
| 521 | for (i = 0; i < nthreads; i++) { | 521 | for (i = 0; i < nthreads; i++) { |
| 522 | unsigned long t = worker[i].ops/runtime.tv_sec; | 522 | unsigned long t = worker[i].ops / bench__runtime.tv_sec; |
| 523 | 523 | ||
| 524 | update_stats(&throughput_stats, t); | 524 | update_stats(&throughput_stats, t); |
| 525 | 525 | ||
| @@ -37,7 +37,7 @@ static unsigned int nfutexes = 1024; · 36 unmodified lines | |||
| 37 | static bool fshared = false, done = false, silent = false; | 37 | static bool fshared = false, done = false, silent = false; |
| 38 | static int futex_flag = 0; | 38 | static int futex_flag = 0; |
| 39 | 39 | ||
| 40 | struct timeval start, end, runtime; | 40 | struct timeval bench__start, bench__end, bench__runtime; |
| 41 | static pthread_mutex_t thread_lock; | 41 | static pthread_mutex_t thread_lock; |
| 42 | static unsigned int threads_starting; | 42 | static unsigned int threads_starting; |
| 43 | static struct stats throughput_stats; | 43 | static struct stats throughput_stats; |
| @@ -103,8 +103,8 @@ static void toggle_done(int sig __maybe_unused, · 59 unmodified lines | |||
| 103 | { | 103 | { |
| 104 | /* inform all threads that we're done for the day */ | 104 | /* inform all threads that we're done for the day */ |
| 105 | done = true; | 105 | done = true; |
| 106 | gettimeofday(&end, NULL); | 106 | gettimeofday(&bench__end, NULL); |
| 107 | timersub(&end, &start, &runtime); | 107 | timersub(&bench__end, &bench__start, &bench__runtime); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void print_summary(void) | 110 | static void print_summary(void) |
| @@ -114,7 +114,7 @@ static void print_summary(void) · 3 unmodified lines | |||
| 114 | 114 | ||
| 115 | printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", | 115 | printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", |
| 116 | !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), | 116 | !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), |
| 117 | (int) runtime.tv_sec); | 117 | (int)bench__runtime.tv_sec); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | int bench_futex_hash(int argc, const char **argv) | 120 | int bench_futex_hash(int argc, const char **argv) |
| @@ -137,6 +137,7 @@ int bench_futex_hash(int argc, const char **argv) · 16 unmodified lines | |||
| 137 | if (!cpu) | 137 | if (!cpu) |
| 138 | goto errmem; | 138 | goto errmem; |
| 139 | 139 | ||
| 140 | memset(&act, 0, sizeof(act)); | ||
| 140 | sigfillset(&act.sa_mask); | 141 | sigfillset(&act.sa_mask); |
| 141 | act.sa_sigaction = toggle_done; | 142 | act.sa_sigaction = toggle_done; |
| 142 | sigaction(SIGINT, &act, NULL); | 143 | sigaction(SIGINT, &act, NULL); |
| @@ -161,7 +162,7 @@ int bench_futex_hash(int argc, const char **argv) · 18 unmodified lines | |||
| 161 | 162 | ||
| 162 | threads_starting = nthreads; | 163 | threads_starting = nthreads; |
| 163 | pthread_attr_init(&thread_attr); | 164 | pthread_attr_init(&thread_attr); |
| 164 | gettimeofday(&start, NULL); | 165 | gettimeofday(&bench__start, NULL); |
| 165 | for (i = 0; i < nthreads; i++) { | 166 | for (i = 0; i < nthreads; i++) { |
| 166 | worker[i].tid = i; | 167 | worker[i].tid = i; |
| 167 | worker[i].futex = calloc(nfutexes, sizeof(*worker[i].futex)); | 168 | worker[i].futex = calloc(nfutexes, sizeof(*worker[i].futex)); |
| @@ -204,7 +205,7 @@ int bench_futex_hash(int argc, const char **argv) · 36 unmodified lines | |||
| 204 | pthread_mutex_destroy(&thread_lock); | 205 | pthread_mutex_destroy(&thread_lock); |
| 205 | 206 | ||
| 206 | for (i = 0; i < nthreads; i++) { | 207 | for (i = 0; i < nthreads; i++) { |
| 207 | unsigned long t = worker[i].ops/runtime.tv_sec; | 208 | unsigned long t = worker[i].ops / bench__runtime.tv_sec; |
| 208 | update_stats(&throughput_stats, t); | 209 | update_stats(&throughput_stats, t); |
| 209 | if (!silent) { | 210 | if (!silent) { |
| 210 | if (nfutexes == 1) | 211 | if (nfutexes == 1) |
| @@ -37,7 +37,6 @@ static bool silent = false, multi = false; · 36 unmodified lines | |||
| 37 | static bool done = false, fshared = false; | 37 | static bool done = false, fshared = false; |
| 38 | static unsigned int nthreads = 0; | 38 | static unsigned int nthreads = 0; |
| 39 | static int futex_flag = 0; | 39 | static int futex_flag = 0; |
| 40 | struct timeval start, end, runtime; | ||
| 41 | static pthread_mutex_t thread_lock; | 40 | static pthread_mutex_t thread_lock; |
| 42 | static unsigned int threads_starting; | 41 | static unsigned int threads_starting; |
| 43 | static struct stats throughput_stats; | 42 | static struct stats throughput_stats; |
| @@ -64,7 +63,7 @@ static void print_summary(void) · 20 unmodified lines | |||
| 64 | 63 | ||
| 65 | printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", | 64 | printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", |
| 66 | !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), | 65 | !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), |
| 67 | (int) runtime.tv_sec); | 66 | (int)bench__runtime.tv_sec); |
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | static void toggle_done(int sig __maybe_unused, | 69 | static void toggle_done(int sig __maybe_unused, |
| @@ -73,8 +72,8 @@ static void toggle_done(int sig __maybe_unused, · 2 unmodified lines | |||
| 73 | { | 72 | { |
| 74 | /* inform all threads that we're done for the day */ | 73 | /* inform all threads that we're done for the day */ |
| 75 | done = true; | 74 | done = true; |
| 76 | gettimeofday(&end, NULL); | 75 | gettimeofday(&bench__end, NULL); |
| 77 | timersub(&end, &start, &runtime); | 76 | timersub(&bench__end, &bench__start, &bench__runtime); |
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | static void *workerfn(void *arg) | 79 | static void *workerfn(void *arg) |
| @@ -161,6 +160,7 @@ int bench_futex_lock_pi(int argc, const char **argv) · 80 unmodified lines | |||
| 161 | if (!cpu) | 160 | if (!cpu) |
| 162 | err(EXIT_FAILURE, "calloc"); | 161 | err(EXIT_FAILURE, "calloc"); |
| 163 | 162 | ||
| 163 | memset(&act, 0, sizeof(act)); | ||
| 164 | sigfillset(&act.sa_mask); | 164 | sigfillset(&act.sa_mask); |
| 165 | act.sa_sigaction = toggle_done; | 165 | act.sa_sigaction = toggle_done; |
| 166 | sigaction(SIGINT, &act, NULL); | 166 | sigaction(SIGINT, &act, NULL); |
| @@ -185,7 +185,7 @@ int bench_futex_lock_pi(int argc, const char **argv) · 18 unmodified lines | |||
| 185 | 185 | ||
| 186 | threads_starting = nthreads; | 186 | threads_starting = nthreads; |
| 187 | pthread_attr_init(&thread_attr); | 187 | pthread_attr_init(&thread_attr); |
| 188 | gettimeofday(&start, NULL); | 188 | gettimeofday(&bench__start, NULL); |
| 189 | 189 | ||
| 190 | create_threads(worker, thread_attr, cpu); | 190 | create_threads(worker, thread_attr, cpu); |
| 191 | pthread_attr_destroy(&thread_attr); | 191 | pthread_attr_destroy(&thread_attr); |
| @@ -211,7 +211,7 @@ int bench_futex_lock_pi(int argc, const char **argv) · 19 unmodified lines | |||
| 211 | pthread_mutex_destroy(&thread_lock); | 211 | pthread_mutex_destroy(&thread_lock); |
| 212 | 212 | ||
| 213 | for (i = 0; i < nthreads; i++) { | 213 | for (i = 0; i < nthreads; i++) { |
| 214 | unsigned long t = worker[i].ops/runtime.tv_sec; | 214 | unsigned long t = worker[i].ops / bench__runtime.tv_sec; |
| 215 | 215 | ||
| 216 | update_stats(&throughput_stats, t); | 216 | update_stats(&throughput_stats, t); |
| 217 | if (!silent) | 217 | if (!silent) |
| @@ -128,6 +128,7 @@ int bench_futex_requeue(int argc, const char **argv) · 127 unmodified lines | |||
| 128 | if (!cpu) | 128 | if (!cpu) |
| 129 | err(EXIT_FAILURE, "cpu_map__new"); | 129 | err(EXIT_FAILURE, "cpu_map__new"); |
| 130 | 130 | ||
| 131 | memset(&act, 0, sizeof(act)); | ||
| 131 | sigfillset(&act.sa_mask); | 132 | sigfillset(&act.sa_mask); |
| 132 | act.sa_sigaction = toggle_done; | 133 | act.sa_sigaction = toggle_done; |
| 133 | sigaction(SIGINT, &act, NULL); | 134 | sigaction(SIGINT, &act, NULL); |
| @@ -234,6 +234,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) · 233 unmodified lines | |||
| 234 | exit(EXIT_FAILURE); | 234 | exit(EXIT_FAILURE); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | memset(&act, 0, sizeof(act)); | ||
| 237 | sigfillset(&act.sa_mask); | 238 | sigfillset(&act.sa_mask); |
| 238 | act.sa_sigaction = toggle_done; | 239 | act.sa_sigaction = toggle_done; |
| 239 | sigaction(SIGINT, &act, NULL); | 240 | sigaction(SIGINT, &act, NULL); |
| @@ -43,7 +43,7 @@ static bool done = false, silent = false, fshared = false; · 42 unmodified lines | |||
| 43 | static pthread_mutex_t thread_lock; | 43 | static pthread_mutex_t thread_lock; |
| 44 | static pthread_cond_t thread_parent, thread_worker; | 44 | static pthread_cond_t thread_parent, thread_worker; |
| 45 | static struct stats waketime_stats, wakeup_stats; | 45 | static struct stats waketime_stats, wakeup_stats; |
| 46 | static unsigned int ncpus, threads_starting, nthreads = 0; | 46 | static unsigned int threads_starting, nthreads = 0; |
| 47 | static int futex_flag = 0; | 47 | static int futex_flag = 0; |
| 48 | 48 | ||
| 49 | static const struct option options[] = { | 49 | static const struct option options[] = { |
| @@ -136,12 +136,13 @@ int bench_futex_wake(int argc, const char **argv) · 86 unmodified lines | |||
| 136 | if (!cpu) | 136 | if (!cpu) |
| 137 | err(EXIT_FAILURE, "calloc"); | 137 | err(EXIT_FAILURE, "calloc"); |
| 138 | 138 | ||
| 139 | memset(&act, 0, sizeof(act)); | ||
| 139 | sigfillset(&act.sa_mask); | 140 | sigfillset(&act.sa_mask); |
| 140 | act.sa_sigaction = toggle_done; | 141 | act.sa_sigaction = toggle_done; |
| 141 | sigaction(SIGINT, &act, NULL); | 142 | sigaction(SIGINT, &act, NULL); |
| 142 | 143 | ||
| 143 | if (!nthreads) | 144 | if (!nthreads) |
| 144 | nthreads = ncpus; | 145 | nthreads = cpu->nr; |
| 145 | 146 | ||
| 146 | worker = calloc(nthreads, sizeof(*worker)); | 147 | worker = calloc(nthreads, sizeof(*worker)); |
| 147 | if (!worker) | 148 | if (!worker) |
| @@ -1312,7 +1312,8 @@ static int cycles_printf(struct hist_entry *he, struct hist_entry *pair, · 1311 unmodified lines | |||
| 1312 | end_line = map__srcline(he->ms.map, bi->sym->start + bi->end, | 1312 | end_line = map__srcline(he->ms.map, bi->sym->start + bi->end, |
| 1313 | he->ms.sym); | 1313 | he->ms.sym); |
| 1314 | 1314 | ||
| 1315 | if ((start_line != SRCLINE_UNKNOWN) && (end_line != SRCLINE_UNKNOWN)) { | 1315 | if ((strncmp(start_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) && |
| 1316 | (strncmp(end_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)) { | ||
| 1316 | scnprintf(buf, sizeof(buf), "[%s -> %s] %4ld", | 1317 | scnprintf(buf, sizeof(buf), "[%s -> %s] %4ld", |
| 1317 | start_line, end_line, block_he->diff.cycles); | 1318 | start_line, end_line, block_he->diff.cycles); |
| 1318 | } else { | 1319 | } else { |
| @@ -684,7 +684,9 @@ repeat: · 683 unmodified lines | |||
| 684 | delay_msecs = top->delay_secs * MSEC_PER_SEC; | 684 | delay_msecs = top->delay_secs * MSEC_PER_SEC; |
| 685 | set_term_quiet_input(&save); | 685 | set_term_quiet_input(&save); |
| 686 | /* trash return*/ | 686 | /* trash return*/ |
| 687 | getc(stdin); | 687 | clearerr(stdin); |
| 688 | if (poll(&stdin_poll, 1, 0) > 0) | ||
| 689 | getc(stdin); | ||
| 688 | 690 | ||
| 689 | while (!done) { | 691 | while (!done) { |
| 690 | perf_top__print_sym_table(top); | 692 | perf_top__print_sym_table(top); |
| @@ -1082,10 +1082,9 @@ static int process_one_file(const char *fpath, const struct stat *sb, · 1081 unmodified lines | |||
| 1082 | */ | 1082 | */ |
| 1083 | int main(int argc, char *argv[]) | 1083 | int main(int argc, char *argv[]) |
| 1084 | { | 1084 | { |
| 1085 | int rc; | 1085 | int rc, ret = 0; |
| 1086 | int maxfds; | 1086 | int maxfds; |
| 1087 | char ldirname[PATH_MAX]; | 1087 | char ldirname[PATH_MAX]; |
| 1088 | |||
| 1089 | const char *arch; | 1088 | const char *arch; |
| 1090 | const char *output_file; | 1089 | const char *output_file; |
| 1091 | const char *start_dirname; | 1090 | const char *start_dirname; |
| @@ -1156,7 +1155,8 @@ int main(int argc, char *argv[]) · 64 unmodified lines | |||
| 1156 | /* Make build fail */ | 1155 | /* Make build fail */ |
| 1157 | fclose(eventsfp); | 1156 | fclose(eventsfp); |
| 1158 | free_arch_std_events(); | 1157 | free_arch_std_events(); |
| 1159 | return 1; | 1158 | ret = 1; |
| 1159 | goto out_free_mapfile; | ||
| 1160 | } else if (rc) { | 1160 | } else if (rc) { |
| 1161 | goto empty_map; | 1161 | goto empty_map; |
| 1162 | } | 1162 | } |
| @@ -1174,14 +1174,17 @@ int main(int argc, char *argv[]) · 11 unmodified lines | |||
| 1174 | /* Make build fail */ | 1174 | /* Make build fail */ |
| 1175 | fclose(eventsfp); | 1175 | fclose(eventsfp); |
| 1176 | free_arch_std_events(); | 1176 | free_arch_std_events(); |
| 1177 | return 1; | 1177 | ret = 1; |
| 1178 | } | 1178 | } |
| 1179 | 1179 | ||
| 1180 | return 0; | 1180 | |
| 1181 | goto out_free_mapfile; | ||
| 1181 | 1182 | ||
| 1182 | empty_map: | 1183 | empty_map: |
| 1183 | fclose(eventsfp); | 1184 | fclose(eventsfp); |
| 1184 | create_empty_mapping(output_file); | 1185 | create_empty_mapping(output_file); |
| 1185 | free_arch_std_events(); | 1186 | free_arch_std_events(); |
| 1186 | return 0; | 1187 | out_free_mapfile: |
| 1188 | free(mapfile); | ||
| 1189 | return ret; | ||
| 1187 | } | 1190 | } |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include "../perf-sys.h" | 19 | #include "../perf-sys.h" |
| 20 | #include "cloexec.h" | 20 | #include "cloexec.h" |
| 21 | 21 | ||
| 22 | volatile long the_var; | 22 | static volatile long the_var; |
| 23 | 23 | ||
| 24 | static noinline int test_function(void) | 24 | static noinline int test_function(void) |
| 25 | { | 25 | { |
| @@ -295,7 +295,8 @@ static int block_range_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, · 294 unmodified lines | |||
| 295 | end_line = map__srcline(he->ms.map, bi->sym->start + bi->end, | 295 | end_line = map__srcline(he->ms.map, bi->sym->start + bi->end, |
| 296 | he->ms.sym); | 296 | he->ms.sym); |
| 297 | 297 | ||
| 298 | if ((start_line != SRCLINE_UNKNOWN) && (end_line != SRCLINE_UNKNOWN)) { | 298 | if ((strncmp(start_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) && |
| 299 | (strncmp(end_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)) { | ||
| 299 | scnprintf(buf, sizeof(buf), "[%s -> %s]", | 300 | scnprintf(buf, sizeof(buf), "[%s -> %s]", |
| 300 | start_line, end_line); | 301 | start_line, end_line); |
| 301 | } else { | 302 | } else { |
| @@ -343,11 +343,11 @@ static const char *normalize_arch(char *arch) · 342 unmodified lines | |||
| 343 | 343 | ||
| 344 | const char *perf_env__arch(struct perf_env *env) | 344 | const char *perf_env__arch(struct perf_env *env) |
| 345 | { | 345 | { |
| 346 | struct utsname uts; | ||
| 347 | char *arch_name; | 346 | char *arch_name; |
| 348 | 347 | ||
| 349 | if (!env || !env->arch) { /* Assume local operation */ | 348 | if (!env || !env->arch) { /* Assume local operation */ |
| 350 | if (uname(&uts) < 0) | 349 | static struct utsname uts = { .machine[0] = '\0', }; |
| 350 | if (uts.machine[0] == '\0' && uname(&uts) < 0) | ||
| 351 | return NULL; | 351 | return NULL; |
| 352 | arch_name = uts.machine; | 352 | arch_name = uts.machine; |
| 353 | } else | 353 | } else |
| @@ -89,7 +89,7 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) · 88 unmodified lines | |||
| 89 | return true; | 89 | return true; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | if (!strncmp(filename, "/system/lib/", 11)) { | 92 | if (!strncmp(filename, "/system/lib/", 12)) { |
| 93 | char *ndk, *app; | 93 | char *ndk, *app; |
| 94 | const char *arch; | 94 | const char *arch; |
| 95 | size_t ndk_length; | 95 | size_t ndk_length; |
| @@ -431,7 +431,7 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, · 335 unmodified lines | |||
| 431 | 431 | ||
| 432 | if (map && map->dso) { | 432 | if (map && map->dso) { |
| 433 | char *srcline = map__srcline(map, addr, NULL); | 433 | char *srcline = map__srcline(map, addr, NULL); |
| 434 | if (srcline != SRCLINE_UNKNOWN) | 434 | if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) |
| 435 | ret = fprintf(fp, "%s%s", prefix, srcline); | 435 | ret = fprintf(fp, "%s%s", prefix, srcline); |
| 436 | free_srcline(srcline); | 436 | free_srcline(srcline); |
| 437 | } | 437 | } |
| @@ -257,21 +257,15 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) · 256 unmodified lines | |||
| 257 | path = zalloc(sizeof(*path)); | 257 | path = zalloc(sizeof(*path)); |
| 258 | if (!path) | 258 | if (!path) |
| 259 | return NULL; | 259 | return NULL; |
| 260 | path->system = malloc(MAX_EVENT_LENGTH); | 260 | if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { |
| 261 | if (!path->system) { | ||
| 262 | free(path); | 261 | free(path); |
| 263 | return NULL; | 262 | return NULL; |
| 264 | } | 263 | } |
| 265 | path->name = malloc(MAX_EVENT_LENGTH); | 264 | if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { |
| 266 | if (!path->name) { | ||
| 267 | zfree(&path->system); | 265 | zfree(&path->system); |
| 268 | free(path); | 266 | free(path); |
| 269 | return NULL; | 267 | return NULL; |
| 270 | } | 268 | } |
| 271 | strncpy(path->system, sys_dirent->d_name, | ||
| 272 | MAX_EVENT_LENGTH); | ||
| 273 | strncpy(path->name, evt_dirent->d_name, | ||
| 274 | MAX_EVENT_LENGTH); | ||
| 275 | return path; | 269 | return path; |
| 276 | } | 270 | } |
| 277 | } | 271 | } |
| @@ -1219,7 +1213,7 @@ static int config_attr(struct perf_event_attr *attr, · 941 unmodified lines | |||
| 1219 | static int get_config_terms(struct list_head *head_config, | 1213 | static int get_config_terms(struct list_head *head_config, |
| 1220 | struct list_head *head_terms __maybe_unused) | 1214 | struct list_head *head_terms __maybe_unused) |
| 1221 | { | 1215 | { |
| 1222 | #define ADD_CONFIG_TERM(__type) \ | 1216 | #define ADD_CONFIG_TERM(__type, __weak) \ |
| 1223 | struct perf_evsel_config_term *__t; \ | 1217 | struct perf_evsel_config_term *__t; \ |
| 1224 | \ | 1218 | \ |
| 1225 | __t = zalloc(sizeof(*__t)); \ | 1219 | __t = zalloc(sizeof(*__t)); \ |
| @@ -1228,18 +1222,18 @@ static int get_config_terms(struct list_head *head_config, · 2 unmodified lines | |||
| 1228 | \ | 1222 | \ |
| 1229 | INIT_LIST_HEAD(&__t->list); \ | 1223 | INIT_LIST_HEAD(&__t->list); \ |
| 1230 | __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ | 1224 | __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ |
| 1231 | __t->weak = term->weak; \ | 1225 | __t->weak = __weak; \ |
| 1232 | list_add_tail(&__t->list, head_terms) | 1226 | list_add_tail(&__t->list, head_terms) |
| 1233 | 1227 | ||
| 1234 | #define ADD_CONFIG_TERM_VAL(__type, __name, __val) \ | 1228 | #define ADD_CONFIG_TERM_VAL(__type, __name, __val, __weak) \ |
| 1235 | do { \ | 1229 | do { \ |
| 1236 | ADD_CONFIG_TERM(__type); \ | 1230 | ADD_CONFIG_TERM(__type, __weak); \ |
| 1237 | __t->val.__name = __val; \ | 1231 | __t->val.__name = __val; \ |
| 1238 | } while (0) | 1232 | } while (0) |
| 1239 | 1233 | ||
| 1240 | #define ADD_CONFIG_TERM_STR(__type, __val) \ | 1234 | #define ADD_CONFIG_TERM_STR(__type, __val, __weak) \ |
| 1241 | do { \ | 1235 | do { \ |
| 1242 | ADD_CONFIG_TERM(__type); \ | 1236 | ADD_CONFIG_TERM(__type, __weak); \ |
| 1243 | __t->val.str = strdup(__val); \ | 1237 | __t->val.str = strdup(__val); \ |
| 1244 | if (!__t->val.str) { \ | 1238 | if (!__t->val.str) { \ |
| 1245 | zfree(&__t); \ | 1239 | zfree(&__t); \ |
| @@ -1253,62 +1247,62 @@ do { \ · 7 unmodified lines | |||
| 1253 | list_for_each_entry(term, head_config, list) { | 1247 | list_for_each_entry(term, head_config, list) { |
| 1254 | switch (term->type_term) { | 1248 | switch (term->type_term) { |
| 1255 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: | 1249 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: |
| 1256 | ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num); | 1250 | ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num, term->weak); |
| 1257 | break; | 1251 | break; |
| 1258 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: | 1252 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: |
| 1259 | ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num); | 1253 | ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num, term->weak); |
| 1260 | break; | 1254 | break; |
| 1261 | case PARSE_EVENTS__TERM_TYPE_TIME: | 1255 | case PARSE_EVENTS__TERM_TYPE_TIME: |
| 1262 | ADD_CONFIG_TERM_VAL(TIME, time, term->val.num); | 1256 | ADD_CONFIG_TERM_VAL(TIME, time, term->val.num, term->weak); |
| 1263 | break; | 1257 | break; |
| 1264 | case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: | 1258 | case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: |
| 1265 | ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str); | 1259 | ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str, term->weak); |
| 1266 | break; | 1260 | break; |
| 1267 | case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: | 1261 | case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: |
| 1268 | ADD_CONFIG_TERM_STR(BRANCH, term->val.str); | 1262 | ADD_CONFIG_TERM_STR(BRANCH, term->val.str, term->weak); |
| 1269 | break; | 1263 | break; |
| 1270 | case PARSE_EVENTS__TERM_TYPE_STACKSIZE: | 1264 | case PARSE_EVENTS__TERM_TYPE_STACKSIZE: |
| 1271 | ADD_CONFIG_TERM_VAL(STACK_USER, stack_user, | 1265 | ADD_CONFIG_TERM_VAL(STACK_USER, stack_user, |
| 1272 | term->val.num); | 1266 | term->val.num, term->weak); |
| 1273 | break; | 1267 | break; |
| 1274 | case PARSE_EVENTS__TERM_TYPE_INHERIT: | 1268 | case PARSE_EVENTS__TERM_TYPE_INHERIT: |
| 1275 | ADD_CONFIG_TERM_VAL(INHERIT, inherit, | 1269 | ADD_CONFIG_TERM_VAL(INHERIT, inherit, |
| 1276 | term->val.num ? 1 : 0); | 1270 | term->val.num ? 1 : 0, term->weak); |
| 1277 | break; | 1271 | break; |
| 1278 | case PARSE_EVENTS__TERM_TYPE_NOINHERIT: | 1272 | case PARSE_EVENTS__TERM_TYPE_NOINHERIT: |
| 1279 | ADD_CONFIG_TERM_VAL(INHERIT, inherit, | 1273 | ADD_CONFIG_TERM_VAL(INHERIT, inherit, |
| 1280 | term->val.num ? 0 : 1); | 1274 | term->val.num ? 0 : 1, term->weak); |
| 1281 | break; | 1275 | break; |
| 1282 | case PARSE_EVENTS__TERM_TYPE_MAX_STACK: | 1276 | case PARSE_EVENTS__TERM_TYPE_MAX_STACK: |
| 1283 | ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack, | 1277 | ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack, |
| 1284 | term->val.num); | 1278 | term->val.num, term->weak); |
| 1285 | break; | 1279 | break; |
| 1286 | case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: | 1280 | case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: |
| 1287 | ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events, | 1281 | ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events, |
| 1288 | term->val.num); | 1282 | term->val.num, term->weak); |
| 1289 | break; | 1283 | break; |
| 1290 | case PARSE_EVENTS__TERM_TYPE_OVERWRITE: | 1284 | case PARSE_EVENTS__TERM_TYPE_OVERWRITE: |
| 1291 | ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, | 1285 | ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, |
| 1292 | term->val.num ? 1 : 0); | 1286 | term->val.num ? 1 : 0, term->weak); |
| 1293 | break; | 1287 | break; |
| 1294 | case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: | 1288 | case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: |
| 1295 | ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, | 1289 | ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, |
| 1296 | term->val.num ? 0 : 1); | 1290 | term->val.num ? 0 : 1, term->weak); |
| 1297 | break; | 1291 | break; |
| 1298 | case PARSE_EVENTS__TERM_TYPE_DRV_CFG: | 1292 | case PARSE_EVENTS__TERM_TYPE_DRV_CFG: |
| 1299 | ADD_CONFIG_TERM_STR(DRV_CFG, term->val.str); | 1293 | ADD_CONFIG_TERM_STR(DRV_CFG, term->val.str, term->weak); |
| 1300 | break; | 1294 | break; |
| 1301 | case PARSE_EVENTS__TERM_TYPE_PERCORE: | 1295 | case PARSE_EVENTS__TERM_TYPE_PERCORE: |
| 1302 | ADD_CONFIG_TERM_VAL(PERCORE, percore, | 1296 | ADD_CONFIG_TERM_VAL(PERCORE, percore, |
| 1303 | term->val.num ? true : false); | 1297 | term->val.num ? true : false, term->weak); |
| 1304 | break; | 1298 | break; |
| 1305 | case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: | 1299 | case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: |
| 1306 | ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output, | 1300 | ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output, |
| 1307 | term->val.num ? 1 : 0); | 1301 | term->val.num ? 1 : 0, term->weak); |
| 1308 | break; | 1302 | break; |
| 1309 | case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: | 1303 | case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: |
| 1310 | ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size, | 1304 | ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size, |
| 1311 | term->val.num); | 1305 | term->val.num, term->weak); |
| 1312 | break; | 1306 | break; |
| 1313 | default: | 1307 | default: |
| 1314 | break; | 1308 | break; |
| @@ -1345,7 +1339,7 @@ static int get_config_chgs(struct perf_pmu *pmu, struct list_head *head_config, · 30 unmodified lines | |||
| 1345 | } | 1339 | } |
| 1346 | 1340 | ||
| 1347 | if (bits) | 1341 | if (bits) |
| 1348 | ADD_CONFIG_TERM_VAL(CFG_CHG, cfg_chg, bits); | 1342 | ADD_CONFIG_TERM_VAL(CFG_CHG, cfg_chg, bits, false); |
| 1349 | 1343 | ||
| 1350 | #undef ADD_CONFIG_TERM | 1344 | #undef ADD_CONFIG_TERM |
| 1351 | return 0; | 1345 | return 0; |
| @@ -206,6 +206,9 @@ static struct strlist *__probe_file__get_namelist(int fd, bool include_group) · 205 unmodified lines | |||
| 206 | } else | 206 | } else |
| 207 | ret = strlist__add(sl, tev.event); | 207 | ret = strlist__add(sl, tev.event); |
| 208 | clear_probe_trace_event(&tev); | 208 | clear_probe_trace_event(&tev); |
| 209 | /* Skip if there is same name multi-probe event in the list */ | ||
| 210 | if (ret == -EEXIST) | ||
| 211 | ret = 0; | ||
| 209 | if (ret < 0) | 212 | if (ret < 0) |
| 210 | break; | 213 | break; |
| 211 | } | 214 | } |
| @@ -637,14 +637,19 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, · 636 unmodified lines | |||
| 637 | return -EINVAL; | 637 | return -EINVAL; |
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | /* Try to get actual symbol name from symtab */ | 640 | if (dwarf_entrypc(sp_die, &eaddr) == 0) { |
| 641 | symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); | 641 | /* If the DIE has entrypc, use it. */ |
| 642 | symbol = dwarf_diename(sp_die); | ||
| 643 | } else { | ||
| 644 | /* Try to get actual symbol name and address from symtab */ | ||
| 645 | symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); | ||
| 646 | eaddr = sym.st_value; | ||
| 647 | } | ||
| 642 | if (!symbol) { | 648 | if (!symbol) { |
| 643 | pr_warning("Failed to find symbol at 0x%lx\n", | 649 | pr_warning("Failed to find symbol at 0x%lx\n", |
| 644 | (unsigned long)paddr); | 650 | (unsigned long)paddr); |
| 645 | return -ENOENT; | 651 | return -ENOENT; |
| 646 | } | 652 | } |
| 647 | eaddr = sym.st_value; | ||
| 648 | 653 | ||
| 649 | tp->offset = (unsigned long)(paddr - eaddr); | 654 | tp->offset = (unsigned long)(paddr - eaddr); |
| 650 | tp->address = (unsigned long)paddr; | 655 | tp->address = (unsigned long)paddr; |
| @@ -2,11 +2,13 @@ from os import getenv · 1 unmodified line | |||
| 2 | from subprocess import Popen, PIPE | 2 | from subprocess import Popen, PIPE |
| 3 | from re import sub | 3 | from re import sub |
| 4 | 4 | ||
| 5 | cc = getenv("CC") | ||
| 6 | cc_is_clang = b"clang version" in Popen([cc, "-v"], stderr=PIPE).stderr.readline() | ||
| 7 | |||
| 5 | def clang_has_option(option): | 8 | def clang_has_option(option): |
| 6 | return [o for o in Popen(['clang', option], stderr=PIPE).stderr.readlines() if b"unknown argument" in o] == [ ] | 9 | return [o for o in Popen([cc, option], stderr=PIPE).stderr.readlines() if b"unknown argument" in o] == [ ] |
| 7 | 10 | ||
| 8 | cc = getenv("CC") | 11 | if cc_is_clang: |
| 9 | if cc == "clang": | ||
| 10 | from distutils.sysconfig import get_config_vars | 12 | from distutils.sysconfig import get_config_vars |
| 11 | vars = get_config_vars() | 13 | vars = get_config_vars() |
| 12 | for var in ('CFLAGS', 'OPT'): | 14 | for var in ('CFLAGS', 'OPT'): |
| @@ -40,7 +42,7 @@ class install_lib(_install_lib): · 27 unmodified lines | |||
| 40 | cflags = getenv('CFLAGS', '').split() | 42 | cflags = getenv('CFLAGS', '').split() |
| 41 | # switch off several checks (need to be at the end of cflags list) | 43 | # switch off several checks (need to be at the end of cflags list) |
| 42 | cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ] | 44 | cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ] |
| 43 | if cc != "clang": | 45 | if not cc_is_clang: |
| 44 | cflags += ['-Wno-cast-function-type' ] | 46 | cflags += ['-Wno-cast-function-type' ] |
| 45 | 47 | ||
| 46 | src_perf = getenv('srctree') + '/tools/perf' | 48 | src_perf = getenv('srctree') + '/tools/perf' |
| @@ -1622,7 +1622,12 @@ int dso__load(struct dso *dso, struct map *map) · 1621 unmodified lines | |||
| 1622 | goto out; | 1622 | goto out; |
| 1623 | } | 1623 | } |
| 1624 | 1624 | ||
| 1625 | if (dso->kernel) { | 1625 | kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || |
| 1626 | dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || | ||
| 1627 | dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || | ||
| 1628 | dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; | ||
| 1629 | |||
| 1630 | if (dso->kernel && !kmod) { | ||
| 1626 | if (dso->kernel == DSO_TYPE_KERNEL) | 1631 | if (dso->kernel == DSO_TYPE_KERNEL) |
| 1627 | ret = dso__load_kernel_sym(dso, map); | 1632 | ret = dso__load_kernel_sym(dso, map); |
| 1628 | else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) | 1633 | else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
| @@ -1650,12 +1655,6 @@ int dso__load(struct dso *dso, struct map *map) · 21 unmodified lines | |||
| 1650 | if (!name) | 1655 | if (!name) |
| 1651 | goto out; | 1656 | goto out; |
| 1652 | 1657 | ||
| 1653 | kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || | ||
| 1654 | dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || | ||
| 1655 | dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || | ||
| 1656 | dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; | ||
| 1657 | |||
| 1658 | |||
| 1659 | /* | 1658 | /* |
| 1660 | * Read the build id if possible. This is required for | 1659 | * Read the build id if possible. This is required for |
| 1661 | * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work | 1660 | * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work |
| @@ -82,7 +82,7 @@ static struct pci_access *pci_acc; · 81 unmodified lines | |||
| 82 | static struct pci_dev *amd_fam14h_pci_dev; | 82 | static struct pci_dev *amd_fam14h_pci_dev; |
| 83 | static int nbp1_entered; | 83 | static int nbp1_entered; |
| 84 | 84 | ||
| 85 | struct timespec start_time; | 85 | static struct timespec start_time; |
| 86 | static unsigned long long timediff; | 86 | static unsigned long long timediff; |
| 87 | 87 | ||
| 88 | #ifdef DEBUG | 88 | #ifdef DEBUG |
| @@ -19,7 +19,7 @@ struct cpuidle_monitor cpuidle_sysfs_monitor; · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | static unsigned long long **previous_count; | 20 | static unsigned long long **previous_count; |
| 21 | static unsigned long long **current_count; | 21 | static unsigned long long **current_count; |
| 22 | struct timespec start_time; | 22 | static struct timespec start_time; |
| 23 | static unsigned long long timediff; | 23 | static unsigned long long timediff; |
| 24 | 24 | ||
| 25 | static int cpuidle_get_count_percent(unsigned int id, double *percent, | 25 | static int cpuidle_get_count_percent(unsigned int id, double *percent, |
| @@ -27,6 +27,8 @@ struct cpuidle_monitor *all_monitors[] = { · 26 unmodified lines | |||
| 27 | 0 | 27 | 0 |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | int cpu_count; | ||
| 31 | |||
| 30 | static struct cpuidle_monitor *monitors[MONITORS_MAX]; | 32 | static struct cpuidle_monitor *monitors[MONITORS_MAX]; |
| 31 | static unsigned int avail_monitors; | 33 | static unsigned int avail_monitors; |
| 32 | 34 | ||
| @@ -25,7 +25,7 @@ · 24 unmodified lines | |||
| 25 | #endif | 25 | #endif |
| 26 | #define CSTATE_DESC_LEN 60 | 26 | #define CSTATE_DESC_LEN 60 |
| 27 | 27 | ||
| 28 | int cpu_count; | 28 | extern int cpu_count; |
| 29 | 29 | ||
| 30 | /* Hard to define the right names ...: */ | 30 | /* Hard to define the right names ...: */ |
| 31 | enum power_range_e { | 31 | enum power_range_e { |
| @@ -16,7 +16,7 @@ override CFLAGS += -D_FORTIFY_SOURCE=2 · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | %: %.c | 17 | %: %.c |
| 18 | @mkdir -p $(BUILD_OUTPUT) | 18 | @mkdir -p $(BUILD_OUTPUT) |
| 19 | $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) | 19 | $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) -lcap |
| 20 | 20 | ||
| 21 | .PHONY : clean | 21 | .PHONY : clean |
| 22 | clean : | 22 | clean : |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | |||
| 30 | #include <sched.h> | 30 | #include <sched.h> |
| 31 | #include <time.h> | 31 | #include <time.h> |
| 32 | #include <cpuid.h> | 32 | #include <cpuid.h> |
| 33 | #include <linux/capability.h> | 33 | #include <sys/capability.h> |
| 34 | #include <errno.h> | 34 | #include <errno.h> |
| 35 | #include <math.h> | 35 | #include <math.h> |
| 36 | 36 | ||
| @@ -304,6 +304,10 @@ int *irqs_per_cpu; /* indexed by cpu_num */ · 267 unmodified lines | |||
| 304 | 304 | ||
| 305 | void setup_all_buffers(void); | 305 | void setup_all_buffers(void); |
| 306 | 306 | ||
| 307 | char *sys_lpi_file; | ||
| 308 | char *sys_lpi_file_sysfs = "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us"; | ||
| 309 | char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec"; | ||
| 310 | |||
| 307 | int cpu_is_not_present(int cpu) | 311 | int cpu_is_not_present(int cpu) |
| 308 | { | 312 | { |
| 309 | return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); | 313 | return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); |
| @@ -2916,8 +2920,6 @@ int snapshot_gfx_mhz(void) · 2606 unmodified lines | |||
| 2916 | * | 2920 | * |
| 2917 | * record snapshot of | 2921 | * record snapshot of |
| 2918 | * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us | 2922 | * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us |
| 2919 | * | ||
| 2920 | * return 1 if config change requires a restart, else return 0 | ||
| 2921 | */ | 2923 | */ |
| 2922 | int snapshot_cpu_lpi_us(void) | 2924 | int snapshot_cpu_lpi_us(void) |
| 2923 | { | 2925 | { |
| @@ -2941,17 +2943,14 @@ int snapshot_cpu_lpi_us(void) · 17 unmodified lines | |||
| 2941 | /* | 2943 | /* |
| 2942 | * snapshot_sys_lpi() | 2944 | * snapshot_sys_lpi() |
| 2943 | * | 2945 | * |
| 2944 | * record snapshot of | 2946 | * record snapshot of sys_lpi_file |
| 2945 | * /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us | ||
| 2946 | * | ||
| 2947 | * return 1 if config change requires a restart, else return 0 | ||
| 2948 | */ | 2947 | */ |
| 2949 | int snapshot_sys_lpi_us(void) | 2948 | int snapshot_sys_lpi_us(void) |
| 2950 | { | 2949 | { |
| 2951 | FILE *fp; | 2950 | FILE *fp; |
| 2952 | int retval; | 2951 | int retval; |
| 2953 | 2952 | ||
| 2954 | fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r"); | 2953 | fp = fopen_or_die(sys_lpi_file, "r"); |
| 2955 | 2954 | ||
| 2956 | retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); | 2955 | retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); |
| 2957 | if (retval != 1) { | 2956 | if (retval != 1) { |
| @@ -3151,28 +3150,42 @@ void check_dev_msr() · 193 unmodified lines | |||
| 3151 | err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); | 3150 | err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); |
| 3152 | } | 3151 | } |
| 3153 | 3152 | ||
| 3154 | void check_permissions() | 3153 | /* |
| 3154 | * check for CAP_SYS_RAWIO | ||
| 3155 | * return 0 on success | ||
| 3156 | * return 1 on fail | ||
| 3157 | */ | ||
| 3158 | int check_for_cap_sys_rawio(void) | ||
| 3155 | { | 3159 | { |
| 3156 | struct __user_cap_header_struct cap_header_data; | 3160 | cap_t caps; |
| 3157 | cap_user_header_t cap_header = &cap_header_data; | 3161 | cap_flag_value_t cap_flag_value; |
| 3158 | struct __user_cap_data_struct cap_data_data; | ||
| 3159 | cap_user_data_t cap_data = &cap_data_data; | ||
| 3160 | extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); | ||
| 3161 | int do_exit = 0; | ||
| 3162 | char pathname[32]; | ||
| 3163 | 3162 | ||
| 3164 | /* check for CAP_SYS_RAWIO */ | 3163 | caps = cap_get_proc(); |
| 3165 | cap_header->pid = getpid(); | 3164 | if (caps == NULL) |
| 3166 | cap_header->version = _LINUX_CAPABILITY_VERSION; | 3165 | err(-6, "cap_get_proc\n"); |
| 3167 | if (capget(cap_header, cap_data) < 0) | ||
| 3168 | err(-6, "capget(2) failed"); | ||
| 3169 | 3166 | ||
| 3170 | if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { | 3167 | if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value)) |
| 3171 | do_exit++; | 3168 | err(-6, "cap_get\n"); |
| 3169 | |||
| 3170 | if (cap_flag_value != CAP_SET) { | ||
| 3172 | warnx("capget(CAP_SYS_RAWIO) failed," | 3171 | warnx("capget(CAP_SYS_RAWIO) failed," |
| 3173 | " try \"# setcap cap_sys_rawio=ep %s\"", progname); | 3172 | " try \"# setcap cap_sys_rawio=ep %s\"", progname); |
| 3173 | return 1; | ||
| 3174 | } | 3174 | } |
| 3175 | 3175 | ||
| 3176 | if (cap_free(caps) == -1) | ||
| 3177 | err(-6, "cap_free\n"); | ||
| 3178 | |||
| 3179 | return 0; | ||
| 3180 | } | ||
| 3181 | void check_permissions(void) | ||
| 3182 | { | ||
| 3183 | int do_exit = 0; | ||
| 3184 | char pathname[32]; | ||
| 3185 | |||
| 3186 | /* check for CAP_SYS_RAWIO */ | ||
| 3187 | do_exit += check_for_cap_sys_rawio(); | ||
| 3188 | |||
| 3176 | /* test file permissions */ | 3189 | /* test file permissions */ |
| 3177 | sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); | 3190 | sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); |
| 3178 | if (euidaccess(pathname, R_OK)) { | 3191 | if (euidaccess(pathname, R_OK)) { |
| @@ -3265,6 +3278,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) · 86 unmodified lines | |||
| 3265 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ | 3278 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
| 3266 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: | 3279 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
| 3267 | case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ | 3280 | case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
| 3281 | case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
| 3268 | pkg_cstate_limits = glm_pkg_cstate_limits; | 3282 | pkg_cstate_limits = glm_pkg_cstate_limits; |
| 3269 | break; | 3283 | break; |
| 3270 | default: | 3284 | default: |
| @@ -3336,6 +3350,17 @@ int is_skx(unsigned int family, unsigned int model) · 65 unmodified lines | |||
| 3336 | } | 3350 | } |
| 3337 | return 0; | 3351 | return 0; |
| 3338 | } | 3352 | } |
| 3353 | int is_ehl(unsigned int family, unsigned int model) | ||
| 3354 | { | ||
| 3355 | if (!genuine_intel) | ||
| 3356 | return 0; | ||
| 3357 | |||
| 3358 | switch (model) { | ||
| 3359 | case INTEL_FAM6_ATOM_TREMONT: | ||
| 3360 | return 1; | ||
| 3361 | } | ||
| 3362 | return 0; | ||
| 3363 | } | ||
| 3339 | 3364 | ||
| 3340 | int has_turbo_ratio_limit(unsigned int family, unsigned int model) | 3365 | int has_turbo_ratio_limit(unsigned int family, unsigned int model) |
| 3341 | { | 3366 | { |
| @@ -3478,6 +3503,23 @@ dump_cstate_pstate_config_info(unsigned int family, unsigned int model) · 136 unmodified lines | |||
| 3478 | dump_nhm_cst_cfg(); | 3503 | dump_nhm_cst_cfg(); |
| 3479 | } | 3504 | } |
| 3480 | 3505 | ||
| 3506 | static void dump_sysfs_file(char *path) | ||
| 3507 | { | ||
| 3508 | FILE *input; | ||
| 3509 | char cpuidle_buf[64]; | ||
| 3510 | |||
| 3511 | input = fopen(path, "r"); | ||
| 3512 | if (input == NULL) { | ||
| 3513 | if (debug) | ||
| 3514 | fprintf(outf, "NSFOD %s\n", path); | ||
| 3515 | return; | ||
| 3516 | } | ||
| 3517 | if (!fgets(cpuidle_buf, sizeof(cpuidle_buf), input)) | ||
| 3518 | err(1, "%s: failed to read file", path); | ||
| 3519 | fclose(input); | ||
| 3520 | |||
| 3521 | fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf); | ||
| 3522 | } | ||
| 3481 | static void | 3523 | static void |
| 3482 | dump_sysfs_cstate_config(void) | 3524 | dump_sysfs_cstate_config(void) |
| 3483 | { | 3525 | { |
| @@ -3491,6 +3533,15 @@ dump_sysfs_cstate_config(void) · 7 unmodified lines | |||
| 3491 | if (!DO_BIC(BIC_sysfs)) | 3533 | if (!DO_BIC(BIC_sysfs)) |
| 3492 | return; | 3534 | return; |
| 3493 | 3535 | ||
| 3536 | if (access("/sys/devices/system/cpu/cpuidle", R_OK)) { | ||
| 3537 | fprintf(outf, "cpuidle not loaded\n"); | ||
| 3538 | return; | ||
| 3539 | } | ||
| 3540 | |||
| 3541 | dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver"); | ||
| 3542 | dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor"); | ||
| 3543 | dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro"); | ||
| 3544 | |||
| 3494 | for (state = 0; state < 10; ++state) { | 3545 | for (state = 0; state < 10; ++state) { |
| 3495 | 3546 | ||
| 3496 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", | 3547 | sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", |
| @@ -3894,6 +3945,20 @@ void rapl_probe_intel(unsigned int family, unsigned int model) · 397 unmodified lines | |||
| 3894 | else | 3945 | else |
| 3895 | BIC_PRESENT(BIC_PkgWatt); | 3946 | BIC_PRESENT(BIC_PkgWatt); |
| 3896 | break; | 3947 | break; |
| 3948 | case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
| 3949 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; | ||
| 3950 | if (rapl_joules) { | ||
| 3951 | BIC_PRESENT(BIC_Pkg_J); | ||
| 3952 | BIC_PRESENT(BIC_Cor_J); | ||
| 3953 | BIC_PRESENT(BIC_RAM_J); | ||
| 3954 | BIC_PRESENT(BIC_GFX_J); | ||
| 3955 | } else { | ||
| 3956 | BIC_PRESENT(BIC_PkgWatt); | ||
| 3957 | BIC_PRESENT(BIC_CorWatt); | ||
| 3958 | BIC_PRESENT(BIC_RAMWatt); | ||
| 3959 | BIC_PRESENT(BIC_GFXWatt); | ||
| 3960 | } | ||
| 3961 | break; | ||
| 3897 | case INTEL_FAM6_SKYLAKE_L: /* SKL */ | 3962 | case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
| 3898 | case INTEL_FAM6_CANNONLAKE_L: /* CNL */ | 3963 | case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
| 3899 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; | 3964 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; |
| @@ -4295,6 +4360,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) · 395 unmodified lines | |||
| 4295 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ | 4360 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
| 4296 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: | 4361 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
| 4297 | case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ | 4362 | case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
| 4363 | case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
| 4298 | return 1; | 4364 | return 1; |
| 4299 | } | 4365 | } |
| 4300 | return 0; | 4366 | return 0; |
| @@ -4324,6 +4390,7 @@ int has_c8910_msrs(unsigned int family, unsigned int model) · 23 unmodified lines | |||
| 4324 | case INTEL_FAM6_CANNONLAKE_L: /* CNL */ | 4390 | case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
| 4325 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ | 4391 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
| 4326 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: | 4392 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
| 4393 | case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
| 4327 | return 1; | 4394 | return 1; |
| 4328 | } | 4395 | } |
| 4329 | return 0; | 4396 | return 0; |
| @@ -4610,14 +4677,24 @@ unsigned int intel_model_duplicates(unsigned int model) · 280 unmodified lines | |||
| 4610 | case INTEL_FAM6_SKYLAKE: | 4677 | case INTEL_FAM6_SKYLAKE: |
| 4611 | case INTEL_FAM6_KABYLAKE_L: | 4678 | case INTEL_FAM6_KABYLAKE_L: |
| 4612 | case INTEL_FAM6_KABYLAKE: | 4679 | case INTEL_FAM6_KABYLAKE: |
| 4680 | case INTEL_FAM6_COMETLAKE_L: | ||
| 4681 | case INTEL_FAM6_COMETLAKE: | ||
| 4613 | return INTEL_FAM6_SKYLAKE_L; | 4682 | return INTEL_FAM6_SKYLAKE_L; |
| 4614 | 4683 | ||
| 4615 | case INTEL_FAM6_ICELAKE_L: | 4684 | case INTEL_FAM6_ICELAKE_L: |
| 4616 | case INTEL_FAM6_ICELAKE_NNPI: | 4685 | case INTEL_FAM6_ICELAKE_NNPI: |
| 4686 | case INTEL_FAM6_TIGERLAKE_L: | ||
| 4687 | case INTEL_FAM6_TIGERLAKE: | ||
| 4617 | return INTEL_FAM6_CANNONLAKE_L; | 4688 | return INTEL_FAM6_CANNONLAKE_L; |
| 4618 | 4689 | ||
| 4619 | case INTEL_FAM6_ATOM_TREMONT_D: | 4690 | case INTEL_FAM6_ATOM_TREMONT_D: |
| 4620 | return INTEL_FAM6_ATOM_GOLDMONT_D; | 4691 | return INTEL_FAM6_ATOM_GOLDMONT_D; |
| 4692 | |||
| 4693 | case INTEL_FAM6_ATOM_TREMONT_L: | ||
| 4694 | return INTEL_FAM6_ATOM_TREMONT; | ||
| 4695 | |||
| 4696 | case INTEL_FAM6_ICELAKE_X: | ||
| 4697 | return INTEL_FAM6_SKYLAKE_X; | ||
| 4621 | } | 4698 | } |
| 4622 | return model; | 4699 | return model; |
| 4623 | } | 4700 | } |
| @@ -4872,7 +4949,8 @@ void process_cpuid() · 248 unmodified lines | |||
| 4872 | do_slm_cstates = is_slm(family, model); | 4949 | do_slm_cstates = is_slm(family, model); |
| 4873 | do_knl_cstates = is_knl(family, model); | 4950 | do_knl_cstates = is_knl(family, model); |
| 4874 | 4951 | ||
| 4875 | if (do_slm_cstates || do_knl_cstates || is_cnl(family, model)) | 4952 | if (do_slm_cstates || do_knl_cstates || is_cnl(family, model) || |
| 4953 | is_ehl(family, model)) | ||
| 4876 | BIC_NOT_PRESENT(BIC_CPU_c3); | 4954 | BIC_NOT_PRESENT(BIC_CPU_c3); |
| 4877 | 4955 | ||
| 4878 | if (!quiet) | 4956 | if (!quiet) |
| @@ -4907,10 +4985,16 @@ void process_cpuid() · 28 unmodified lines | |||
| 4907 | else | 4985 | else |
| 4908 | BIC_NOT_PRESENT(BIC_CPU_LPI); | 4986 | BIC_NOT_PRESENT(BIC_CPU_LPI); |
| 4909 | 4987 | ||
| 4910 | if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", R_OK)) | 4988 | if (!access(sys_lpi_file_sysfs, R_OK)) { |
| 4989 | sys_lpi_file = sys_lpi_file_sysfs; | ||
| 4911 | BIC_PRESENT(BIC_SYS_LPI); | 4990 | BIC_PRESENT(BIC_SYS_LPI); |
| 4912 | else | 4991 | } else if (!access(sys_lpi_file_debugfs, R_OK)) { |
| 4992 | sys_lpi_file = sys_lpi_file_debugfs; | ||
| 4993 | BIC_PRESENT(BIC_SYS_LPI); | ||
| 4994 | } else { | ||
| 4995 | sys_lpi_file_sysfs = NULL; | ||
| 4913 | BIC_NOT_PRESENT(BIC_SYS_LPI); | 4996 | BIC_NOT_PRESENT(BIC_SYS_LPI); |
| 4997 | } | ||
| 4914 | 4998 | ||
| 4915 | if (!quiet) | 4999 | if (!quiet) |
| 4916 | decode_misc_feature_control(); | 5000 | decode_misc_feature_control(); |
| @@ -5306,7 +5390,7 @@ int get_and_dump_counters(void) · 389 unmodified lines | |||
| 5306 | } | 5390 | } |
| 5307 | 5391 | ||
| 5308 | void print_version() { | 5392 | void print_version() { |
| 5309 | fprintf(outf, "turbostat version 19.08.31" | 5393 | fprintf(outf, "turbostat version 20.03.20" |
| 5310 | " - Len Brown <lenb@kernel.org>\n"); | 5394 | " - Len Brown <lenb@kernel.org>\n"); |
| 5311 | } | 5395 | } |
| 5312 | 5396 | ||
| @@ -5323,9 +5407,9 @@ int add_counter(unsigned int msr_num, char *path, char *name, · 10 unmodified lines | |||
| 5323 | } | 5407 | } |
| 5324 | 5408 | ||
| 5325 | msrp->msr_num = msr_num; | 5409 | msrp->msr_num = msr_num; |
| 5326 | strncpy(msrp->name, name, NAME_BYTES); | 5410 | strncpy(msrp->name, name, NAME_BYTES - 1); |
| 5327 | if (path) | 5411 | if (path) |
| 5328 | strncpy(msrp->path, path, PATH_BYTES); | 5412 | strncpy(msrp->path, path, PATH_BYTES - 1); |
| 5329 | msrp->width = width; | 5413 | msrp->width = width; |
| 5330 | msrp->type = type; | 5414 | msrp->type = type; |
| 5331 | msrp->format = format; | 5415 | msrp->format = format; |
| @@ -1,8 +1,8 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | ifneq ($(O),) | 2 | ifneq ($(O),) |
| 3 | ifeq ($(origin O), command line) | 3 | ifeq ($(origin O), command line) |
| 4 | dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) | 4 | dummy := $(if $(shell cd $(PWD); test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) |
| 5 | ABSOLUTE_O := $(shell cd $(O) ; pwd) | 5 | ABSOLUTE_O := $(shell cd $(PWD); cd $(O) ; pwd) |
| 6 | OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) | 6 | OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) |
| 7 | COMMAND_O := O=$(ABSOLUTE_O) | 7 | COMMAND_O := O=$(ABSOLUTE_O) |
| 8 | ifeq ($(objtree),) | 8 | ifeq ($(objtree),) |
| @@ -33,6 +33,7 @@ TARGETS += memory-hotplug · 32 unmodified lines | |||
| 33 | TARGETS += mount | 33 | TARGETS += mount |
| 34 | TARGETS += mqueue | 34 | TARGETS += mqueue |
| 35 | TARGETS += net | 35 | TARGETS += net |
| 36 | TARGETS += net/forwarding | ||
| 36 | TARGETS += net/mptcp | 37 | TARGETS += net/mptcp |
| 37 | TARGETS += netfilter | 38 | TARGETS += netfilter |
| 38 | TARGETS += networking/timestamping | 39 | TARGETS += networking/timestamping |
| @@ -0,0 +1,60 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | #include <test_progs.h> | ||
| 3 | #include <stdio.h> | ||
| 4 | #include <stdlib.h> | ||
| 5 | #include <sys/mman.h> | ||
| 6 | #include <pthread.h> | ||
| 7 | #include <sys/types.h> | ||
| 8 | #include <sys/stat.h> | ||
| 9 | #include <fcntl.h> | ||
| 10 | #include "test_send_signal_kern.skel.h" | ||
| 11 | |||
| 12 | static void sigusr1_handler(int signum) | ||
| 13 | { | ||
| 14 | } | ||
| 15 | |||
| 16 | #define THREAD_COUNT 100 | ||
| 17 | |||
| 18 | static void *worker(void *p) | ||
| 19 | { | ||
| 20 | int i; | ||
| 21 | |||
| 22 | for ( i = 0; i < 1000; i++) | ||
| 23 | usleep(1); | ||
| 24 | |||
| 25 | return NULL; | ||
| 26 | } | ||
| 27 | |||
| 28 | void test_send_signal_sched_switch(void) | ||
| 29 | { | ||
| 30 | struct test_send_signal_kern *skel; | ||
| 31 | pthread_t threads[THREAD_COUNT]; | ||
| 32 | u32 duration = 0; | ||
| 33 | int i, err; | ||
| 34 | |||
| 35 | signal(SIGUSR1, sigusr1_handler); | ||
| 36 | |||
| 37 | skel = test_send_signal_kern__open_and_load(); | ||
| 38 | if (CHECK(!skel, "skel_open_and_load", "skeleton open_and_load failed\n")) | ||
| 39 | return; | ||
| 40 | |||
| 41 | skel->bss->pid = getpid(); | ||
| 42 | skel->bss->sig = SIGUSR1; | ||
| 43 | |||
| 44 | err = test_send_signal_kern__attach(skel); | ||
| 45 | if (CHECK(err, "skel_attach", "skeleton attach failed\n")) | ||
| 46 | goto destroy_skel; | ||
| 47 | |||
| 48 | for (i = 0; i < THREAD_COUNT; i++) { | ||
| 49 | err = pthread_create(threads + i, NULL, worker, NULL); | ||
| 50 | if (CHECK(err, "pthread_create", "Error creating thread, %s\n", | ||
| 51 | strerror(errno))) | ||
| 52 | goto destroy_skel; | ||
| 53 | } | ||
| 54 | |||
| 55 | for (i = 0; i < THREAD_COUNT; i++) | ||
| 56 | pthread_join(threads[i], NULL); | ||
| 57 | |||
| 58 | destroy_skel: | ||
| 59 | test_send_signal_kern__destroy(skel); | ||
| 60 | } | ||
| @@ -31,6 +31,12 @@ int send_signal_tp(void *ctx) · 30 unmodified lines | |||
| 31 | return bpf_send_signal_test(ctx); | 31 | return bpf_send_signal_test(ctx); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | SEC("tracepoint/sched/sched_switch") | ||
| 35 | int send_signal_tp_sched(void *ctx) | ||
| 36 | { | ||
| 37 | return bpf_send_signal_test(ctx); | ||
| 38 | } | ||
| 39 | |||
| 34 | SEC("perf_event") | 40 | SEC("perf_event") |
| 35 | int send_signal_perf(void *ctx) | 41 | int send_signal_perf(void *ctx) |
| 36 | { | 42 | { |
| @@ -1062,6 +1062,48 @@ static struct btf_raw_test raw_tests[] = { · 1061 unmodified lines | |||
| 1062 | .err_str = "Member exceeds struct_size", | 1062 | .err_str = "Member exceeds struct_size", |
| 1063 | }, | 1063 | }, |
| 1064 | 1064 | ||
| 1065 | /* Test member unexceeds the size of struct | ||
| 1066 | * | ||
| 1067 | * enum E { | ||
| 1068 | * E0, | ||
| 1069 | * E1, | ||
| 1070 | * }; | ||
| 1071 | * | ||
| 1072 | * struct A { | ||
| 1073 | * char m; | ||
| 1074 | * enum E __attribute__((packed)) n; | ||
| 1075 | * }; | ||
| 1076 | */ | ||
| 1077 | { | ||
| 1078 | .descr = "size check test #5", | ||
| 1079 | .raw_types = { | ||
| 1080 | /* int */ /* [1] */ | ||
| 1081 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)), | ||
| 1082 | /* char */ /* [2] */ | ||
| 1083 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), | ||
| 1084 | /* enum E { */ /* [3] */ | ||
| 1085 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 1), | ||
| 1086 | BTF_ENUM_ENC(NAME_TBD, 0), | ||
| 1087 | BTF_ENUM_ENC(NAME_TBD, 1), | ||
| 1088 | /* } */ | ||
| 1089 | /* struct A { */ /* [4] */ | ||
| 1090 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 2), | ||
| 1091 | BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* char m; */ | ||
| 1092 | BTF_MEMBER_ENC(NAME_TBD, 3, 8),/* enum E __attribute__((packed)) n; */ | ||
| 1093 | /* } */ | ||
| 1094 | BTF_END_RAW, | ||
| 1095 | }, | ||
| 1096 | .str_sec = "\0E\0E0\0E1\0A\0m\0n", | ||
| 1097 | .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"), | ||
| 1098 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
| 1099 | .map_name = "size_check5_map", | ||
| 1100 | .key_size = sizeof(int), | ||
| 1101 | .value_size = 2, | ||
| 1102 | .key_type_id = 1, | ||
| 1103 | .value_type_id = 4, | ||
| 1104 | .max_entries = 4, | ||
| 1105 | }, | ||
| 1106 | |||
| 1065 | /* typedef const void * const_void_ptr; | 1107 | /* typedef const void * const_void_ptr; |
| 1066 | * struct A { | 1108 | * struct A { |
| 1067 | * const_void_ptr m; | 1109 | * const_void_ptr m; |
| @@ -61,6 +61,21 @@ · 60 unmodified lines | |||
| 61 | }, | 61 | }, |
| 62 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 62 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 63 | }, | 63 | }, |
| 64 | { | ||
| 65 | "jset32: ignores upper bits", | ||
| 66 | .insns = { | ||
| 67 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 68 | BPF_LD_IMM64(BPF_REG_7, 0x8000000000000000), | ||
| 69 | BPF_LD_IMM64(BPF_REG_8, 0x8000000000000000), | ||
| 70 | BPF_JMP_REG(BPF_JSET, BPF_REG_7, BPF_REG_8, 1), | ||
| 71 | BPF_EXIT_INSN(), | ||
| 72 | BPF_JMP32_REG(BPF_JSET, BPF_REG_7, BPF_REG_8, 1), | ||
| 73 | BPF_MOV64_IMM(BPF_REG_0, 2), | ||
| 74 | BPF_EXIT_INSN(), | ||
| 75 | }, | ||
| 76 | .result = ACCEPT, | ||
| 77 | .retval = 2, | ||
| 78 | }, | ||
| 64 | { | 79 | { |
| 65 | "jset32: min/max deduction", | 80 | "jset32: min/max deduction", |
| 66 | .insns = { | 81 | .insns = { |
| @@ -11,7 +11,9 @@ TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh msg_zerocopy.sh psock_snd.sh · 10 unmodified lines | |||
| 11 | TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh | 11 | TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh |
| 12 | TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh | 12 | TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh |
| 13 | TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh traceroute.sh | 13 | TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh traceroute.sh |
| 14 | TEST_PROGS += fin_ack_lat.sh | 14 | TEST_PROGS += fin_ack_lat.sh fib_nexthop_multiprefix.sh fib_nexthops.sh |
| 15 | TEST_PROGS += altnames.sh icmp_redirect.sh ip6_gre_headroom.sh | ||
| 16 | TEST_PROGS += route_localnet.sh | ||
| 15 | TEST_PROGS += reuseaddr_ports_exhausted.sh | 17 | TEST_PROGS += reuseaddr_ports_exhausted.sh |
| 16 | TEST_PROGS_EXTENDED := in_netns.sh | 18 | TEST_PROGS_EXTENDED := in_netns.sh |
| 17 | TEST_GEN_FILES = socket nettest | 19 | TEST_GEN_FILES = socket nettest |
| @@ -0,0 +1,76 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0+ OR MIT | ||
| 2 | |||
| 3 | TEST_PROGS = bridge_igmp.sh \ | ||
| 4 | bridge_port_isolation.sh \ | ||
| 5 | bridge_sticky_fdb.sh \ | ||
| 6 | bridge_vlan_aware.sh \ | ||
| 7 | bridge_vlan_unaware.sh \ | ||
| 8 | ethtool.sh \ | ||
| 9 | gre_inner_v4_multipath.sh \ | ||
| 10 | gre_inner_v6_multipath.sh \ | ||
| 11 | gre_multipath.sh \ | ||
| 12 | ip6gre_inner_v4_multipath.sh \ | ||
| 13 | ip6gre_inner_v6_multipath.sh \ | ||
| 14 | ipip_flat_gre_key.sh \ | ||
| 15 | ipip_flat_gre_keys.sh \ | ||
| 16 | ipip_flat_gre.sh \ | ||
| 17 | ipip_hier_gre_key.sh \ | ||
| 18 | ipip_hier_gre_keys.sh \ | ||
| 19 | ipip_hier_gre.sh \ | ||
| 20 | loopback.sh \ | ||
| 21 | mirror_gre_bound.sh \ | ||
| 22 | mirror_gre_bridge_1d.sh \ | ||
| 23 | mirror_gre_bridge_1d_vlan.sh \ | ||
| 24 | mirror_gre_bridge_1q_lag.sh \ | ||
| 25 | mirror_gre_bridge_1q.sh \ | ||
| 26 | mirror_gre_changes.sh \ | ||
| 27 | mirror_gre_flower.sh \ | ||
| 28 | mirror_gre_lag_lacp.sh \ | ||
| 29 | mirror_gre_neigh.sh \ | ||
| 30 | mirror_gre_nh.sh \ | ||
| 31 | mirror_gre.sh \ | ||
| 32 | mirror_gre_vlan_bridge_1q.sh \ | ||
| 33 | mirror_gre_vlan.sh \ | ||
| 34 | mirror_vlan.sh \ | ||
| 35 | router_bridge.sh \ | ||
| 36 | router_bridge_vlan.sh \ | ||
| 37 | router_broadcast.sh \ | ||
| 38 | router_mpath_nh.sh \ | ||
| 39 | router_multicast.sh \ | ||
| 40 | router_multipath.sh \ | ||
| 41 | router.sh \ | ||
| 42 | router_vid_1.sh \ | ||
| 43 | sch_ets.sh \ | ||
| 44 | sch_tbf_ets.sh \ | ||
| 45 | sch_tbf_prio.sh \ | ||
| 46 | sch_tbf_root.sh \ | ||
| 47 | tc_actions.sh \ | ||
| 48 | tc_chains.sh \ | ||
| 49 | tc_flower_router.sh \ | ||
| 50 | tc_flower.sh \ | ||
| 51 | tc_shblocks.sh \ | ||
| 52 | tc_vlan_modify.sh \ | ||
| 53 | vxlan_asymmetric.sh \ | ||
| 54 | vxlan_bridge_1d_port_8472.sh \ | ||
| 55 | vxlan_bridge_1d.sh \ | ||
| 56 | vxlan_bridge_1q_port_8472.sh \ | ||
| 57 | vxlan_bridge_1q.sh \ | ||
| 58 | vxlan_symmetric.sh | ||
| 59 | |||
| 60 | TEST_PROGS_EXTENDED := devlink_lib.sh \ | ||
| 61 | ethtool_lib.sh \ | ||
| 62 | fib_offload_lib.sh \ | ||
| 63 | forwarding.config.sample \ | ||
| 64 | ipip_lib.sh \ | ||
| 65 | lib.sh \ | ||
| 66 | mirror_gre_lib.sh \ | ||
| 67 | mirror_gre_topo_lib.sh \ | ||
| 68 | mirror_lib.sh \ | ||
| 69 | mirror_topo_lib.sh \ | ||
| 70 | sch_ets_core.sh \ | ||
| 71 | sch_ets_tests.sh \ | ||
| 72 | sch_tbf_core.sh \ | ||
| 73 | sch_tbf_etsprio.sh \ | ||
| 74 | tc_common.sh | ||
| 75 | |||
| 76 | include ../../lib.mk | ||
File mode changed from 100755 to 100644.
| @@ -21,6 +21,10 @@ · 20 unmodified lines | |||
| 21 | #include <sys/socket.h> | 21 | #include <sys/socket.h> |
| 22 | #include <unistd.h> | 22 | #include <unistd.h> |
| 23 | 23 | ||
| 24 | #ifndef SOL_DCCP | ||
| 25 | #define SOL_DCCP 269 | ||
| 26 | #endif | ||
| 27 | |||
| 24 | static const char *IP4_ADDR = "127.0.0.1"; | 28 | static const char *IP4_ADDR = "127.0.0.1"; |
| 25 | static const char *IP6_ADDR = "::1"; | 29 | static const char *IP6_ADDR = "::1"; |
| 26 | static const char *IP4_MAPPED6 = "::ffff:127.0.0.1"; | 30 | static const char *IP4_MAPPED6 = "::ffff:127.0.0.1"; |
| @@ -3,6 +3,10 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh \ | 4 | TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh \ |
| 5 | conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh \ | 5 | conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh \ |
| 6 | nft_concat_range.sh | 6 | nft_concat_range.sh \ |
| 7 | nft_queue.sh | ||
| 8 | |||
| 9 | LDLIBS = -lmnl | ||
| 10 | TEST_GEN_FILES = nf-queue | ||
| 7 | 11 | ||
| 8 | include ../lib.mk | 12 | include ../lib.mk |
| @@ -1,2 +1,8 @@ | |||
| 1 | CONFIG_NET_NS=y | 1 | CONFIG_NET_NS=y |
| 2 | CONFIG_NF_TABLES_INET=y | 2 | CONFIG_NF_TABLES_INET=y |
| 3 | CONFIG_NFT_QUEUE=m | ||
| 4 | CONFIG_NFT_NAT=m | ||
| 5 | CONFIG_NFT_REDIR=m | ||
| 6 | CONFIG_NFT_MASQ=m | ||
| 7 | CONFIG_NFT_FLOW_OFFLOAD=m | ||
| 8 | CONFIG_NF_CT_NETLINK=m | ||
| @@ -0,0 +1,352 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | #include <errno.h> | ||
| 4 | #include <stdbool.h> | ||
| 5 | #include <stdio.h> | ||
| 6 | #include <stdint.h> | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <unistd.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include <time.h> | ||
| 11 | #include <arpa/inet.h> | ||
| 12 | |||
| 13 | #include <libmnl/libmnl.h> | ||
| 14 | #include <linux/netfilter.h> | ||
| 15 | #include <linux/netfilter/nfnetlink.h> | ||
| 16 | #include <linux/netfilter/nfnetlink_queue.h> | ||
| 17 | |||
| 18 | struct options { | ||
| 19 | bool count_packets; | ||
| 20 | int verbose; | ||
| 21 | unsigned int queue_num; | ||
| 22 | unsigned int timeout; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static unsigned int queue_stats[5]; | ||
| 26 | static struct options opts; | ||
| 27 | |||
| 28 | static void help(const char *p) | ||
| 29 | { | ||
| 30 | printf("Usage: %s [-c|-v [-vv] ] [-t timeout] [-q queue_num]\n", p); | ||
| 31 | } | ||
| 32 | |||
| 33 | static int parse_attr_cb(const struct nlattr *attr, void *data) | ||
| 34 | { | ||
| 35 | const struct nlattr **tb = data; | ||
| 36 | int type = mnl_attr_get_type(attr); | ||
| 37 | |||
| 38 | /* skip unsupported attribute in user-space */ | ||
| 39 | if (mnl_attr_type_valid(attr, NFQA_MAX) < 0) | ||
| 40 | return MNL_CB_OK; | ||
| 41 | |||
| 42 | switch (type) { | ||
| 43 | case NFQA_MARK: | ||
| 44 | case NFQA_IFINDEX_INDEV: | ||
| 45 | case NFQA_IFINDEX_OUTDEV: | ||
| 46 | case NFQA_IFINDEX_PHYSINDEV: | ||
| 47 | case NFQA_IFINDEX_PHYSOUTDEV: | ||
| 48 | if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { | ||
| 49 | perror("mnl_attr_validate"); | ||
| 50 | return MNL_CB_ERROR; | ||
| 51 | } | ||
| 52 | break; | ||
| 53 | case NFQA_TIMESTAMP: | ||
| 54 | if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, | ||
| 55 | sizeof(struct nfqnl_msg_packet_timestamp)) < 0) { | ||
| 56 | perror("mnl_attr_validate2"); | ||
| 57 | return MNL_CB_ERROR; | ||
| 58 | } | ||
| 59 | break; | ||
| 60 | case NFQA_HWADDR: | ||
| 61 | if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, | ||
| 62 | sizeof(struct nfqnl_msg_packet_hw)) < 0) { | ||
| 63 | perror("mnl_attr_validate2"); | ||
| 64 | return MNL_CB_ERROR; | ||
| 65 | } | ||
| 66 | break; | ||
| 67 | case NFQA_PAYLOAD: | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | tb[type] = attr; | ||
| 71 | return MNL_CB_OK; | ||
| 72 | } | ||
| 73 | |||
| 74 | static int queue_cb(const struct nlmsghdr *nlh, void *data) | ||
| 75 | { | ||
| 76 | struct nlattr *tb[NFQA_MAX+1] = { 0 }; | ||
| 77 | struct nfqnl_msg_packet_hdr *ph = NULL; | ||
| 78 | uint32_t id = 0; | ||
| 79 | |||
| 80 | (void)data; | ||
| 81 | |||
| 82 | mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb); | ||
| 83 | if (tb[NFQA_PACKET_HDR]) { | ||
| 84 | ph = mnl_attr_get_payload(tb[NFQA_PACKET_HDR]); | ||
| 85 | id = ntohl(ph->packet_id); | ||
| 86 | |||
| 87 | if (opts.verbose > 0) | ||
| 88 | printf("packet hook=%u, hwproto 0x%x", | ||
| 89 | ntohs(ph->hw_protocol), ph->hook); | ||
| 90 | |||
| 91 | if (ph->hook >= 5) { | ||
| 92 | fprintf(stderr, "Unknown hook %d\n", ph->hook); | ||
| 93 | return MNL_CB_ERROR; | ||
| 94 | } | ||
| 95 | |||
| 96 | if (opts.verbose > 0) { | ||
| 97 | uint32_t skbinfo = 0; | ||
| 98 | |||
| 99 | if (tb[NFQA_SKB_INFO]) | ||
| 100 | skbinfo = ntohl(mnl_attr_get_u32(tb[NFQA_SKB_INFO])); | ||
| 101 | if (skbinfo & NFQA_SKB_CSUMNOTREADY) | ||
| 102 | printf(" csumnotready"); | ||
| 103 | if (skbinfo & NFQA_SKB_GSO) | ||
| 104 | printf(" gso"); | ||
| 105 | if (skbinfo & NFQA_SKB_CSUM_NOTVERIFIED) | ||
| 106 | printf(" csumnotverified"); | ||
| 107 | puts(""); | ||
| 108 | } | ||
| 109 | |||
| 110 | if (opts.count_packets) | ||
| 111 | queue_stats[ph->hook]++; | ||
| 112 | } | ||
| 113 | |||
| 114 | return MNL_CB_OK + id; | ||
| 115 | } | ||
| 116 | |||
| 117 | static struct nlmsghdr * | ||
| 118 | nfq_build_cfg_request(char *buf, uint8_t command, int queue_num) | ||
| 119 | { | ||
| 120 | struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); | ||
| 121 | struct nfqnl_msg_config_cmd cmd = { | ||
| 122 | .command = command, | ||
| 123 | .pf = htons(AF_INET), | ||
| 124 | }; | ||
| 125 | struct nfgenmsg *nfg; | ||
| 126 | |||
| 127 | nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG; | ||
| 128 | nlh->nlmsg_flags = NLM_F_REQUEST; | ||
| 129 | |||
| 130 | nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); | ||
| 131 | |||
| 132 | nfg->nfgen_family = AF_UNSPEC; | ||
| 133 | nfg->version = NFNETLINK_V0; | ||
| 134 | nfg->res_id = htons(queue_num); | ||
| 135 | |||
| 136 | mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(cmd), &cmd); | ||
| 137 | |||
| 138 | return nlh; | ||
| 139 | } | ||
| 140 | |||
| 141 | static struct nlmsghdr * | ||
| 142 | nfq_build_cfg_params(char *buf, uint8_t mode, int range, int queue_num) | ||
| 143 | { | ||
| 144 | struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); | ||
| 145 | struct nfqnl_msg_config_params params = { | ||
| 146 | .copy_range = htonl(range), | ||
| 147 | .copy_mode = mode, | ||
| 148 | }; | ||
| 149 | struct nfgenmsg *nfg; | ||
| 150 | |||
| 151 | nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG; | ||
| 152 | nlh->nlmsg_flags = NLM_F_REQUEST; | ||
| 153 | |||
| 154 | nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); | ||
| 155 | nfg->nfgen_family = AF_UNSPEC; | ||
| 156 | nfg->version = NFNETLINK_V0; | ||
| 157 | nfg->res_id = htons(queue_num); | ||
| 158 | |||
| 159 | mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), ¶ms); | ||
| 160 | |||
| 161 | return nlh; | ||
| 162 | } | ||
| 163 | |||
| 164 | static struct nlmsghdr * | ||
| 165 | nfq_build_verdict(char *buf, int id, int queue_num, int verd) | ||
| 166 | { | ||
| 167 | struct nfqnl_msg_verdict_hdr vh = { | ||
| 168 | .verdict = htonl(verd), | ||
| 169 | .id = htonl(id), | ||
| 170 | }; | ||
| 171 | struct nlmsghdr *nlh; | ||
| 172 | struct nfgenmsg *nfg; | ||
| 173 | |||
| 174 | nlh = mnl_nlmsg_put_header(buf); | ||
| 175 | nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT; | ||
| 176 | nlh->nlmsg_flags = NLM_F_REQUEST; | ||
| 177 | nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg)); | ||
| 178 | nfg->nfgen_family = AF_UNSPEC; | ||
| 179 | nfg->version = NFNETLINK_V0; | ||
| 180 | nfg->res_id = htons(queue_num); | ||
| 181 | |||
| 182 | mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh); | ||
| 183 | |||
| 184 | return nlh; | ||
| 185 | } | ||
| 186 | |||
| 187 | static void print_stats(void) | ||
| 188 | { | ||
| 189 | unsigned int last, total; | ||
| 190 | int i; | ||
| 191 | |||
| 192 | if (!opts.count_packets) | ||
| 193 | return; | ||
| 194 | |||
| 195 | total = 0; | ||
| 196 | last = queue_stats[0]; | ||
| 197 | |||
| 198 | for (i = 0; i < 5; i++) { | ||
| 199 | printf("hook %d packets %08u\n", i, queue_stats[i]); | ||
| 200 | last = queue_stats[i]; | ||
| 201 | total += last; | ||
| 202 | } | ||
| 203 | |||
| 204 | printf("%u packets total\n", total); | ||
| 205 | } | ||
| 206 | |||
| 207 | struct mnl_socket *open_queue(void) | ||
| 208 | { | ||
| 209 | char buf[MNL_SOCKET_BUFFER_SIZE]; | ||
| 210 | unsigned int queue_num; | ||
| 211 | struct mnl_socket *nl; | ||
| 212 | struct nlmsghdr *nlh; | ||
| 213 | struct timeval tv; | ||
| 214 | uint32_t flags; | ||
| 215 | |||
| 216 | nl = mnl_socket_open(NETLINK_NETFILTER); | ||
| 217 | if (nl == NULL) { | ||
| 218 | perror("mnl_socket_open"); | ||
| 219 | exit(EXIT_FAILURE); | ||
| 220 | } | ||
| 221 | |||
| 222 | if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { | ||
| 223 | perror("mnl_socket_bind"); | ||
| 224 | exit(EXIT_FAILURE); | ||
| 225 | } | ||
| 226 | |||
| 227 | queue_num = opts.queue_num; | ||
| 228 | nlh = nfq_build_cfg_request(buf, NFQNL_CFG_CMD_BIND, queue_num); | ||
| 229 | |||
| 230 | if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { | ||
| 231 | perror("mnl_socket_sendto"); | ||
| 232 | exit(EXIT_FAILURE); | ||
| 233 | } | ||
| 234 | |||
| 235 | nlh = nfq_build_cfg_params(buf, NFQNL_COPY_PACKET, 0xFFFF, queue_num); | ||
| 236 | |||
| 237 | flags = NFQA_CFG_F_GSO | NFQA_CFG_F_UID_GID; | ||
| 238 | mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(flags)); | ||
| 239 | mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(flags)); | ||
| 240 | |||
| 241 | if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { | ||
| 242 | perror("mnl_socket_sendto"); | ||
| 243 | exit(EXIT_FAILURE); | ||
| 244 | } | ||
| 245 | |||
| 246 | memset(&tv, 0, sizeof(tv)); | ||
| 247 | tv.tv_sec = opts.timeout; | ||
| 248 | if (opts.timeout && setsockopt(mnl_socket_get_fd(nl), | ||
| 249 | SOL_SOCKET, SO_RCVTIMEO, | ||
| 250 | &tv, sizeof(tv))) { | ||
| 251 | perror("setsockopt(SO_RCVTIMEO)"); | ||
| 252 | exit(EXIT_FAILURE); | ||
| 253 | } | ||
| 254 | |||
| 255 | return nl; | ||
| 256 | } | ||
| 257 | |||
| 258 | static int mainloop(void) | ||
| 259 | { | ||
| 260 | unsigned int buflen = 64 * 1024 + MNL_SOCKET_BUFFER_SIZE; | ||
| 261 | struct mnl_socket *nl; | ||
| 262 | struct nlmsghdr *nlh; | ||
| 263 | unsigned int portid; | ||
| 264 | char *buf; | ||
| 265 | int ret; | ||
| 266 | |||
| 267 | buf = malloc(buflen); | ||
| 268 | if (!buf) { | ||
| 269 | perror("malloc"); | ||
| 270 | exit(EXIT_FAILURE); | ||
| 271 | } | ||
| 272 | |||
| 273 | nl = open_queue(); | ||
| 274 | portid = mnl_socket_get_portid(nl); | ||
| 275 | |||
| 276 | for (;;) { | ||
| 277 | uint32_t id; | ||
| 278 | |||
| 279 | ret = mnl_socket_recvfrom(nl, buf, buflen); | ||
| 280 | if (ret == -1) { | ||
| 281 | if (errno == ENOBUFS) | ||
| 282 | continue; | ||
| 283 | |||
| 284 | if (errno == EAGAIN) { | ||
| 285 | errno = 0; | ||
| 286 | ret = 0; | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | |||
| 290 | perror("mnl_socket_recvfrom"); | ||
| 291 | exit(EXIT_FAILURE); | ||
| 292 | } | ||
| 293 | |||
| 294 | ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL); | ||
| 295 | if (ret < 0) { | ||
| 296 | perror("mnl_cb_run"); | ||
| 297 | exit(EXIT_FAILURE); | ||
| 298 | } | ||
| 299 | |||
| 300 | id = ret - MNL_CB_OK; | ||
| 301 | nlh = nfq_build_verdict(buf, id, opts.queue_num, NF_ACCEPT); | ||
| 302 | if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { | ||
| 303 | perror("mnl_socket_sendto"); | ||
| 304 | exit(EXIT_FAILURE); | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | mnl_socket_close(nl); | ||
| 309 | |||
| 310 | return ret; | ||
| 311 | } | ||
| 312 | |||
| 313 | static void parse_opts(int argc, char **argv) | ||
| 314 | { | ||
| 315 | int c; | ||
| 316 | |||
| 317 | while ((c = getopt(argc, argv, "chvt:q:")) != -1) { | ||
| 318 | switch (c) { | ||
| 319 | case 'c': | ||
| 320 | opts.count_packets = true; | ||
| 321 | break; | ||
| 322 | case 'h': | ||
| 323 | help(argv[0]); | ||
| 324 | exit(0); | ||
| 325 | break; | ||
| 326 | case 'q': | ||
| 327 | opts.queue_num = atoi(optarg); | ||
| 328 | if (opts.queue_num > 0xffff) | ||
| 329 | opts.queue_num = 0; | ||
| 330 | break; | ||
| 331 | case 't': | ||
| 332 | opts.timeout = atoi(optarg); | ||
| 333 | break; | ||
| 334 | case 'v': | ||
| 335 | opts.verbose++; | ||
| 336 | break; | ||
| 337 | } | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 341 | int main(int argc, char *argv[]) | ||
| 342 | { | ||
| 343 | int ret; | ||
| 344 | |||
| 345 | parse_opts(argc, argv); | ||
| 346 | |||
| 347 | ret = mainloop(); | ||
| 348 | if (opts.count_packets) | ||
| 349 | print_stats(); | ||
| 350 | |||
| 351 | return ret; | ||
| 352 | } | ||
| @@ -0,0 +1,332 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # | ||
| 3 | # This tests nf_queue: | ||
| 4 | # 1. can process packets from all hooks | ||
| 5 | # 2. support running nfqueue from more than one base chain | ||
| 6 | # | ||
| 7 | # Kselftest framework requirement - SKIP code is 4. | ||
| 8 | ksft_skip=4 | ||
| 9 | ret=0 | ||
| 10 | |||
| 11 | sfx=$(mktemp -u "XXXXXXXX") | ||
| 12 | ns1="ns1-$sfx" | ||
| 13 | ns2="ns2-$sfx" | ||
| 14 | nsrouter="nsrouter-$sfx" | ||
| 15 | |||
| 16 | cleanup() | ||
| 17 | { | ||
| 18 | ip netns del ${ns1} | ||
| 19 | ip netns del ${ns2} | ||
| 20 | ip netns del ${nsrouter} | ||
| 21 | rm -f "$TMPFILE0" | ||
| 22 | rm -f "$TMPFILE1" | ||
| 23 | } | ||
| 24 | |||
| 25 | nft --version > /dev/null 2>&1 | ||
| 26 | if [ $? -ne 0 ];then | ||
| 27 | echo "SKIP: Could not run test without nft tool" | ||
| 28 | exit $ksft_skip | ||
| 29 | fi | ||
| 30 | |||
| 31 | ip -Version > /dev/null 2>&1 | ||
| 32 | if [ $? -ne 0 ];then | ||
| 33 | echo "SKIP: Could not run test without ip tool" | ||
| 34 | exit $ksft_skip | ||
| 35 | fi | ||
| 36 | |||
| 37 | ip netns add ${nsrouter} | ||
| 38 | if [ $? -ne 0 ];then | ||
| 39 | echo "SKIP: Could not create net namespace" | ||
| 40 | exit $ksft_skip | ||
| 41 | fi | ||
| 42 | |||
| 43 | TMPFILE0=$(mktemp) | ||
| 44 | TMPFILE1=$(mktemp) | ||
| 45 | trap cleanup EXIT | ||
| 46 | |||
| 47 | ip netns add ${ns1} | ||
| 48 | ip netns add ${ns2} | ||
| 49 | |||
| 50 | ip link add veth0 netns ${nsrouter} type veth peer name eth0 netns ${ns1} > /dev/null 2>&1 | ||
| 51 | if [ $? -ne 0 ];then | ||
| 52 | echo "SKIP: No virtual ethernet pair device support in kernel" | ||
| 53 | exit $ksft_skip | ||
| 54 | fi | ||
| 55 | ip link add veth1 netns ${nsrouter} type veth peer name eth0 netns ${ns2} | ||
| 56 | |||
| 57 | ip -net ${nsrouter} link set lo up | ||
| 58 | ip -net ${nsrouter} link set veth0 up | ||
| 59 | ip -net ${nsrouter} addr add 10.0.1.1/24 dev veth0 | ||
| 60 | ip -net ${nsrouter} addr add dead:1::1/64 dev veth0 | ||
| 61 | |||
| 62 | ip -net ${nsrouter} link set veth1 up | ||
| 63 | ip -net ${nsrouter} addr add 10.0.2.1/24 dev veth1 | ||
| 64 | ip -net ${nsrouter} addr add dead:2::1/64 dev veth1 | ||
| 65 | |||
| 66 | ip -net ${ns1} link set lo up | ||
| 67 | ip -net ${ns1} link set eth0 up | ||
| 68 | |||
| 69 | ip -net ${ns2} link set lo up | ||
| 70 | ip -net ${ns2} link set eth0 up | ||
| 71 | |||
| 72 | ip -net ${ns1} addr add 10.0.1.99/24 dev eth0 | ||
| 73 | ip -net ${ns1} addr add dead:1::99/64 dev eth0 | ||
| 74 | ip -net ${ns1} route add default via 10.0.1.1 | ||
| 75 | ip -net ${ns1} route add default via dead:1::1 | ||
| 76 | |||
| 77 | ip -net ${ns2} addr add 10.0.2.99/24 dev eth0 | ||
| 78 | ip -net ${ns2} addr add dead:2::99/64 dev eth0 | ||
| 79 | ip -net ${ns2} route add default via 10.0.2.1 | ||
| 80 | ip -net ${ns2} route add default via dead:2::1 | ||
| 81 | |||
| 82 | load_ruleset() { | ||
| 83 | local name=$1 | ||
| 84 | local prio=$2 | ||
| 85 | |||
| 86 | ip netns exec ${nsrouter} nft -f - <<EOF | ||
| 87 | table inet $name { | ||
| 88 | chain nfq { | ||
| 89 | ip protocol icmp queue bypass | ||
| 90 | icmpv6 type { "echo-request", "echo-reply" } queue num 1 bypass | ||
| 91 | } | ||
| 92 | chain pre { | ||
| 93 | type filter hook prerouting priority $prio; policy accept; | ||
| 94 | jump nfq | ||
| 95 | } | ||
| 96 | chain input { | ||
| 97 | type filter hook input priority $prio; policy accept; | ||
| 98 | jump nfq | ||
| 99 | } | ||
| 100 | chain forward { | ||
| 101 | type filter hook forward priority $prio; policy accept; | ||
| 102 | tcp dport 12345 queue num 2 | ||
| 103 | jump nfq | ||
| 104 | } | ||
| 105 | chain output { | ||
| 106 | type filter hook output priority $prio; policy accept; | ||
| 107 | tcp dport 12345 queue num 3 | ||
| 108 | jump nfq | ||
| 109 | } | ||
| 110 | chain post { | ||
| 111 | type filter hook postrouting priority $prio; policy accept; | ||
| 112 | jump nfq | ||
| 113 | } | ||
| 114 | } | ||
| 115 | EOF | ||
| 116 | } | ||
| 117 | |||
| 118 | load_counter_ruleset() { | ||
| 119 | local prio=$1 | ||
| 120 | |||
| 121 | ip netns exec ${nsrouter} nft -f - <<EOF | ||
| 122 | table inet countrules { | ||
| 123 | chain pre { | ||
| 124 | type filter hook prerouting priority $prio; policy accept; | ||
| 125 | counter | ||
| 126 | } | ||
| 127 | chain input { | ||
| 128 | type filter hook input priority $prio; policy accept; | ||
| 129 | counter | ||
| 130 | } | ||
| 131 | chain forward { | ||
| 132 | type filter hook forward priority $prio; policy accept; | ||
| 133 | counter | ||
| 134 | } | ||
| 135 | chain output { | ||
| 136 | type filter hook output priority $prio; policy accept; | ||
| 137 | counter | ||
| 138 | } | ||
| 139 | chain post { | ||
| 140 | type filter hook postrouting priority $prio; policy accept; | ||
| 141 | counter | ||
| 142 | } | ||
| 143 | } | ||
| 144 | EOF | ||
| 145 | } | ||
| 146 | |||
| 147 | test_ping() { | ||
| 148 | ip netns exec ${ns1} ping -c 1 -q 10.0.2.99 > /dev/null | ||
| 149 | if [ $? -ne 0 ];then | ||
| 150 | return 1 | ||
| 151 | fi | ||
| 152 | |||
| 153 | ip netns exec ${ns1} ping -c 1 -q dead:2::99 > /dev/null | ||
| 154 | if [ $? -ne 0 ];then | ||
| 155 | return 1 | ||
| 156 | fi | ||
| 157 | |||
| 158 | return 0 | ||
| 159 | } | ||
| 160 | |||
| 161 | test_ping_router() { | ||
| 162 | ip netns exec ${ns1} ping -c 1 -q 10.0.2.1 > /dev/null | ||
| 163 | if [ $? -ne 0 ];then | ||
| 164 | return 1 | ||
| 165 | fi | ||
| 166 | |||
| 167 | ip netns exec ${ns1} ping -c 1 -q dead:2::1 > /dev/null | ||
| 168 | if [ $? -ne 0 ];then | ||
| 169 | return 1 | ||
| 170 | fi | ||
| 171 | |||
| 172 | return 0 | ||
| 173 | } | ||
| 174 | |||
| 175 | test_queue_blackhole() { | ||
| 176 | local proto=$1 | ||
| 177 | |||
| 178 | ip netns exec ${nsrouter} nft -f - <<EOF | ||
| 179 | table $proto blackh { | ||
| 180 | chain forward { | ||
| 181 | type filter hook forward priority 0; policy accept; | ||
| 182 | queue num 600 | ||
| 183 | } | ||
| 184 | } | ||
| 185 | EOF | ||
| 186 | if [ $proto = "ip" ] ;then | ||
| 187 | ip netns exec ${ns1} ping -c 1 -q 10.0.2.99 > /dev/null | ||
| 188 | lret=$? | ||
| 189 | elif [ $proto = "ip6" ]; then | ||
| 190 | ip netns exec ${ns1} ping -c 1 -q dead:2::99 > /dev/null | ||
| 191 | lret=$? | ||
| 192 | else | ||
| 193 | lret=111 | ||
| 194 | fi | ||
| 195 | |||
| 196 | # queue without bypass keyword should drop traffic if no listener exists. | ||
| 197 | if [ $lret -eq 0 ];then | ||
| 198 | echo "FAIL: $proto expected failure, got $lret" 1>&2 | ||
| 199 | exit 1 | ||
| 200 | fi | ||
| 201 | |||
| 202 | ip netns exec ${nsrouter} nft delete table $proto blackh | ||
| 203 | if [ $? -ne 0 ] ;then | ||
| 204 | echo "FAIL: $proto: Could not delete blackh table" | ||
| 205 | exit 1 | ||
| 206 | fi | ||
| 207 | |||
| 208 | echo "PASS: $proto: statement with no listener results in packet drop" | ||
| 209 | } | ||
| 210 | |||
| 211 | test_queue() | ||
| 212 | { | ||
| 213 | local expected=$1 | ||
| 214 | local last="" | ||
| 215 | |||
| 216 | # spawn nf-queue listeners | ||
| 217 | ip netns exec ${nsrouter} ./nf-queue -c -q 0 -t 3 > "$TMPFILE0" & | ||
| 218 | ip netns exec ${nsrouter} ./nf-queue -c -q 1 -t 3 > "$TMPFILE1" & | ||
| 219 | sleep 1 | ||
| 220 | test_ping | ||
| 221 | ret=$? | ||
| 222 | if [ $ret -ne 0 ];then | ||
| 223 | echo "FAIL: netns routing/connectivity with active listener on queue $queue: $ret" 1>&2 | ||
| 224 | exit $ret | ||
| 225 | fi | ||
| 226 | |||
| 227 | test_ping_router | ||
| 228 | ret=$? | ||
| 229 | if [ $ret -ne 0 ];then | ||
| 230 | echo "FAIL: netns router unreachable listener on queue $queue: $ret" 1>&2 | ||
| 231 | exit $ret | ||
| 232 | fi | ||
| 233 | |||
| 234 | wait | ||
| 235 | ret=$? | ||
| 236 | |||
| 237 | for file in $TMPFILE0 $TMPFILE1; do | ||
| 238 | last=$(tail -n1 "$file") | ||
| 239 | if [ x"$last" != x"$expected packets total" ]; then | ||
| 240 | echo "FAIL: Expected $expected packets total, but got $last" 1>&2 | ||
| 241 | cat "$file" 1>&2 | ||
| 242 | |||
| 243 | ip netns exec ${nsrouter} nft list ruleset | ||
| 244 | exit 1 | ||
| 245 | fi | ||
| 246 | done | ||
| 247 | |||
| 248 | echo "PASS: Expected and received $last" | ||
| 249 | } | ||
| 250 | |||
| 251 | test_tcp_forward() | ||
| 252 | { | ||
| 253 | ip netns exec ${nsrouter} ./nf-queue -q 2 -t 10 & | ||
| 254 | local nfqpid=$! | ||
| 255 | |||
| 256 | tmpfile=$(mktemp) || exit 1 | ||
| 257 | dd conv=sparse status=none if=/dev/zero bs=1M count=100 of=$tmpfile | ||
| 258 | ip netns exec ${ns2} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null & | ||
| 259 | local rpid=$! | ||
| 260 | |||
| 261 | sleep 1 | ||
| 262 | ip netns exec ${ns1} nc -w 5 10.0.2.99 12345 <"$tmpfile" >/dev/null & | ||
| 263 | |||
| 264 | rm -f "$tmpfile" | ||
| 265 | |||
| 266 | wait $rpid | ||
| 267 | wait $lpid | ||
| 268 | [ $? -eq 0 ] && echo "PASS: tcp and nfqueue in forward chain" | ||
| 269 | } | ||
| 270 | |||
| 271 | test_tcp_localhost() | ||
| 272 | { | ||
| 273 | tc -net "${nsrouter}" qdisc add dev lo root netem loss random 1% | ||
| 274 | |||
| 275 | tmpfile=$(mktemp) || exit 1 | ||
| 276 | |||
| 277 | dd conv=sparse status=none if=/dev/zero bs=1M count=900 of=$tmpfile | ||
| 278 | ip netns exec ${nsrouter} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null & | ||
| 279 | local rpid=$! | ||
| 280 | |||
| 281 | ip netns exec ${nsrouter} ./nf-queue -q 3 -t 30 & | ||
| 282 | local nfqpid=$! | ||
| 283 | |||
| 284 | sleep 1 | ||
| 285 | ip netns exec ${nsrouter} nc -w 5 127.0.0.1 12345 <"$tmpfile" > /dev/null | ||
| 286 | rm -f "$tmpfile" | ||
| 287 | |||
| 288 | wait $rpid | ||
| 289 | [ $? -eq 0 ] && echo "PASS: tcp via loopback" | ||
| 290 | } | ||
| 291 | |||
| 292 | ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null | ||
| 293 | ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null | ||
| 294 | ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null | ||
| 295 | |||
| 296 | load_ruleset "filter" 0 | ||
| 297 | |||
| 298 | sleep 3 | ||
| 299 | |||
| 300 | test_ping | ||
| 301 | ret=$? | ||
| 302 | if [ $ret -eq 0 ];then | ||
| 303 | # queue bypass works (rules were skipped, no listener) | ||
| 304 | echo "PASS: ${ns1} can reach ${ns2}" | ||
| 305 | else | ||
| 306 | echo "FAIL: ${ns1} cannot reach ${ns2}: $ret" 1>&2 | ||
| 307 | exit $ret | ||
| 308 | fi | ||
| 309 | |||
| 310 | test_queue_blackhole ip | ||
| 311 | test_queue_blackhole ip6 | ||
| 312 | |||
| 313 | # dummy ruleset to add base chains between the | ||
| 314 | # queueing rules. We don't want the second reinject | ||
| 315 | # to re-execute the old hooks. | ||
| 316 | load_counter_ruleset 10 | ||
| 317 | |||
| 318 | # we are hooking all: prerouting/input/forward/output/postrouting. | ||
| 319 | # we ping ${ns2} from ${ns1} via ${nsrouter} using ipv4 and ipv6, so: | ||
| 320 | # 1x icmp prerouting,forward,postrouting -> 3 queue events (6 incl. reply). | ||
| 321 | # 1x icmp prerouting,input,output postrouting -> 4 queue events incl. reply. | ||
| 322 | # so we expect that userspace program receives 10 packets. | ||
| 323 | test_queue 10 | ||
| 324 | |||
| 325 | # same. We queue to a second program as well. | ||
| 326 | load_ruleset "filter2" 20 | ||
| 327 | test_queue 20 | ||
| 328 | |||
| 329 | test_tcp_forward | ||
| 330 | test_tcp_localhost | ||
| 331 | |||
| 332 | exit $ret | ||
| @@ -527,11 +527,16 @@ n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0 · 526 unmodified lines | |||
| 527 | n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75 | 527 | n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75 |
| 528 | n0 wg set wg0 peer "$pub2" allowed-ips ::/0 | 528 | n0 wg set wg0 peer "$pub2" allowed-ips ::/0 |
| 529 | n0 wg set wg0 peer "$pub2" remove | 529 | n0 wg set wg0 peer "$pub2" remove |
| 530 | low_order_points=( AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38= ) | 530 | for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do |
| 531 | n0 wg set wg0 private-key /dev/null ${low_order_points[@]/#/peer } | 531 | n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111 |
| 532 | [[ -z $(n0 wg show wg0 peers) ]] | 532 | done |
| 533 | n0 wg set wg0 private-key <(echo "$key1") ${low_order_points[@]/#/peer } | 533 | [[ -n $(n0 wg show wg0 peers) ]] |
| 534 | [[ -z $(n0 wg show wg0 peers) ]] | 534 | exec 4< <(n0 ncat -l -u -p 1111) |
| 535 | ncat_pid=$! | ||
| 536 | waitncatudp $netns0 $ncat_pid | ||
| 537 | ip0 link set wg0 up | ||
| 538 | ! read -r -n 1 -t 2 <&4 || false | ||
| 539 | kill $ncat_pid | ||
| 535 | ip0 link del wg0 | 540 | ip0 link del wg0 |
| 536 | 541 | ||
| 537 | declare -A objects | 542 | declare -A objects |
| @@ -41,7 +41,7 @@ $(DISTFILES_PATH)/$(1): · 40 unmodified lines | |||
| 41 | flock -x $$@.lock -c '[ -f $$@ ] && exit 0; wget -O $$@.tmp $(MIRROR)$(1) || wget -O $$@.tmp $(2)$(1) || rm -f $$@.tmp; [ -f $$@.tmp ] || exit 1; if echo "$(3) $$@.tmp" | sha256sum -c -; then mv $$@.tmp $$@; else rm -f $$@.tmp; exit 71; fi' | 41 | flock -x $$@.lock -c '[ -f $$@ ] && exit 0; wget -O $$@.tmp $(MIRROR)$(1) || wget -O $$@.tmp $(2)$(1) || rm -f $$@.tmp; [ -f $$@.tmp ] || exit 1; if echo "$(3) $$@.tmp" | sha256sum -c -; then mv $$@.tmp $$@; else rm -f $$@.tmp; exit 71; fi' |
| 42 | endef | 42 | endef |
| 43 | 43 | ||
| 44 | $(eval $(call tar_download,MUSL,musl,1.1.24,.tar.gz,https://www.musl-libc.org/releases/,1370c9a812b2cf2a7d92802510cca0058cc37e66a7bedd70051f0a34015022a3)) | 44 | $(eval $(call tar_download,MUSL,musl,1.2.0,.tar.gz,https://musl.libc.org/releases/,c6de7b191139142d3f9a7b5b702c9cae1b5ee6e7f57e582da9328629408fd4e8)) |
| 45 | $(eval $(call tar_download,IPERF,iperf,3.7,.tar.gz,https://downloads.es.net/pub/iperf/,d846040224317caf2f75c843d309a950a7db23f9b44b94688ccbe557d6d1710c)) | 45 | $(eval $(call tar_download,IPERF,iperf,3.7,.tar.gz,https://downloads.es.net/pub/iperf/,d846040224317caf2f75c843d309a950a7db23f9b44b94688ccbe557d6d1710c)) |
| 46 | $(eval $(call tar_download,BASH,bash,5.0,.tar.gz,https://ftp.gnu.org/gnu/bash/,b4a80f2ac66170b2913efbfb9f2594f1f76c7b1afd11f799e22035d63077fb4d)) | 46 | $(eval $(call tar_download,BASH,bash,5.0,.tar.gz,https://ftp.gnu.org/gnu/bash/,b4a80f2ac66170b2913efbfb9f2594f1f76c7b1afd11f799e22035d63077fb4d)) |
| 47 | $(eval $(call tar_download,IPROUTE2,iproute2,5.4.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,fe97aa60a0d4c5ac830be18937e18dc3400ca713a33a89ad896ff1e3d46086ae)) | 47 | $(eval $(call tar_download,IPROUTE2,iproute2,5.4.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,fe97aa60a0d4c5ac830be18937e18dc3400ca713a33a89ad896ff1e3d46086ae)) |
| @@ -13,7 +13,6 @@ · 12 unmodified lines | |||
| 13 | #include <fcntl.h> | 13 | #include <fcntl.h> |
| 14 | #include <sys/wait.h> | 14 | #include <sys/wait.h> |
| 15 | #include <sys/mount.h> | 15 | #include <sys/mount.h> |
| 16 | #include <sys/types.h> | ||
| 17 | #include <sys/stat.h> | 16 | #include <sys/stat.h> |
| 18 | #include <sys/types.h> | 17 | #include <sys/types.h> |
| 19 | #include <sys/io.h> | 18 | #include <sys/io.h> |
| @@ -56,7 +56,6 @@ CONFIG_NO_HZ_IDLE=y · 55 unmodified lines | |||
| 56 | CONFIG_NO_HZ_FULL=n | 56 | CONFIG_NO_HZ_FULL=n |
| 57 | CONFIG_HZ_PERIODIC=n | 57 | CONFIG_HZ_PERIODIC=n |
| 58 | CONFIG_HIGH_RES_TIMERS=y | 58 | CONFIG_HIGH_RES_TIMERS=y |
| 59 | CONFIG_COMPAT_32BIT_TIME=y | ||
| 60 | CONFIG_ARCH_RANDOM=y | 59 | CONFIG_ARCH_RANDOM=y |
| 61 | CONFIG_FILE_LOCKING=y | 60 | CONFIG_FILE_LOCKING=y |
| 62 | CONFIG_POSIX_TIMERS=y | 61 | CONFIG_POSIX_TIMERS=y |
| @@ -124,17 +124,6 @@ choice · 123 unmodified lines | |||
| 124 | 124 | ||
| 125 | If in doubt, select 'None' | 125 | If in doubt, select 'None' |
| 126 | 126 | ||
| 127 | config INITRAMFS_COMPRESSION_NONE | ||
| 128 | bool "None" | ||
| 129 | help | ||
| 130 | Do not compress the built-in initramfs at all. This may sound wasteful | ||
| 131 | in space, but, you should be aware that the built-in initramfs will be | ||
| 132 | compressed at a later stage anyways along with the rest of the kernel, | ||
| 133 | on those architectures that support this. However, not compressing the | ||
| 134 | initramfs may lead to slightly higher memory consumption during a | ||
| 135 | short time at boot, while both the cpio image and the unpacked | ||
| 136 | filesystem image will be present in memory simultaneously | ||
| 137 | |||
| 138 | config INITRAMFS_COMPRESSION_GZIP | 127 | config INITRAMFS_COMPRESSION_GZIP |
| 139 | bool "Gzip" | 128 | bool "Gzip" |
| 140 | depends on RD_GZIP | 129 | depends on RD_GZIP |
| @@ -207,4 +196,15 @@ config INITRAMFS_COMPRESSION_LZ4 · 66 unmodified lines | |||
| 207 | If you choose this, keep in mind that most distros don't provide lz4 | 196 | If you choose this, keep in mind that most distros don't provide lz4 |
| 208 | by default which could cause a build failure. | 197 | by default which could cause a build failure. |
| 209 | 198 | ||
| 199 | config INITRAMFS_COMPRESSION_NONE | ||
| 200 | bool "None" | ||
| 201 | help | ||
| 202 | Do not compress the built-in initramfs at all. This may sound wasteful | ||
| 203 | in space, but, you should be aware that the built-in initramfs will be | ||
| 204 | compressed at a later stage anyways along with the rest of the kernel, | ||
| 205 | on those architectures that support this. However, not compressing the | ||
| 206 | initramfs may lead to slightly higher memory consumption during a | ||
| 207 | short time at boot, while both the cpio image and the unpacked | ||
| 208 | filesystem image will be present in memory simultaneously | ||
| 209 | |||
| 210 | endchoice | 210 | endchoice |