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 | 225 | Praveen BP <praveenbp@ti.com> |
| 226 | 226 | Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com> |
| 227 | 227 | Qais Yousef <qsyousef@gmail.com> <qais.yousef@imgtec.com> |
| 228 | +Quentin Monnet <quentin@isovalent.com> <quentin.monnet@netronome.com> | |
| 228 | 229 | Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com> |
| 229 | 230 | Rafael J. Wysocki <rjw@rjwysocki.net> <rjw@sisk.pl> |
| 230 | 231 | Rajesh Shah <rajesh.shah@intel.com> |
| @@ -110,6 +110,8 @@ stable kernels. · 109 unmodified lines | ||
| 110 | 110 | +----------------+-----------------+-----------------+-----------------------------+ |
| 111 | 111 | | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | |
| 112 | 112 | +----------------+-----------------+-----------------+-----------------------------+ |
| 113 | +| Cavium | ThunderX GICv3 | #38539 | N/A | | |
| 114 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 113 | 115 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | |
| 114 | 116 | +----------------+-----------------+-----------------+-----------------------------+ |
| 115 | 117 | | Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 | |
| @@ -266,11 +266,15 @@ to use. · 265 unmodified lines | ||
| 266 | 266 | attached (via the dmaengine_desc_attach_metadata() helper to the descriptor. |
| 267 | 267 | |
| 268 | 268 | From the DMA driver the following is expected for this mode: |
| 269 | + | |
| 269 | 270 | - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM |
| 271 | + | |
| 270 | 272 | The data from the provided metadata buffer should be prepared for the DMA |
| 271 | 273 | controller to be sent alongside of the payload data. Either by copying to a |
| 272 | 274 | hardware descriptor, or highly coupled packet. |
| 275 | + | |
| 273 | 276 | - DMA_DEV_TO_MEM |
| 277 | + | |
| 274 | 278 | On transfer completion the DMA driver must copy the metadata to the client |
| 275 | 279 | provided metadata buffer before notifying the client about the completion. |
| 276 | 280 | After the transfer completion, DMA drivers must not touch the metadata |
| @@ -284,10 +288,14 @@ to use. · 7 unmodified lines | ||
| 284 | 288 | and dmaengine_desc_set_metadata_len() is provided as helper functions. |
| 285 | 289 | |
| 286 | 290 | From the DMA driver the following is expected for this mode: |
| 287 | − - get_metadata_ptr | |
| 291 | + | |
| 292 | + - get_metadata_ptr() | |
| 293 | + | |
| 288 | 294 | Should return a pointer for the metadata buffer, the maximum size of the |
| 289 | 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 | 299 | It is called by the clients after it have placed the metadata to the buffer |
| 292 | 300 | to let the DMA driver know the number of valid bytes provided. |
| 293 | 301 | |
| @@ -258,11 +258,11 @@ conditions. · 257 unmodified lines | ||
| 258 | 258 | | option | condition | size read write read write | |
| 259 | 259 | +--------------+-----------+-----------------------------------------+ |
| 260 | 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 | 262 | | (default) | offline | 0 no no no no | |
| 263 | 263 | +--------------+-----------+-----------------------------------------+ |
| 264 | 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 | 266 | | | offline | 0 no no no no | |
| 267 | 267 | +--------------+-----------+-----------------------------------------+ |
| 268 | 268 | | | good | 0 no no yes yes | |
| @@ -270,7 +270,7 @@ conditions. · 1 unmodified line | ||
| 270 | 270 | | | offline | 0 no no no no | |
| 271 | 271 | +--------------+-----------+-----------------------------------------+ |
| 272 | 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 | 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 | 307 | * zone-offline |
| 308 | 308 | * repair |
| 309 | 309 | |
| 310 | −The I/O error actions defined for each behavior are detailed in the previous | |
| 311 | −section. | |
| 310 | +The run-time I/O error actions defined for each behavior are detailed in the | |
| 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 | 321 | Zonefs User Space Tools |
| 314 | 322 | ======================= |
| @@ -237,7 +237,7 @@ This is solely useful to speed up test compiles. · 236 unmodified lines | ||
| 237 | 237 | KBUILD_EXTRA_SYMBOLS |
| 238 | 238 | -------------------- |
| 239 | 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 | 242 | ALLSOURCE_ARCHS |
| 243 | 243 | --------------- |
| @@ -44,7 +44,7 @@ intermediate:: · 43 unmodified lines | ||
| 44 | 44 | def_bool y |
| 45 | 45 | |
| 46 | 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 | 50 | Variables |
| @@ -924,7 +924,7 @@ When kbuild executes, the following steps are followed (roughly): · 923 unmodified lines | ||
| 924 | 924 | $(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that |
| 925 | 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 | 929 | KBUILD_CFLAGS_KERNEL |
| 930 | 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 | 938 | $(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that |
| 939 | 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 | 942 | KBUILD_LDFLAGS_MODULE |
| 943 | 943 | Options for $(LD) when linking modules |
| @@ -945,7 +945,7 @@ When kbuild executes, the following steps are followed (roughly): · 1 unmodified line | ||
| 945 | 945 | $(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options |
| 946 | 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 | 950 | KBUILD_LDS |
| 951 | 951 | |
| @@ -470,9 +470,9 @@ build. · 469 unmodified lines | ||
| 470 | 470 | |
| 471 | 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 | 477 | The fields are separated by tabs and values may be empty (e.g. |
| 478 | 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 | 7527 | F: net/802/hippi.c |
| 7528 | 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 | 7536 | HISILICON SECURITY ENGINE V2 DRIVER (SEC2) |
| 7531 | 7537 | M: Zaibo Xu <xuzaibo@huawei.com> |
| 7532 | 7538 | L: linux-crypto@vger.kernel.org |
| @@ -8487,7 +8493,6 @@ L: dmaengine@vger.kernel.org · 954 unmodified lines | ||
| 8487 | 8493 | S: Supported |
| 8488 | 8494 | F: drivers/dma/idxd/* |
| 8489 | 8495 | F: include/uapi/linux/idxd.h |
| 8490 | −F: include/linux/idxd.h | |
| 8491 | 8496 | |
| 8492 | 8497 | INTEL IDLE DRIVER |
| 8493 | 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 | 8699 | M: Luca Coelho <luciano.coelho@intel.com> |
| 8695 | 8700 | M: Intel Linux Wireless <linuxwifi@intel.com> |
| 8696 | 8701 | L: linux-wireless@vger.kernel.org |
| 8697 | −W: http://intellinuxwireless.org | |
| 8702 | +W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi | |
| 8698 | 8703 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git |
| 8699 | 8704 | S: Supported |
| 8700 | 8705 | F: drivers/net/wireless/intel/iwlwifi/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 6 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc5 | |
| 5 | +EXTRAVERSION = -rc7 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -1804,7 +1804,7 @@ existing-targets := $(wildcard $(sort $(targets))) · 1795 unmodified lines | ||
| 1804 | 1804 | |
| 1805 | 1805 | -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) |
| 1806 | 1806 | |
| 1807 | −endif # config-targets | |
| 1807 | +endif # config-build | |
| 1808 | 1808 | endif # mixed-build |
| 1809 | 1809 | endif # need-sub-make |
| 1810 | 1810 | |
| @@ -154,7 +154,7 @@ config ARC_CPU_HS · 153 unmodified lines | ||
| 154 | 154 | help |
| 155 | 155 | Support for ARC HS38x Cores based on ARCv2 ISA |
| 156 | 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 | 158 | - Optional L2 Cache and IO-Coherency |
| 159 | 159 | - Revised Interrupt Architecture (multiple priorites, reg banks, |
| 160 | 160 | auto stack switch, auto regfile save/restore) |
| @@ -192,7 +192,7 @@ config ARC_SMP_HALT_ON_RESET · 31 unmodified lines | ||
| 192 | 192 | help |
| 193 | 193 | In SMP configuration cores can be configured as Halt-on-reset |
| 194 | 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 | 196 | at designated entry point. For other case, all jump to common |
| 197 | 197 | entry point and spin wait for Master's signal. |
| 198 | 198 | |
| @@ -21,8 +21,6 @@ CONFIG_MODULES=y · 20 unmodified lines | ||
| 21 | 21 | CONFIG_MODULE_FORCE_LOAD=y |
| 22 | 22 | CONFIG_MODULE_UNLOAD=y |
| 23 | 23 | # CONFIG_BLK_DEV_BSG is not set |
| 24 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 25 | −# CONFIG_IOSCHED_CFQ is not set | |
| 26 | 24 | CONFIG_ARC_PLAT_EZNPS=y |
| 27 | 25 | CONFIG_SMP=y |
| 28 | 26 | CONFIG_NR_CPUS=4096 |
| @@ -20,8 +20,6 @@ CONFIG_ISA_ARCOMPACT=y · 19 unmodified lines | ||
| 20 | 20 | CONFIG_KPROBES=y |
| 21 | 21 | CONFIG_MODULES=y |
| 22 | 22 | # CONFIG_BLK_DEV_BSG is not set |
| 23 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 24 | −# CONFIG_IOSCHED_CFQ is not set | |
| 25 | 23 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" |
| 26 | 24 | # CONFIG_COMPACTION is not set |
| 27 | 25 | CONFIG_NET=y |
| @@ -19,8 +19,6 @@ CONFIG_PERF_EVENTS=y · 18 unmodified lines | ||
| 19 | 19 | CONFIG_KPROBES=y |
| 20 | 20 | CONFIG_MODULES=y |
| 21 | 21 | # CONFIG_BLK_DEV_BSG is not set |
| 22 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 23 | −# CONFIG_IOSCHED_CFQ is not set | |
| 24 | 22 | CONFIG_ISA_ARCV2=y |
| 25 | 23 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs" |
| 26 | 24 | # CONFIG_COMPACTION is not set |
| @@ -14,8 +14,6 @@ CONFIG_PERF_EVENTS=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_KPROBES=y |
| 15 | 15 | CONFIG_MODULES=y |
| 16 | 16 | # CONFIG_BLK_DEV_BSG is not set |
| 17 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 18 | −# CONFIG_IOSCHED_CFQ is not set | |
| 19 | 17 | CONFIG_ISA_ARCV2=y |
| 20 | 18 | CONFIG_SMP=y |
| 21 | 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 | 44 | #endif /* !CONFIG_ISA_ARCOMPACT */ |
| 45 | 45 | |
| 46 | +struct task_struct; | |
| 47 | + | |
| 46 | 48 | extern void fpu_save_restore(struct task_struct *p, struct task_struct *n); |
| 47 | 49 | |
| 48 | 50 | #else /* !CONFIG_ARC_FPU_SAVE_RESTORE */ |
| @@ -29,6 +29,8 @@ · 28 unmodified lines | ||
| 29 | 29 | .endm |
| 30 | 30 | |
| 31 | 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 | 35 | /* annotation for data we want in DCCM - if enabled in .config */ |
| 34 | 36 | .macro ARCFP_DATA nm |
| @@ -8,11 +8,11 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/delay.h> |
| 9 | 9 | #include <linux/root_dev.h> |
| 10 | 10 | #include <linux/clk.h> |
| 11 | −#include <linux/clk-provider.h> | |
| 12 | 11 | #include <linux/clocksource.h> |
| 13 | 12 | #include <linux/console.h> |
| 14 | 13 | #include <linux/module.h> |
| 15 | 14 | #include <linux/cpu.h> |
| 15 | +#include <linux/of_clk.h> | |
| 16 | 16 | #include <linux/of_fdt.h> |
| 17 | 17 | #include <linux/of.h> |
| 18 | 18 | #include <linux/cache.h> |
| @@ -104,8 +104,7 @@ static void show_faulting_vma(unsigned long address) · 103 unmodified lines | ||
| 104 | 104 | if (IS_ERR(nm)) |
| 105 | 105 | nm = "?"; |
| 106 | 106 | } |
| 107 | − pr_info(" @off 0x%lx in [%s]\n" | |
| 108 | − " VMA: 0x%08lx to 0x%08lx\n", | |
| 107 | + pr_info(" @off 0x%lx in [%s] VMA: 0x%08lx to 0x%08lx\n", | |
| 109 | 108 | vma->vm_start < TASK_UNMAPPED_BASE ? |
| 110 | 109 | address : address - vma->vm_start, |
| 111 | 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 | 119 | unsigned int vec, cause_code; |
| 121 | 120 | unsigned long address; |
| 122 | 121 | |
| 123 | − pr_info("\n[ECR ]: 0x%08lx => ", regs->event); | |
| 124 | − | |
| 125 | 122 | /* For Data fault, this is data address not instruction addr */ |
| 126 | 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 | 128 | /* For DTLB Miss or ProtV, display the memory involved too */ |
| 132 | 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 | 131 | (cause_code == 0x01) ? "Read" : |
| 135 | 132 | ((cause_code == 0x02) ? "Write" : "EX"), |
| 136 | − address, regs->ret); | |
| 133 | + address, (void *)regs->ret); | |
| 137 | 134 | } else if (vec == ECR_V_ITLB_MISS) { |
| 138 | 135 | pr_cont("Insn could not be fetched\n"); |
| 139 | 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 | 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 | 191 | if (user_mode(regs)) |
| 199 | 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 | 199 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" |
| 204 | 200 | |
| 205 | 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 | 203 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 208 | 204 | STS_BIT(regs, DE), STS_BIT(regs, AE), |
| 209 | 205 | STS_BIT(regs, A2), STS_BIT(regs, A1), |
| 210 | 206 | STS_BIT(regs, E2), STS_BIT(regs, E1)); |
| 211 | 207 | #else |
| 212 | − pr_cont(" : %2s%2s%2s%2s\n", | |
| 208 | + pr_cont(" [%2s%2s%2s%2s]", | |
| 213 | 209 | STS_BIT(regs, IE), |
| 214 | 210 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 215 | 211 | STS_BIT(regs, DE), STS_BIT(regs, AE)); |
| 216 | 212 | #endif |
| 217 | − pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", | |
| 218 | − regs->bta, regs->sp, regs->fp); | |
| 213 | + pr_cont(" BTA: 0x%08lx\n", regs->bta); | |
| 214 | + pr_info("BLK: %pS\n SP: 0x%08lx FP: 0x%08lx\n", | |
| 215 | + (void *)regs->blink, regs->sp, regs->fp); | |
| 219 | 216 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", |
| 220 | 217 | regs->lp_start, regs->lp_end, regs->lp_count); |
| 221 | 218 | |
| @@ -307,13 +307,15 @@ endif · 306 unmodified lines | ||
| 307 | 307 | ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) |
| 308 | 308 | prepare: stack_protector_prepare |
| 309 | 309 | stack_protector_prepare: prepare0 |
| 310 | − $(eval KBUILD_CFLAGS += \ | |
| 310 | + $(eval SSP_PLUGIN_CFLAGS := \ | |
| 311 | 311 | -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ |
| 312 | 312 | awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ |
| 313 | 313 | include/generated/asm-offsets.h) \ |
| 314 | 314 | -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ |
| 315 | 315 | awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ |
| 316 | 316 | include/generated/asm-offsets.h)) |
| 317 | + $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) | |
| 318 | + $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) | |
| 317 | 319 | endif |
| 318 | 320 | |
| 319 | 321 | all: $(notdir $(KBUILD_IMAGE)) |
| @@ -101,7 +101,6 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ · 100 unmodified lines | ||
| 101 | 101 | $(libfdt) $(libfdt_hdrs) hyp-stub.S |
| 102 | 102 | |
| 103 | 103 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| 104 | −KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) | |
| 105 | 104 | |
| 106 | 105 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
| 107 | 106 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
| @@ -117,7 +116,8 @@ CFLAGS_fdt_ro.o := $(nossp-flags-y) · 9 unmodified lines | ||
| 117 | 116 | CFLAGS_fdt_rw.o := $(nossp-flags-y) |
| 118 | 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 | 121 | asflags-y := -DZIMAGE |
| 122 | 122 | |
| 123 | 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 | 94 | * this. |
| 95 | 95 | */ |
| 96 | 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 | 99 | if (!np) |
| 98 | 100 | goto out_put; |
| 99 | 101 | |
| @@ -118,7 +118,7 @@ ENTRY(arm_copy_from_user) · 117 unmodified lines | ||
| 118 | 118 | |
| 119 | 119 | ENDPROC(arm_copy_from_user) |
| 120 | 120 | |
| 121 | − .pushsection .fixup,"ax" | |
| 121 | + .pushsection .text.fixup,"ax" | |
| 122 | 122 | .align 0 |
| 123 | 123 | copy_abort_preamble |
| 124 | 124 | ldmfd sp!, {r1, r2, r3} |
| @@ -119,12 +119,12 @@ · 118 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | ethernet@e4000 { |
| 121 | 121 | phy-handle = <&rgmii_phy1>; |
| 122 | − phy-connection-type = "rgmii-txid"; | |
| 122 | + phy-connection-type = "rgmii-id"; | |
| 123 | 123 | }; |
| 124 | 124 | |
| 125 | 125 | ethernet@e6000 { |
| 126 | 126 | phy-handle = <&rgmii_phy2>; |
| 127 | − phy-connection-type = "rgmii-txid"; | |
| 127 | + phy-connection-type = "rgmii-id"; | |
| 128 | 128 | }; |
| 129 | 129 | |
| 130 | 130 | ethernet@e8000 { |
| @@ -131,12 +131,12 @@ · 130 unmodified lines | ||
| 131 | 131 | &fman0 { |
| 132 | 132 | ethernet@e4000 { |
| 133 | 133 | phy-handle = <&rgmii_phy1>; |
| 134 | − phy-connection-type = "rgmii"; | |
| 134 | + phy-connection-type = "rgmii-id"; | |
| 135 | 135 | }; |
| 136 | 136 | |
| 137 | 137 | ethernet@e6000 { |
| 138 | 138 | phy-handle = <&rgmii_phy2>; |
| 139 | − phy-connection-type = "rgmii"; | |
| 139 | + phy-connection-type = "rgmii-id"; | |
| 140 | 140 | }; |
| 141 | 141 | |
| 142 | 142 | ethernet@e8000 { |
| @@ -55,10 +55,10 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, · 54 unmodified lines | ||
| 55 | 55 | break; |
| 56 | 56 | } |
| 57 | 57 | chacha_4block_xor_neon(state, dst, src, nrounds, l); |
| 58 | − bytes -= CHACHA_BLOCK_SIZE * 5; | |
| 59 | − src += CHACHA_BLOCK_SIZE * 5; | |
| 60 | − dst += CHACHA_BLOCK_SIZE * 5; | |
| 61 | − state[12] += 5; | |
| 58 | + bytes -= l; | |
| 59 | + src += l; | |
| 60 | + dst += l; | |
| 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 | 30 | #define ASID(mm) ((mm)->context.id.counter & 0xffff) |
| 31 | 31 | |
| 32 | −extern bool arm64_use_ng_mappings; | |
| 33 | − | |
| 34 | 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 | 37 | typedef void (*bp_hardening_cb_t)(void); |
| @@ -23,11 +23,13 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <asm/pgtable-types.h> |
| 25 | 25 | |
| 26 | +extern bool arm64_use_ng_mappings; | |
| 27 | + | |
| 26 | 28 | #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) |
| 27 | 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) | |
| 30 | −#define PMD_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PMD_SECT_NG : 0) | |
| 31 | +#define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0) | |
| 32 | +#define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0) | |
| 31 | 33 | |
| 32 | 34 | #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) |
| 33 | 35 | #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) |
| @@ -25,8 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | #define __NR_compat_gettimeofday 78 |
| 26 | 26 | #define __NR_compat_sigreturn 119 |
| 27 | 27 | #define __NR_compat_rt_sigreturn 173 |
| 28 | −#define __NR_compat_clock_getres 247 | |
| 29 | 28 | #define __NR_compat_clock_gettime 263 |
| 29 | +#define __NR_compat_clock_getres 264 | |
| 30 | 30 | #define __NR_compat_clock_gettime64 403 |
| 31 | 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 | 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 | 972 | void smp_send_stop(void) |
| 962 | 973 | { |
| 963 | 974 | unsigned long timeout; |
| 964 | 975 | |
| 965 | − if (num_online_cpus() > 1) { | |
| 976 | + if (num_other_online_cpus()) { | |
| 966 | 977 | cpumask_t mask; |
| 967 | 978 | |
| 968 | 979 | cpumask_copy(&mask, cpu_online_mask); |
| @@ -975,10 +986,10 @@ void smp_send_stop(void) · 6 unmodified lines | ||
| 975 | 986 | |
| 976 | 987 | /* Wait up to one second for other CPUs to stop */ |
| 977 | 988 | timeout = USEC_PER_SEC; |
| 978 | − while (num_online_cpus() > 1 && timeout--) | |
| 989 | + while (num_other_online_cpus() && timeout--) | |
| 979 | 990 | udelay(1); |
| 980 | 991 | |
| 981 | − if (num_online_cpus() > 1) | |
| 992 | + if (num_other_online_cpus()) | |
| 982 | 993 | pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", |
| 983 | 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 | 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 | 1020 | sdei_mask_local_cpu(); |
| 1006 | 1021 | return; |
| 1007 | 1022 | } |
| @@ -1009,7 +1024,7 @@ void crash_smp_send_stop(void) · 1 unmodified line | ||
| 1009 | 1024 | cpumask_copy(&mask, cpu_online_mask); |
| 1010 | 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 | 1029 | pr_crit("SMP: stopping secondary CPUs\n"); |
| 1015 | 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 | 1818 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); |
| 1819 | 1819 | |
| 1820 | + kvmppc_mmu_destroy_pr(vcpu); | |
| 1820 | 1821 | free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); |
| 1821 | 1822 | #ifdef CONFIG_KVM_BOOK3S_32_HANDLER |
| 1822 | 1823 | kfree(vcpu->arch.shadow_vcpu); |
| @@ -759,7 +759,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 758 unmodified lines | ||
| 759 | 759 | return 0; |
| 760 | 760 | |
| 761 | 761 | out_vcpu_uninit: |
| 762 | − kvmppc_mmu_destroy(vcpu); | |
| 763 | 762 | kvmppc_subarch_vcpu_uninit(vcpu); |
| 764 | 763 | return err; |
| 765 | 764 | } |
| @@ -792,7 +791,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) · 26 unmodified lines | ||
| 792 | 791 | |
| 793 | 792 | kvmppc_core_vcpu_free(vcpu); |
| 794 | 793 | |
| 795 | − kvmppc_mmu_destroy(vcpu); | |
| 796 | 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 | 120 | unsigned long k_cur; |
| 121 | 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 | 123 | for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { |
| 130 | 124 | pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); |
| 131 | 125 | pte_t *ptep = pte_offset_kernel(pmd, k_cur); |
| @@ -143,7 +137,8 @@ void __init kasan_mmu_init(void) · 11 unmodified lines | ||
| 143 | 137 | int ret; |
| 144 | 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 | 142 | ret = kasan_init_shadow_page_tables(KASAN_SHADOW_START, KASAN_SHADOW_END); |
| 148 | 143 | |
| 149 | 144 | if (ret) |
| @@ -3268,7 +3268,10 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) · 3267 unmodified lines | ||
| 3268 | 3268 | /* Initial reset is a superset of the normal reset */ |
| 3269 | 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 | 3275 | vcpu->arch.sie_block->gpsw.mask = 0; |
| 3273 | 3276 | vcpu->arch.sie_block->gpsw.addr = 0; |
| 3274 | 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 | 3281 | memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr)); |
| 3279 | 3282 | vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK; |
| 3280 | 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 | 3297 | vcpu->run->s.regs.fpc = 0; |
| 3282 | 3298 | vcpu->arch.sie_block->gbea = 1; |
| 3283 | 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 | 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 | |
| 194 | − * to a single target core, however, event counts generated by processes | |
| 195 | − * running on other cores cannot be masked out. So we do not support | |
| 196 | − * sampling and per-thread events. | |
| 193 | + * that share the same NB / Last level cache. On family 16h and below, | |
| 194 | + * Interrupts can be directed to a single target core, however, event | |
| 195 | + * counts generated by processes running on other cores cannot be masked | |
| 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 | 199 | hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; |
| 203 | 200 | hwc->idx = -1; |
| 204 | 201 | |
| @@ -306,7 +303,7 @@ static struct pmu amd_nb_pmu = { · 101 unmodified lines | ||
| 306 | 303 | .start = amd_uncore_start, |
| 307 | 304 | .stop = amd_uncore_stop, |
| 308 | 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 | 309 | static struct pmu amd_llc_pmu = { |
| @@ -317,7 +314,7 @@ static struct pmu amd_llc_pmu = { · 4 unmodified lines | ||
| 317 | 314 | .start = amd_uncore_start, |
| 318 | 315 | .stop = amd_uncore_stop, |
| 319 | 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 | 320 | static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) |
| @@ -360,7 +360,6 @@ struct x86_emulate_ctxt { · 359 unmodified lines | ||
| 360 | 360 | u64 d; |
| 361 | 361 | unsigned long _eip; |
| 362 | 362 | struct operand memop; |
| 363 | − /* Fields above regs are cleared together. */ | |
| 364 | 363 | unsigned long _regs[NR_VCPU_REGS]; |
| 365 | 364 | struct operand *memopp; |
| 366 | 365 | struct fetch_cache fetch; |
| @@ -838,13 +838,15 @@ static void free_moved_vector(struct apic_chip_data *apicd) · 837 unmodified lines | ||
| 838 | 838 | bool managed = apicd->is_managed; |
| 839 | 839 | |
| 840 | 840 | /* |
| 841 | − * This should never happen. Managed interrupts are not | |
| 842 | − * migrated except on CPU down, which does not involve the | |
| 843 | − * cleanup vector. But try to keep the accounting correct | |
| 844 | − * nevertheless. | |
| 841 | + * Managed interrupts are usually not migrated away | |
| 842 | + * from an online CPU, but CPU isolation 'managed_irq' | |
| 843 | + * can make that happen. | |
| 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 | 850 | trace_vector_free_moved(apicd->irq, cpu, vector, managed); |
| 849 | 851 | irq_matrix_free(vector_matrix, cpu, vector, managed); |
| 850 | 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 | 493 | return; |
| 494 | 494 | |
| 495 | 495 | if ((val & 3UL) == 1UL) { |
| 496 | − /* PPIN available but disabled: */ | |
| 496 | + /* PPIN locked in disabled mode */ | |
| 497 | 497 | return; |
| 498 | 498 | } |
| 499 | 499 | |
| 500 | − /* If PPIN is disabled, but not locked, try to enable: */ | |
| 501 | − if (!(val & 3UL)) { | |
| 500 | + /* If PPIN is disabled, try to enable */ | |
| 501 | + if (!(val & 2UL)) { | |
| 502 | 502 | wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); |
| 503 | 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 | 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 | 487 | struct thermal_state *state = &per_cpu(thermal_state, cpu); |
| 488 | 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); | |
| 491 | − cancel_delayed_work(&state->core_throttle.therm_work); | |
| 495 | + cancel_delayed_work_sync(&state->package_throttle.therm_work); | |
| 496 | + cancel_delayed_work_sync(&state->core_throttle.therm_work); | |
| 492 | 497 | |
| 493 | 498 | state->package_throttle.rate_control_active = false; |
| 494 | 499 | state->core_throttle.rate_control_active = false; |
| @@ -68,7 +68,7 @@ config KVM_WERROR · 67 unmodified lines | ||
| 68 | 68 | depends on (X86_64 && !KASAN) || !COMPILE_TEST |
| 69 | 69 | depends on EXPERT |
| 70 | 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 | 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 | 5173 | ctxt->fetch.ptr = ctxt->fetch.data; |
| 5174 | 5174 | ctxt->fetch.end = ctxt->fetch.data + insn_len; |
| 5175 | 5175 | ctxt->opcode_len = 1; |
| 5176 | + ctxt->intercept = x86_intercept_none; | |
| 5176 | 5177 | if (insn_len > 0) |
| 5177 | 5178 | memcpy(ctxt->fetch.data, insn, insn_len); |
| 5178 | 5179 | else { |
| @@ -378,12 +378,15 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) · 377 unmodified lines | ||
| 378 | 378 | if (e->fields.delivery_mode == APIC_DM_FIXED) { |
| 379 | 379 | struct kvm_lapic_irq irq; |
| 380 | 380 | |
| 381 | − irq.shorthand = APIC_DEST_NOSHORT; | |
| 382 | 381 | irq.vector = e->fields.vector; |
| 383 | 382 | irq.delivery_mode = e->fields.delivery_mode << 8; |
| 384 | − irq.dest_id = e->fields.dest_id; | |
| 385 | 383 | irq.dest_mode = |
| 386 | 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 | 390 | bitmap_zero(&vcpu_bitmap, 16); |
| 388 | 391 | kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq, |
| 389 | 392 | &vcpu_bitmap); |
| @@ -6312,7 +6312,8 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu, · 6311 unmodified lines | ||
| 6312 | 6312 | enum exit_fastpath_completion *exit_fastpath) |
| 6313 | 6313 | { |
| 6314 | 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 | 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 | 224 | return; |
| 225 | 225 | |
| 226 | 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 | 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 | 1923 | if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa)) |
| 1924 | 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 | 1928 | if (!vmx->nested.hv_evmcs) |
| 1928 | 1929 | vmx->nested.current_vmptr = -1ull; |
| 1929 | 1930 | |
| @@ -2338,6 +2338,17 @@ static void hardware_disable(void) · 2337 unmodified lines | ||
| 2338 | 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 | 2352 | static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, |
| 2342 | 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 | 2429 | SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | |
| 2419 | 2430 | SECONDARY_EXEC_PT_USE_GPA | |
| 2420 | 2431 | SECONDARY_EXEC_PT_CONCEAL_VMX | |
| 2421 | − SECONDARY_EXEC_ENABLE_VMFUNC | | |
| 2422 | − SECONDARY_EXEC_ENCLS_EXITING; | |
| 2432 | + SECONDARY_EXEC_ENABLE_VMFUNC; | |
| 2433 | + if (cpu_has_sgx()) | |
| 2434 | + opt2 |= SECONDARY_EXEC_ENCLS_EXITING; | |
| 2423 | 2435 | if (adjust_vmx_controls(min2, opt2, |
| 2424 | 2436 | MSR_IA32_VMX_PROCBASED_CTLS2, |
| 2425 | 2437 | &_cpu_based_2nd_exec_control) < 0) |
| @@ -7195,10 +7195,12 @@ static void kvm_timer_init(void) · 7194 unmodified lines | ||
| 7195 | 7195 | |
| 7196 | 7196 | cpu = get_cpu(); |
| 7197 | 7197 | policy = cpufreq_cpu_get(cpu); |
| 7198 | − if (policy && policy->cpuinfo.max_freq) | |
| 7199 | − max_tsc_khz = policy->cpuinfo.max_freq; | |
| 7198 | + if (policy) { | |
| 7199 | + if (policy->cpuinfo.max_freq) | |
| 7200 | + max_tsc_khz = policy->cpuinfo.max_freq; | |
| 7201 | + cpufreq_cpu_put(policy); | |
| 7202 | + } | |
| 7200 | 7203 | put_cpu(); |
| 7201 | − cpufreq_cpu_put(policy); | |
| 7202 | 7204 | #endif |
| 7203 | 7205 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, |
| 7204 | 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 | 190 | return pmd_k; |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | −void vmalloc_sync_all(void) | |
| 193 | +static void vmalloc_sync(void) | |
| 194 | 194 | { |
| 195 | 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 | 231 | * 32-bit: |
| 222 | 232 | * |
| @@ -319,11 +329,23 @@ out: · 96 unmodified lines | ||
| 319 | 329 | |
| 320 | 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 | 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 | 350 | * 64-bit: |
| 329 | 351 | * |
| @@ -106,6 +106,22 @@ static unsigned int __ioremap_check_encrypted(struct resource *res) · 105 unmodified lines | ||
| 106 | 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 | 125 | static int __ioremap_collect_map_flags(struct resource *res, void *arg) |
| 110 | 126 | { |
| 111 | 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 | 140 | * To avoid multiple resource walks, this function walks resources marked as |
| 125 | 141 | * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a |
| 126 | 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 | 147 | static void __ioremap_check_mem(resource_size_t addr, unsigned long size, |
| 129 | 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 | 154 | memset(desc, 0, sizeof(struct ioremap_desc)); |
| 136 | 155 | |
| 137 | 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 | 2040 | /* and dreg_lo,sreg_lo */ |
| 2041 | 2041 | EMIT2(0x23, add_2reg(0xC0, sreg_lo, dreg_lo)); |
| 2042 | − /* and dreg_hi,sreg_hi */ | |
| 2043 | − EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); | |
| 2044 | − /* or dreg_lo,dreg_hi */ | |
| 2045 | − EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); | |
| 2042 | + if (is_jmp64) { | |
| 2043 | + /* and dreg_hi,sreg_hi */ | |
| 2044 | + EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); | |
| 2045 | + /* or dreg_lo,dreg_hi */ | |
| 2046 | + EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); | |
| 2047 | + } | |
| 2046 | 2048 | goto emit_cond_jmp; |
| 2047 | 2049 | } |
| 2048 | 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 | 1318 | return false; |
| 1319 | 1319 | |
| 1320 | 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 | 1322 | return false; |
| 1323 | 1323 | |
| 1324 | 1324 | return true; |
| @@ -398,6 +398,28 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head, · 397 unmodified lines | ||
| 398 | 398 | WARN_ON(e && (rq->tag != -1)); |
| 399 | 399 | |
| 400 | 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 | 423 | blk_mq_request_bypass_insert(rq, at_head, false); |
| 402 | 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 | 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 | 341 | * Can be deleted altogether. Later. |
| 306 | 342 | * |
| @@ -171,7 +171,7 @@ int ghes_estatus_pool_init(int num_ghes) · 170 unmodified lines | ||
| 171 | 171 | * New allocation must be visible in all pgd before it can be found by |
| 172 | 172 | * an NMI allocating from the pool. |
| 173 | 173 | */ |
| 174 | − vmalloc_sync_all(); | |
| 174 | + vmalloc_sync_mappings(); | |
| 175 | 175 | |
| 176 | 176 | rc = gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1); |
| 177 | 177 | if (rc) |
| @@ -448,6 +448,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb) · 447 unmodified lines | ||
| 448 | 448 | inode->i_uid = info->root_uid; |
| 449 | 449 | inode->i_gid = info->root_gid; |
| 450 | 450 | |
| 451 | + refcount_set(&device->ref, 1); | |
| 451 | 452 | device->binderfs_inode = inode; |
| 452 | 453 | device->miscdev.minor = minor; |
| 453 | 454 | |
| @@ -4713,7 +4713,7 @@ EXPORT_SYMBOL(of_clk_get_by_name); · 4712 unmodified lines | ||
| 4713 | 4713 | * |
| 4714 | 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 | 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 | 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 | 4730 | struct of_phandle_args clkspec; |
| 4731 | 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 | 595 | static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { |
| 614 | 596 | .halt_reg = 0x4008, |
| 615 | 597 | .halt_check = BRANCH_HALT, |
| @@ -687,7 +669,6 @@ static struct clk_regmap *disp_cc_sc7180_clocks[] = { · 71 unmodified lines | ||
| 687 | 669 | [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, |
| 688 | 670 | [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, |
| 689 | 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 | 672 | [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, |
| 692 | 673 | [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, |
| 693 | 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 | 98 | static struct clk_branch video_cc_vcodec0_core_clk = { |
| 99 | 99 | .halt_reg = 0x890, |
| 100 | − .halt_check = BRANCH_HALT, | |
| 100 | + .halt_check = BRANCH_HALT_VOTED, | |
| 101 | 101 | .clkr = { |
| 102 | 102 | .enable_reg = 0x890, |
| 103 | 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 | 1153 | if (!device->device_release) |
| 1154 | − dev_warn(device->dev, | |
| 1154 | + dev_dbg(device->dev, | |
| 1155 | 1155 | "WARN: Device release is not defined so it is not safe to unbind this driver while in use\n"); |
| 1156 | 1156 | |
| 1157 | 1157 | kref_init(&device->ref); |
| @@ -81,9 +81,9 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) · 80 unmodified lines | ||
| 81 | 81 | dev = &idxd->pdev->dev; |
| 82 | 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 | 87 | return -EBUSY; |
| 88 | 88 | |
| 89 | 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 | 564 | if (IS_ERR(flow->udma_rflow)) { |
| 565 | 565 | ret = PTR_ERR(flow->udma_rflow); |
| 566 | 566 | dev_err(dev, "UDMAX rflow get err %d\n", ret); |
| 567 | − goto err; | |
| 567 | + return ret; | |
| 568 | 568 | } |
| 569 | 569 | |
| 570 | 570 | if (flow->udma_rflow_id != xudma_rflow_get_id(flow->udma_rflow)) { |
| 571 | − xudma_rflow_put(rx_chn->common.udmax, flow->udma_rflow); | |
| 572 | − return -ENODEV; | |
| 571 | + ret = -ENODEV; | |
| 572 | + goto err_rflow_put; | |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | 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 | 578 | if (!flow->ringrx) { |
| 579 | 579 | ret = -ENODEV; |
| 580 | 580 | dev_err(dev, "Failed to get RX ring\n"); |
| 581 | − goto err; | |
| 581 | + goto err_rflow_put; | |
| 582 | 582 | } |
| 583 | 583 | |
| 584 | 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 | 586 | if (!flow->ringrxfdq) { |
| 587 | 587 | ret = -ENODEV; |
| 588 | 588 | dev_err(dev, "Failed to get RXFDQ ring\n"); |
| 589 | − goto err; | |
| 589 | + goto err_ringrx_free; | |
| 590 | 590 | } |
| 591 | 591 | |
| 592 | 592 | ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg); |
| 593 | 593 | if (ret) { |
| 594 | 594 | dev_err(dev, "Failed to cfg ringrx %d\n", ret); |
| 595 | − goto err; | |
| 595 | + goto err_ringrxfdq_free; | |
| 596 | 596 | } |
| 597 | 597 | |
| 598 | 598 | ret = k3_ringacc_ring_cfg(flow->ringrxfdq, &flow_cfg->rxfdq_cfg); |
| 599 | 599 | if (ret) { |
| 600 | 600 | dev_err(dev, "Failed to cfg ringrxfdq %d\n", ret); |
| 601 | − goto err; | |
| 601 | + goto err_ringrxfdq_free; | |
| 602 | 602 | } |
| 603 | 603 | |
| 604 | 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 | 648 | if (ret) { |
| 649 | 649 | dev_err(dev, "flow%d config failed: %d\n", flow->udma_rflow_id, |
| 650 | 650 | ret); |
| 651 | − goto err; | |
| 651 | + goto err_ringrxfdq_free; | |
| 652 | 652 | } |
| 653 | 653 | |
| 654 | 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 | 656 | flow->udma_rflow_id, rx_chn->flows_ready); |
| 657 | 657 | |
| 658 | 658 | return 0; |
| 659 | −err: | |
| 660 | − k3_udma_glue_release_rx_flow(rx_chn, flow_idx); | |
| 659 | + | |
| 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 | 670 | return ret; |
| 662 | 671 | } |
| 663 | 672 | |
| @@ -83,13 +83,16 @@ static ssize_t · 82 unmodified lines | ||
| 83 | 83 | efivar_attr_read(struct efivar_entry *entry, char *buf) |
| 84 | 84 | { |
| 85 | 85 | struct efi_variable *var = &entry->var; |
| 86 | + unsigned long size = sizeof(var->Data); | |
| 86 | 87 | char *str = buf; |
| 88 | + int ret; | |
| 87 | 89 | |
| 88 | 90 | if (!entry || !buf) |
| 89 | 91 | return -EINVAL; |
| 90 | 92 | |
| 91 | − var->DataSize = 1024; | |
| 92 | − if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | |
| 93 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | |
| 94 | + var->DataSize = size; | |
| 95 | + if (ret) | |
| 93 | 96 | return -EIO; |
| 94 | 97 | |
| 95 | 98 | if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) |
| @@ -116,13 +119,16 @@ static ssize_t · 20 unmodified lines | ||
| 116 | 119 | efivar_size_read(struct efivar_entry *entry, char *buf) |
| 117 | 120 | { |
| 118 | 121 | struct efi_variable *var = &entry->var; |
| 122 | + unsigned long size = sizeof(var->Data); | |
| 119 | 123 | char *str = buf; |
| 124 | + int ret; | |
| 120 | 125 | |
| 121 | 126 | if (!entry || !buf) |
| 122 | 127 | return -EINVAL; |
| 123 | 128 | |
| 124 | − var->DataSize = 1024; | |
| 125 | − if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | |
| 129 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | |
| 130 | + var->DataSize = size; | |
| 131 | + if (ret) | |
| 126 | 132 | return -EIO; |
| 127 | 133 | |
| 128 | 134 | str += sprintf(str, "0x%lx\n", var->DataSize); |
| @@ -133,12 +139,15 @@ static ssize_t · 4 unmodified lines | ||
| 133 | 139 | efivar_data_read(struct efivar_entry *entry, char *buf) |
| 134 | 140 | { |
| 135 | 141 | struct efi_variable *var = &entry->var; |
| 142 | + unsigned long size = sizeof(var->Data); | |
| 143 | + int ret; | |
| 136 | 144 | |
| 137 | 145 | if (!entry || !buf) |
| 138 | 146 | return -EINVAL; |
| 139 | 147 | |
| 140 | − var->DataSize = 1024; | |
| 141 | − if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | |
| 148 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | |
| 149 | + var->DataSize = size; | |
| 150 | + if (ret) | |
| 142 | 151 | return -EIO; |
| 143 | 152 | |
| 144 | 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 | 208 | u8 *data; |
| 200 | 209 | int err; |
| 201 | 210 | |
| 211 | + if (!entry || !buf) | |
| 212 | + return -EINVAL; | |
| 213 | + | |
| 202 | 214 | if (in_compat_syscall()) { |
| 203 | 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 | 263 | struct efi_variable *var = &entry->var; |
| 252 | 264 | struct compat_efi_variable *compat; |
| 265 | + unsigned long datasize = sizeof(var->Data); | |
| 253 | 266 | size_t size; |
| 267 | + int ret; | |
| 254 | 268 | |
| 255 | 269 | if (!entry || !buf) |
| 256 | 270 | return 0; |
| 257 | 271 | |
| 258 | − var->DataSize = 1024; | |
| 259 | − if (efivar_entry_get(entry, &entry->var.Attributes, | |
| 260 | − &entry->var.DataSize, entry->var.Data)) | |
| 272 | + ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); | |
| 273 | + var->DataSize = datasize; | |
| 274 | + if (ret) | |
| 261 | 275 | return -EIO; |
| 262 | 276 | |
| 263 | 277 | if (in_compat_syscall()) { |
| @@ -21,18 +21,21 @@ · 20 unmodified lines | ||
| 21 | 21 | #include "gpiolib.h" |
| 22 | 22 | #include "gpiolib-acpi.h" |
| 23 | 23 | |
| 24 | −#define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l | |
| 25 | −#define QUIRK_NO_WAKEUP 0x02l | |
| 26 | − | |
| 27 | 24 | static int run_edge_events_on_boot = -1; |
| 28 | 25 | module_param(run_edge_events_on_boot, int, 0444); |
| 29 | 26 | MODULE_PARM_DESC(run_edge_events_on_boot, |
| 30 | 27 | "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); |
| 31 | 28 | |
| 32 | −static int honor_wakeup = -1; | |
| 33 | −module_param(honor_wakeup, int, 0444); | |
| 34 | −MODULE_PARM_DESC(honor_wakeup, | |
| 35 | − "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto"); | |
| 29 | +static char *ignore_wake; | |
| 30 | +module_param(ignore_wake, charp, 0444); | |
| 31 | +MODULE_PARM_DESC(ignore_wake, | |
| 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 | 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 | 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 | 259 | /* Always returns AE_OK so that we keep looping over the resources */ |
| 206 | 260 | static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, |
| 207 | 261 | void *context) |
| @@ -289,7 +343,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, · 81 unmodified lines | ||
| 289 | 343 | event->handle = evt_handle; |
| 290 | 344 | event->handler = handler; |
| 291 | 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 | 347 | event->pin = pin; |
| 294 | 348 | event->desc = desc; |
| 295 | 349 | |
| @@ -1328,7 +1382,9 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = { · 1032 unmodified lines | ||
| 1328 | 1382 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), |
| 1329 | 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 | 1397 | DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), |
| 1342 | 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 | |
| 1349 | − * embedded-controller connected via I2C + an ACPI GPIO | |
| 1350 | − * event handler. The embedded controller generates various | |
| 1351 | − * spurious wakeup events when suspended. So disable wakeup | |
| 1352 | − * for its handler (it uses the only ACPI GPIO event handler). | |
| 1353 | − * This breaks wakeup when opening the lid, the user needs | |
| 1406 | + * HP X2 10 models with Cherry Trail SoC + TI PMIC use an | |
| 1407 | + * external embedded-controller connected via I2C + an ACPI GPIO | |
| 1408 | + * event handler on INT33FF:01 pin 0, causing spurious wakeups. | |
| 1409 | + * When suspending by closing the LID, the power to the USB | |
| 1410 | + * keyboard is turned off, causing INT0002 ACPI events to | |
| 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 | 1414 | * to press the power-button to wakeup the system. The |
| 1355 | 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 | 1418 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
| 1359 | 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 | 1455 | {} /* Terminating entry */ |
| 1364 | 1456 | }; |
| 1365 | 1457 | |
| 1366 | 1458 | static int acpi_gpio_setup_params(void) |
| 1367 | 1459 | { |
| 1460 | + const struct acpi_gpiolib_dmi_quirk *quirk = NULL; | |
| 1368 | 1461 | const struct dmi_system_id *id; |
| 1369 | − long quirks = 0; | |
| 1370 | 1462 | |
| 1371 | 1463 | id = dmi_first_match(gpiolib_acpi_quirks); |
| 1372 | 1464 | if (id) |
| 1373 | − quirks = (long)id->driver_data; | |
| 1465 | + quirk = id->driver_data; | |
| 1374 | 1466 | |
| 1375 | 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 | 1469 | run_edge_events_on_boot = 0; |
| 1378 | 1470 | else |
| 1379 | 1471 | run_edge_events_on_boot = 1; |
| 1380 | 1472 | } |
| 1381 | 1473 | |
| 1382 | − if (honor_wakeup < 0) { | |
| 1383 | − if (quirks & QUIRK_NO_WAKEUP) | |
| 1384 | − honor_wakeup = 0; | |
| 1385 | − else | |
| 1386 | − honor_wakeup = 1; | |
| 1387 | − } | |
| 1474 | + if (ignore_wake == NULL && quirk && quirk->ignore_wake) | |
| 1475 | + ignore_wake = quirk->ignore_wake; | |
| 1388 | 1476 | |
| 1389 | 1477 | return 0; |
| 1390 | 1478 | } |
| @@ -2306,9 +2306,16 @@ static void gpiochip_irq_disable(struct irq_data *d) · 2305 unmodified lines | ||
| 2306 | 2306 | { |
| 2307 | 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 | 2316 | if (chip->irq.irq_disable) |
| 2310 | 2317 | chip->irq.irq_disable(d); |
| 2311 | − else | |
| 2318 | + else if (chip->irq.chip->irq_mask) | |
| 2312 | 2319 | chip->irq.chip->irq_mask(d); |
| 2313 | 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 | 781 | ssize_t result = 0; |
| 782 | 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 | 785 | return -EINVAL; |
| 786 | 786 | |
| 787 | 787 | /* decode offset */ |
| 788 | − offset = *pos & GENMASK_ULL(11, 0); | |
| 788 | + offset = (*pos & GENMASK_ULL(11, 0)) >> 2; | |
| 789 | 789 | se = (*pos & GENMASK_ULL(19, 12)) >> 12; |
| 790 | 790 | sh = (*pos & GENMASK_ULL(27, 20)) >> 20; |
| 791 | 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 | 823 | while (size) { |
| 824 | 824 | uint32_t value; |
| 825 | 825 | |
| 826 | − value = data[offset++]; | |
| 826 | + value = data[result >> 2]; | |
| 827 | 827 | r = put_user(value, (uint32_t *)buf); |
| 828 | 828 | if (r) { |
| 829 | 829 | result = r; |
| @@ -3913,6 +3913,8 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, · 3912 unmodified lines | ||
| 3913 | 3913 | if (r) |
| 3914 | 3914 | goto out; |
| 3915 | 3915 | |
| 3916 | + amdgpu_fbdev_set_suspend(tmp_adev, 0); | |
| 3917 | + | |
| 3916 | 3918 | /* must succeed. */ |
| 3917 | 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 | 4089 | amdgpu_unregister_gpu_instance(tmp_adev); |
| 4088 | 4090 | |
| 4091 | + amdgpu_fbdev_set_suspend(adev, 1); | |
| 4092 | + | |
| 4089 | 4093 | /* disable ras on ALL IPs */ |
| 4090 | 4094 | if (!(in_ras_intr && !use_baco) && |
| 4091 | 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 | 693 | bool enable = (state == AMD_CG_STATE_GATE); |
| 694 | 694 | |
| 695 | 695 | if (enable) { |
| 696 | − if (jpeg_v2_0_is_idle(handle)) | |
| 696 | + if (!jpeg_v2_0_is_idle(handle)) | |
| 697 | 697 | return -EBUSY; |
| 698 | 698 | jpeg_v2_0_enable_clock_gating(adev); |
| 699 | 699 | } else { |
| @@ -477,7 +477,7 @@ static int jpeg_v2_5_set_clockgating_state(void *handle, · 476 unmodified lines | ||
| 477 | 477 | continue; |
| 478 | 478 | |
| 479 | 479 | if (enable) { |
| 480 | − if (jpeg_v2_5_is_idle(handle)) | |
| 480 | + if (!jpeg_v2_5_is_idle(handle)) | |
| 481 | 481 | return -EBUSY; |
| 482 | 482 | jpeg_v2_5_enable_clock_gating(adev, i); |
| 483 | 483 | } else { |
| @@ -1352,7 +1352,7 @@ static int vcn_v1_0_set_clockgating_state(void *handle, · 1351 unmodified lines | ||
| 1352 | 1352 | |
| 1353 | 1353 | if (enable) { |
| 1354 | 1354 | /* wait for STATUS to clear */ |
| 1355 | − if (vcn_v1_0_is_idle(handle)) | |
| 1355 | + if (!vcn_v1_0_is_idle(handle)) | |
| 1356 | 1356 | return -EBUSY; |
| 1357 | 1357 | vcn_v1_0_enable_clock_gating(adev); |
| 1358 | 1358 | } else { |
| @@ -1217,7 +1217,7 @@ static int vcn_v2_0_set_clockgating_state(void *handle, · 1216 unmodified lines | ||
| 1217 | 1217 | |
| 1218 | 1218 | if (enable) { |
| 1219 | 1219 | /* wait for STATUS to clear */ |
| 1220 | − if (vcn_v2_0_is_idle(handle)) | |
| 1220 | + if (!vcn_v2_0_is_idle(handle)) | |
| 1221 | 1221 | return -EBUSY; |
| 1222 | 1222 | vcn_v2_0_enable_clock_gating(adev); |
| 1223 | 1223 | } else { |
| @@ -1672,7 +1672,7 @@ static int vcn_v2_5_set_clockgating_state(void *handle, · 1671 unmodified lines | ||
| 1672 | 1672 | return 0; |
| 1673 | 1673 | |
| 1674 | 1674 | if (enable) { |
| 1675 | − if (vcn_v2_5_is_idle(handle)) | |
| 1675 | + if (!vcn_v2_5_is_idle(handle)) | |
| 1676 | 1676 | return -EBUSY; |
| 1677 | 1677 | vcn_v2_5_enable_clock_gating(adev); |
| 1678 | 1678 | } else { |
| @@ -522,8 +522,9 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 521 unmodified lines | ||
| 522 | 522 | |
| 523 | 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, | |
| 526 | − amdgpu_dm_vrr_active(acrtc_state)); | |
| 525 | + DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, | |
| 526 | + amdgpu_dm_vrr_active(acrtc_state), | |
| 527 | + acrtc_state->active_planes); | |
| 527 | 528 | |
| 528 | 529 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); |
| 529 | 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 | 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 | 559 | if (acrtc->event) { |
| 548 | 560 | drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); |
| 549 | 561 | acrtc->event = NULL; |
| @@ -3401,6 +3401,17 @@ static bool retrieve_link_cap(struct dc_link *link) · 3400 unmodified lines | ||
| 3401 | 3401 | sink_id.ieee_device_id, |
| 3402 | 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 | 3415 | core_link_read_dpcd( |
| 3405 | 3416 | link, |
| 3406 | 3417 | DP_SINK_HW_REVISION_START, |
| @@ -108,7 +108,6 @@ static const struct hwseq_private_funcs dcn20_private_funcs = { · 107 unmodified lines | ||
| 108 | 108 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, |
| 109 | 109 | .dpp_pg_control = dcn20_dpp_pg_control, |
| 110 | 110 | .hubp_pg_control = dcn20_hubp_pg_control, |
| 111 | − .dsc_pg_control = NULL, | |
| 112 | 111 | .update_odm = dcn20_update_odm, |
| 113 | 112 | .dsc_pg_control = dcn20_dsc_pg_control, |
| 114 | 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 | 116 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, |
| 117 | 117 | .dpp_pg_control = dcn20_dpp_pg_control, |
| 118 | 118 | .hubp_pg_control = dcn20_hubp_pg_control, |
| 119 | − .dsc_pg_control = NULL, | |
| 120 | 119 | .update_odm = dcn20_update_odm, |
| 121 | 120 | .dsc_pg_control = dcn20_dsc_pg_control, |
| 122 | 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 | 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 | 151 | struct komeda_drv *mdrv = dev_get_drvdata(dev); |
| 152 | 152 | |
| 153 | 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 | 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 | 156 | size = min(size, mem); |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | − if (pci_request_region(pdev, 0, "bochs-drm") != 0) { | |
| 160 | − DRM_ERROR("Cannot request framebuffer\n"); | |
| 161 | − return -EBUSY; | |
| 162 | − } | |
| 159 | + if (pci_request_region(pdev, 0, "bochs-drm") != 0) | |
| 160 | + DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); | |
| 163 | 161 | |
| 164 | 162 | bochs->fb_map = ioremap(addr, size); |
| 165 | 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 | 1624 | frame.colorspace = HDMI_COLORSPACE_RGB; |
| 1625 | 1625 | |
| 1626 | 1626 | /* Set up colorimetry */ |
| 1627 | − switch (hdmi->hdmi_data.enc_out_encoding) { | |
| 1628 | − case V4L2_YCBCR_ENC_601: | |
| 1629 | − if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) | |
| 1630 | − frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | |
| 1631 | − else | |
| 1627 | + if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { | |
| 1628 | + switch (hdmi->hdmi_data.enc_out_encoding) { | |
| 1629 | + case V4L2_YCBCR_ENC_601: | |
| 1630 | + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) | |
| 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 | 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 | 1653 | frame.extended_colorimetry = |
| 1634 | − 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; | |
| 1654 | + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | |
| 1649 | 1655 | } |
| 1650 | 1656 | |
| 1651 | 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 | 544 | DRM_DEBUG_LEASE("Creating lease\n"); |
| 545 | + /* lessee will take the ownership of leases */ | |
| 545 | 546 | lessee = drm_lease_create(lessor, &leases); |
| 546 | 547 | |
| 547 | 548 | if (IS_ERR(lessee)) { |
| 548 | 549 | ret = PTR_ERR(lessee); |
| 550 | + idr_destroy(&leases); | |
| 549 | 551 | goto out_leases; |
| 550 | 552 | } |
| 551 | 553 | |
| @@ -580,7 +582,6 @@ out_lessee: · 28 unmodified lines | ||
| 580 | 582 | |
| 581 | 583 | out_leases: |
| 582 | 584 | put_unused_fd(fd); |
| 583 | − idr_destroy(&leases); | |
| 584 | 585 | |
| 585 | 586 | DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); |
| 586 | 587 | return ret; |
| @@ -1600,17 +1600,6 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve, · 1599 unmodified lines | ||
| 1600 | 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 | 1603 | #define for_each_waiter(p__, rq__) \ |
| 1615 | 1604 | list_for_each_entry_lockless(p__, \ |
| 1616 | 1605 | &(rq__)->sched.waiters_list, \ |
| @@ -1740,11 +1729,9 @@ static void record_preemption(struct intel_engine_execlists *execlists) · 123 unmodified lines | ||
| 1740 | 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 | 1735 | if (!rq) |
| 1749 | 1736 | return 0; |
| 1750 | 1737 | |
| @@ -1755,13 +1742,14 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) · 4 unmodified lines | ||
| 1755 | 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 | 1748 | if (!intel_engine_has_preempt_reset(engine)) |
| 1761 | 1749 | return; |
| 1762 | 1750 | |
| 1763 | 1751 | set_timer_ms(&engine->execlists.preempt, |
| 1764 | − active_preempt_timeout(engine)); | |
| 1752 | + active_preempt_timeout(engine, rq)); | |
| 1765 | 1753 | } |
| 1766 | 1754 | |
| 1767 | 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 | 1762 | struct intel_engine_execlists * const execlists = &engine->execlists; |
| 1775 | 1763 | struct i915_request **port = execlists->pending; |
| 1776 | 1764 | struct i915_request ** const last_port = port + execlists->port_mask; |
| 1765 | + struct i915_request * const *active; | |
| 1777 | 1766 | struct i915_request *last; |
| 1778 | 1767 | struct rb_node *rb; |
| 1779 | 1768 | bool submit = false; |
| @@ -1828,7 +1817,10 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 48 unmodified lines | ||
| 1828 | 1817 | * i.e. we will retrigger preemption following the ack in case |
| 1829 | 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 | 1824 | if (last) { |
| 1833 | 1825 | if (need_preempt(engine, last, rb)) { |
| 1834 | 1826 | ENGINE_TRACE(engine, |
| @@ -2110,7 +2102,7 @@ done: · 275 unmodified lines | ||
| 2110 | 2102 | * Skip if we ended up with exactly the same set of requests, |
| 2111 | 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 | 2106 | (port - execlists->pending + 1) * sizeof(*port))) { |
| 2115 | 2107 | do |
| 2116 | 2108 | execlists_schedule_out(fetch_and_zero(port)); |
| @@ -2121,7 +2113,7 @@ done: · 4 unmodified lines | ||
| 2121 | 2113 | clear_ports(port + 1, last_port - port); |
| 2122 | 2114 | |
| 2123 | 2115 | execlists_submit_ports(engine); |
| 2124 | − set_preempt_timeout(engine); | |
| 2116 | + set_preempt_timeout(engine, *active); | |
| 2125 | 2117 | } else { |
| 2126 | 2118 | skip_submit: |
| 2127 | 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 | 4001 | *cs++ = preparser_disable(false); |
| 4010 | 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 | 4005 | return 0; |
| @@ -1529,15 +1529,34 @@ err_obj: · 1528 unmodified lines | ||
| 1529 | 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 | 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 | 1553 | * which only controls CPU initiated MMIO. Routing does not |
| 1537 | 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)) | |
| 1540 | − return true; | |
| 1556 | + for (i = 0; mcr_ranges_gen8[i].start; i++) | |
| 1557 | + if (offset >= mcr_ranges_gen8[i].start && | |
| 1558 | + offset <= mcr_ranges_gen8[i].end) | |
| 1559 | + return true; | |
| 1541 | 1560 | |
| 1542 | 1561 | return false; |
| 1543 | 1562 | } |
| @@ -532,6 +532,8 @@ static const struct hid_device_id hammer_devices[] = { · 531 unmodified lines | ||
| 532 | 532 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, |
| 533 | 533 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 534 | 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 | 537 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 536 | 538 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, |
| 537 | 539 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| @@ -478,6 +478,7 @@ · 477 unmodified lines | ||
| 478 | 478 | #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 |
| 479 | 479 | #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c |
| 480 | 480 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d |
| 481 | +#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 | |
| 481 | 482 | |
| 482 | 483 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
| 483 | 484 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
| @@ -726,6 +727,7 @@ · 242 unmodified lines | ||
| 726 | 727 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 |
| 727 | 728 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 |
| 728 | 729 | #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 |
| 730 | +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d | |
| 729 | 731 | |
| 730 | 732 | #define USB_VENDOR_ID_LG 0x1fd2 |
| 731 | 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 | 458 | if (ret >= PAGE_SIZE) |
| 459 | 459 | break; |
| 460 | 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 | 462 | else |
| 463 | − ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); | |
| 463 | + ret += scnprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); | |
| 464 | 464 | if (ret > 0) |
| 465 | 465 | buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n'; |
| 466 | 466 | return ret; |
| @@ -103,6 +103,7 @@ static const struct hid_device_id hid_quirks[] = { · 102 unmodified lines | ||
| 103 | 103 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, |
| 104 | 104 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, |
| 105 | 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 | 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, |
| 107 | 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, |
| 108 | 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 | 314 | while (i < ret) { |
| 315 | 315 | if (i + attribute->size > ret) { |
| 316 | − len += snprintf(&buf[len], | |
| 316 | + len += scnprintf(&buf[len], | |
| 317 | 317 | PAGE_SIZE - len, |
| 318 | 318 | "%d ", values[i]); |
| 319 | 319 | break; |
| @@ -336,10 +336,10 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr, · 16 unmodified lines | ||
| 336 | 336 | ++i; |
| 337 | 337 | break; |
| 338 | 338 | } |
| 339 | − len += snprintf(&buf[len], PAGE_SIZE - len, | |
| 339 | + len += scnprintf(&buf[len], PAGE_SIZE - len, | |
| 340 | 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 | 344 | return len; |
| 345 | 345 | } else if (input) |
| @@ -718,9 +718,6 @@ static int msc_win_set_lockout(struct msc_window *win, · 717 unmodified lines | ||
| 718 | 718 | |
| 719 | 719 | if (old != expect) { |
| 720 | 720 | ret = -EINVAL; |
| 721 | − dev_warn_ratelimited(msc_dev(win->msc), | |
| 722 | − "expected lockout state %d, got %d\n", | |
| 723 | − expect, old); | |
| 724 | 721 | goto unlock; |
| 725 | 722 | } |
| 726 | 723 | |
| @@ -741,6 +738,10 @@ unlock: · 14 unmodified lines | ||
| 741 | 738 | /* from intel_th_msc_window_unlock(), don't warn if not locked */ |
| 742 | 739 | if (expect == WIN_LOCKED && old == new) |
| 743 | 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 | 747 | return ret; |
| @@ -760,7 +761,7 @@ static int msc_configure(struct msc *msc) · 13 unmodified lines | ||
| 760 | 761 | lockdep_assert_held(&msc->buf_mutex); |
| 761 | 762 | |
| 762 | 763 | if (msc->mode > MSC_MODE_MULTI) |
| 763 | − return -ENOTSUPP; | |
| 764 | + return -EINVAL; | |
| 764 | 765 | |
| 765 | 766 | if (msc->mode == MSC_MODE_MULTI) { |
| 766 | 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 | 1295 | } else if (msc->mode == MSC_MODE_MULTI) { |
| 1295 | 1296 | ret = msc_buffer_multi_alloc(msc, nr_pages, nr_wins); |
| 1296 | 1297 | } else { |
| 1297 | − ret = -ENOTSUPP; | |
| 1298 | + ret = -EINVAL; | |
| 1298 | 1299 | } |
| 1299 | 1300 | |
| 1300 | 1301 | if (!ret) { |
| @@ -1530,7 +1531,7 @@ static ssize_t intel_th_msc_read(struct file *file, char __user *buf, · 229 unmodified lines | ||
| 1530 | 1531 | if (ret >= 0) |
| 1531 | 1532 | *ppos = iter->offset; |
| 1532 | 1533 | } else { |
| 1533 | − ret = -ENOTSUPP; | |
| 1534 | + ret = -EINVAL; | |
| 1534 | 1535 | } |
| 1535 | 1536 | |
| 1536 | 1537 | put_count: |
| @@ -234,6 +234,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { · 233 unmodified lines | ||
| 234 | 234 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), |
| 235 | 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 | 243 | /* Elkhart Lake */ |
| 239 | 244 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), |
| @@ -238,7 +238,7 @@ static struct configfs_attribute *sys_t_policy_attrs[] = { · 237 unmodified lines | ||
| 238 | 238 | static inline bool sys_t_need_ts(struct sys_t_output *op) |
| 239 | 239 | { |
| 240 | 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 | 242 | op->ts_jiffies = jiffies; |
| 243 | 243 | |
| 244 | 244 | return true; |
| @@ -250,8 +250,8 @@ static inline bool sys_t_need_ts(struct sys_t_output *op) · 5 unmodified lines | ||
| 250 | 250 | static bool sys_t_need_clock_sync(struct sys_t_output *op) |
| 251 | 251 | { |
| 252 | 252 | if (op->node.clocksync_interval && |
| 253 | − time_after(op->clocksync_jiffies + op->node.clocksync_interval, | |
| 254 | − jiffies)) { | |
| 253 | + time_after(jiffies, | |
| 254 | + op->clocksync_jiffies + op->node.clocksync_interval)) { | |
| 255 | 255 | op->clocksync_jiffies = jiffies; |
| 256 | 256 | |
| 257 | 257 | return true; |
| @@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) · 312 unmodified lines | ||
| 313 | 313 | pm_runtime_get_noresume(&pdev->dev); |
| 314 | 314 | |
| 315 | 315 | i2c_del_adapter(&dev->adapter); |
| 316 | + devm_free_irq(&pdev->dev, dev->irq, dev); | |
| 316 | 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 | 348 | if (ret == -ENOENT) |
| 349 | 349 | retdesc = ERR_PTR(-EPROBE_DEFER); |
| 350 | 350 | |
| 351 | − if (ret != -EPROBE_DEFER) | |
| 351 | + if (PTR_ERR(retdesc) != -EPROBE_DEFER) | |
| 352 | 352 | dev_err(dev, "error trying to get descriptor: %d\n", ret); |
| 353 | 353 | |
| 354 | 354 | return retdesc; |
| @@ -132,11 +132,6 @@ · 131 unmodified lines | ||
| 132 | 132 | #define TCOBASE 0x050 |
| 133 | 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 | 135 | #define SBREG_BAR 0x10 |
| 141 | 136 | #define SBREG_SMBCTRL 0xc6000c |
| 142 | 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 | 1548 | pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); |
| 1554 | 1549 | spin_unlock(&p2sb_spinlock); |
| 1555 | 1550 | |
| 1556 | − res = &tco_res[ICH_RES_MEM_OFF]; | |
| 1551 | + res = &tco_res[1]; | |
| 1557 | 1552 | if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) |
| 1558 | 1553 | res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; |
| 1559 | 1554 | else |
| @@ -1563,7 +1558,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, · 3 unmodified lines | ||
| 1563 | 1558 | res->flags = IORESOURCE_MEM; |
| 1564 | 1559 | |
| 1565 | 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 | 1562 | sizeof(spt_tco_platform_data)); |
| 1568 | 1563 | } |
| 1569 | 1564 | |
| @@ -1576,17 +1571,16 @@ static struct platform_device * · 6 unmodified lines | ||
| 1576 | 1571 | i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, |
| 1577 | 1572 | struct resource *tco_res) |
| 1578 | 1573 | { |
| 1579 | − return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, | |
| 1580 | − tco_res, 2, &cnl_tco_platform_data, | |
| 1581 | − sizeof(cnl_tco_platform_data)); | |
| 1574 | + return platform_device_register_resndata(&pci_dev->dev, | |
| 1575 | + "iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data, | |
| 1576 | + sizeof(cnl_tco_platform_data)); | |
| 1582 | 1577 | } |
| 1583 | 1578 | |
| 1584 | 1579 | static void i801_add_tco(struct i801_priv *priv) |
| 1585 | 1580 | { |
| 1586 | − u32 base_addr, tco_base, tco_ctl, ctrl_val; | |
| 1587 | 1581 | struct pci_dev *pci_dev = priv->pci_dev; |
| 1588 | − struct resource tco_res[3], *res; | |
| 1589 | − unsigned int devfn; | |
| 1582 | + struct resource tco_res[2], *res; | |
| 1583 | + u32 tco_base, tco_ctl; | |
| 1590 | 1584 | |
| 1591 | 1585 | /* If we have ACPI based watchdog use that instead */ |
| 1592 | 1586 | if (acpi_has_watchdog()) |
| @@ -1601,30 +1595,15 @@ static void i801_add_tco(struct i801_priv *priv) · 8 unmodified lines | ||
| 1601 | 1595 | return; |
| 1602 | 1596 | |
| 1603 | 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); | |
| 1614 | − pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr); | |
| 1615 | − | |
| 1616 | − res = &tco_res[ICH_RES_IO_SMI]; | |
| 1617 | − res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF; | |
| 1618 | − res->end = res->start + 3; | |
| 1602 | + res = &tco_res[0]; | |
| 1603 | + res->start = tco_base & ~1; | |
| 1604 | + res->end = res->start + 32 - 1; | |
| 1619 | 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 | 1607 | if (priv->features & FEATURE_TCO_CNL) |
| 1629 | 1608 | priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); |
| 1630 | 1609 | else |
| @@ -394,9 +394,17 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); · 393 unmodified lines | ||
| 394 | 394 | static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) |
| 395 | 395 | { |
| 396 | 396 | struct device *dev; |
| 397 | + struct i2c_client *client; | |
| 397 | 398 | |
| 398 | 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 | 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 | 237 | .realbits = 12, \ |
| 238 | 238 | .storagebits = 16, \ |
| 239 | 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 | 111 | #ifdef CONFIG_ACPI |
| 112 | 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 | 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 | 724 | for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { |
| 725 | 725 | struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); |
| 726 | + u32 cor; | |
| 726 | 727 | |
| 727 | 728 | if (!chan) |
| 728 | 729 | continue; |
| @@ -731,6 +732,20 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 2 unmodified lines | ||
| 731 | 732 | chan->type == IIO_PRESSURE) |
| 732 | 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 | 749 | if (state) { |
| 735 | 750 | at91_adc_writel(st, AT91_SAMA5D2_CHER, |
| 736 | 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 | 845 | static void stm32_dfsdm_dma_buffer_done(void *data) |
| 871 | 846 | { |
| 872 | 847 | struct iio_dev *indio_dev = data; |
| @@ -874,11 +849,6 @@ static void stm32_dfsdm_dma_buffer_done(void *data) · 1 unmodified line | ||
| 874 | 849 | int available = stm32_dfsdm_adc_dma_residue(adc); |
| 875 | 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 | 853 | * FIXME: In Kernel interface does not support cyclic DMA buffer,and |
| 884 | 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 | 876 | adc->bufi = 0; |
| 907 | 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 | 888 | if (adc->dev_data->type == DFSDM_IIO) |
| 911 | 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 | 1516 | ret = iio_triggered_buffer_setup(indio_dev, |
| 1539 | − &iio_pollfunc_store_time, | |
| 1540 | − &stm32_dfsdm_adc_trigger_handler, | |
| 1517 | + &iio_pollfunc_store_time, NULL, | |
| 1541 | 1518 | &stm32_dfsdm_buffer_setup_ops); |
| 1542 | 1519 | if (ret) { |
| 1543 | 1520 | stm32_dfsdm_dma_release(indio_dev); |
| @@ -91,6 +91,8 @@ config SPS30 · 90 unmodified lines | ||
| 91 | 91 | tristate "SPS30 particulate matter sensor" |
| 92 | 92 | depends on I2C |
| 93 | 93 | select CRC8 |
| 94 | + select IIO_BUFFER | |
| 95 | + select IIO_TRIGGERED_BUFFER | |
| 94 | 96 | help |
| 95 | 97 | Say Y here to build support for the Sensirion SPS30 particulate |
| 96 | 98 | matter sensor. |
| @@ -167,16 +167,17 @@ static int vcnl4200_init(struct vcnl4000_data *data) · 166 unmodified lines | ||
| 167 | 167 | data->vcnl4200_ps.reg = VCNL4200_PS_DATA; |
| 168 | 168 | switch (id) { |
| 169 | 169 | case VCNL4200_PROD_ID: |
| 170 | − /* Integration time is 50ms, but the experiments */ | |
| 171 | − /* show 54ms in total. */ | |
| 172 | − data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000); | |
| 173 | − data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000); | |
| 170 | + /* Default wait time is 50ms, add 20% tolerance. */ | |
| 171 | + data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000); | |
| 172 | + /* Default wait time is 4.8ms, add 20% tolerance. */ | |
| 173 | + data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000); | |
| 174 | 174 | data->al_scale = 24000; |
| 175 | 175 | break; |
| 176 | 176 | case VCNL4040_PROD_ID: |
| 177 | − /* Integration time is 80ms, add 10ms. */ | |
| 178 | − data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000); | |
| 179 | − data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000); | |
| 177 | + /* Default wait time is 80ms, add 20% tolerance. */ | |
| 178 | + data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000); | |
| 179 | + /* Default wait time is 5ms, add 20% tolerance. */ | |
| 180 | + data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000); | |
| 180 | 181 | data->al_scale = 120000; |
| 181 | 182 | break; |
| 182 | 183 | } |
| @@ -564,7 +564,7 @@ static int ak8974_read_raw(struct iio_dev *indio_dev, · 563 unmodified lines | ||
| 564 | 564 | * We read all axes and discard all but one, for optimized |
| 565 | 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 | 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 | 270 | static const struct of_device_id of_ping_match[] = { |
| 271 | 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 | 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 | 167 | u32 ccer, cr1; |
| 167 | 168 | |
| @@ -179,6 +180,12 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv) · 11 unmodified lines | ||
| 179 | 180 | regmap_write(priv->regmap, TIM_PSC, 0); |
| 180 | 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 | 189 | /* Make sure that registers are updated */ |
| 183 | 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 | 204 | return ret; |
| 198 | 205 | |
| 199 | 206 | if (freq == 0) { |
| 200 | − stm32_timer_stop(priv); | |
| 207 | + stm32_timer_stop(priv, trig); | |
| 201 | 208 | } else { |
| 202 | 209 | ret = stm32_timer_start(priv, trig, freq); |
| 203 | 210 | if (ret) |
| @@ -3826,7 +3826,7 @@ int amd_iommu_activate_guest_mode(void *data) · 3825 unmodified lines | ||
| 3826 | 3826 | entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; |
| 3827 | 3827 | |
| 3828 | 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 | 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 | 3852 | APICID_TO_IRTE_DEST_HI(cfg->dest_apicid); |
| 3853 | 3853 | |
| 3854 | 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 | 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 | 177 | start -= iova_offset(iovad, start); |
| 178 | 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 | 180 | for (i = 0; i < num_pages; i++) { |
| 185 | − msi_page[i].phys = start; | |
| 186 | − msi_page[i].iova = start; | |
| 187 | − INIT_LIST_HEAD(&msi_page[i].list); | |
| 188 | − list_add(&msi_page[i].list, &cookie->msi_page_list); | |
| 181 | + msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); | |
| 182 | + if (!msi_page) | |
| 183 | + return -ENOMEM; | |
| 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 | 189 | start += iovad->granule; |
| 190 | 190 | } |
| 191 | 191 | |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/slab.h> |
| 29 | 29 | #include <linux/iommu.h> |
| 30 | 30 | #include <linux/numa.h> |
| 31 | +#include <linux/limits.h> | |
| 31 | 32 | #include <asm/irq_remapping.h> |
| 32 | 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 | 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 | 139 | /* Only generate path[] for device addition event */ |
| 132 | 140 | if (event == BUS_NOTIFY_ADD_DEVICE) |
| 133 | 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 | 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 | 376 | if (dmaru->segment == drhd->segment && |
| 368 | 377 | dmaru->reg_base_addr == drhd->address) |
| 369 | 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 | 450 | /* Check for NUL termination within the designated length */ |
| 442 | 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 | 453 | "Your BIOS is broken; ANDD object name is not NUL-terminated\n" |
| 445 | 454 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 446 | 455 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 447 | 456 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 448 | 457 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 458 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 449 | 459 | return -EINVAL; |
| 450 | 460 | } |
| 451 | 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 | 481 | return 0; |
| 472 | 482 | } |
| 473 | 483 | } |
| 474 | − WARN_TAINT( | |
| 475 | − 1, TAINT_FIRMWARE_WORKAROUND, | |
| 484 | + pr_warn(FW_BUG | |
| 476 | 485 | "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" |
| 477 | 486 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 478 | − drhd->reg_base_addr, | |
| 487 | + rhsa->base_address, | |
| 479 | 488 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 480 | 489 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 481 | 490 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 491 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 482 | 492 | |
| 483 | 493 | return 0; |
| 484 | 494 | } |
| @@ -827,14 +837,14 @@ int __init dmar_table_init(void) · 342 unmodified lines | ||
| 827 | 837 | |
| 828 | 838 | static void warn_invalid_dmar(u64 addr, const char *message) |
| 829 | 839 | { |
| 830 | − WARN_TAINT_ONCE( | |
| 831 | − 1, TAINT_FIRMWARE_WORKAROUND, | |
| 840 | + pr_warn_once(FW_BUG | |
| 832 | 841 | "Your BIOS is broken; DMAR reported at address %llx%s!\n" |
| 833 | 842 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 834 | 843 | addr, message, |
| 835 | 844 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 836 | 845 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 837 | 846 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 847 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 838 | 848 | } |
| 839 | 849 | |
| 840 | 850 | static int __ref |
| @@ -33,38 +33,42 @@ struct iommu_regset { · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #define IOMMU_REGSET_ENTRY(_reg_) \ |
| 35 | 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 | 38 | IOMMU_REGSET_ENTRY(VER), |
| 38 | − IOMMU_REGSET_ENTRY(CAP), | |
| 39 | − IOMMU_REGSET_ENTRY(ECAP), | |
| 40 | 39 | IOMMU_REGSET_ENTRY(GCMD), |
| 41 | 40 | IOMMU_REGSET_ENTRY(GSTS), |
| 42 | − IOMMU_REGSET_ENTRY(RTADDR), | |
| 43 | − IOMMU_REGSET_ENTRY(CCMD), | |
| 44 | 41 | IOMMU_REGSET_ENTRY(FSTS), |
| 45 | 42 | IOMMU_REGSET_ENTRY(FECTL), |
| 46 | 43 | IOMMU_REGSET_ENTRY(FEDATA), |
| 47 | 44 | IOMMU_REGSET_ENTRY(FEADDR), |
| 48 | 45 | IOMMU_REGSET_ENTRY(FEUADDR), |
| 49 | − IOMMU_REGSET_ENTRY(AFLOG), | |
| 50 | 46 | IOMMU_REGSET_ENTRY(PMEN), |
| 51 | 47 | IOMMU_REGSET_ENTRY(PLMBASE), |
| 52 | 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 | 63 | IOMMU_REGSET_ENTRY(PHMBASE), |
| 54 | 64 | IOMMU_REGSET_ENTRY(PHMLIMIT), |
| 55 | 65 | IOMMU_REGSET_ENTRY(IQH), |
| 56 | 66 | IOMMU_REGSET_ENTRY(IQT), |
| 57 | 67 | IOMMU_REGSET_ENTRY(IQA), |
| 58 | − IOMMU_REGSET_ENTRY(ICS), | |
| 59 | 68 | IOMMU_REGSET_ENTRY(IRTA), |
| 60 | 69 | IOMMU_REGSET_ENTRY(PQH), |
| 61 | 70 | IOMMU_REGSET_ENTRY(PQT), |
| 62 | 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 | 72 | IOMMU_REGSET_ENTRY(MTRRCAP), |
| 69 | 73 | IOMMU_REGSET_ENTRY(MTRRDEF), |
| 70 | 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 | 131 | * by adding the offset to the pointer (virtual address). |
| 128 | 132 | */ |
| 129 | 133 | raw_spin_lock_irqsave(&iommu->register_lock, flag); |
| 130 | − for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) { | |
| 131 | − value = dmar_readq(iommu->reg + iommu_regs[i].offset); | |
| 134 | + for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) { | |
| 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 | 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 | 144 | value); |
| 135 | 145 | } |
| 136 | 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 | 283 | struct dmar_drhd_unit *drhd; |
| 274 | 284 | struct intel_iommu *iommu; |
| 285 | + u32 sts; | |
| 275 | 286 | |
| 276 | 287 | rcu_read_lock(); |
| 277 | 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 | 295 | root_tbl_walk(m, iommu); |
| 279 | 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 | 432 | struct dmar_drhd_unit *drhd; |
| 416 | 433 | struct intel_iommu *iommu; |
| 417 | 434 | u64 irta; |
| 435 | + u32 sts; | |
| 418 | 436 | |
| 419 | 437 | rcu_read_lock(); |
| 420 | 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 | 442 | seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n", |
| 425 | 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 | 447 | irta = virt_to_phys(iommu->ir_table->base); |
| 429 | 448 | seq_printf(m, " IR table address:%llx\n", irta); |
| 430 | 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 | 4262 | /* we know that the this iommu should be at offset 0xa000 from vtbar */ |
| 4263 | 4263 | drhd = dmar_find_matched_drhd_unit(pdev); |
| 4264 | − if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, | |
| 4265 | − TAINT_FIRMWARE_WORKAROUND, | |
| 4266 | − "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) | |
| 4264 | + if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { | |
| 4265 | + pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); | |
| 4266 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 4267 | 4267 | pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; |
| 4268 | + } | |
| 4268 | 4269 | } |
| 4269 | 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 | 4461 | struct dmar_rmrr_unit *rmrru; |
| 4461 | 4462 | |
| 4462 | 4463 | rmrr = (struct acpi_dmar_reserved_memory *)header; |
| 4463 | − if (rmrr_sanity_check(rmrr)) | |
| 4464 | − WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | |
| 4464 | + if (rmrr_sanity_check(rmrr)) { | |
| 4465 | + pr_warn(FW_BUG | |
| 4465 | 4466 | "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" |
| 4466 | 4467 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 4467 | 4468 | rmrr->base_address, rmrr->end_address, |
| 4468 | 4469 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 4469 | 4470 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 4470 | 4471 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 4472 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 4473 | + } | |
| 4471 | 4474 | |
| 4472 | 4475 | rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); |
| 4473 | 4476 | if (!rmrru) |
| @@ -5130,6 +5133,9 @@ int __init intel_iommu_init(void) · 656 unmodified lines | ||
| 5130 | 5133 | |
| 5131 | 5134 | down_write(&dmar_global_lock); |
| 5132 | 5135 | |
| 5136 | + if (!no_iommu) | |
| 5137 | + intel_iommu_debugfs_init(); | |
| 5138 | + | |
| 5133 | 5139 | if (no_iommu || dmar_disabled) { |
| 5134 | 5140 | /* |
| 5135 | 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 | 5200 | init_iommu_pm_ops(); |
| 5195 | 5201 | |
| 5202 | + down_read(&dmar_global_lock); | |
| 5196 | 5203 | for_each_active_iommu(iommu, drhd) { |
| 5197 | 5204 | iommu_device_sysfs_add(&iommu->iommu, NULL, |
| 5198 | 5205 | intel_iommu_groups, |
| @@ -5200,6 +5207,7 @@ int __init intel_iommu_init(void) · 1 unmodified line | ||
| 5200 | 5207 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); |
| 5201 | 5208 | iommu_device_register(&iommu->iommu); |
| 5202 | 5209 | } |
| 5210 | + up_read(&dmar_global_lock); | |
| 5203 | 5211 | |
| 5204 | 5212 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); |
| 5205 | 5213 | if (si_domain && !hw_pass_through) |
| @@ -5210,7 +5218,6 @@ int __init intel_iommu_init(void) · 4 unmodified lines | ||
| 5210 | 5218 | down_read(&dmar_global_lock); |
| 5211 | 5219 | if (probe_acpi_namespace_devices()) |
| 5212 | 5220 | pr_warn("ACPI name space devices didn't probe correctly\n"); |
| 5213 | − up_read(&dmar_global_lock); | |
| 5214 | 5221 | |
| 5215 | 5222 | /* Finally, we enable the DMA remapping hardware. */ |
| 5216 | 5223 | for_each_iommu(iommu, drhd) { |
| @@ -5219,10 +5226,11 @@ int __init intel_iommu_init(void) · 2 unmodified lines | ||
| 5219 | 5226 | |
| 5220 | 5227 | iommu_disable_protect_mem_regions(iommu); |
| 5221 | 5228 | } |
| 5229 | + up_read(&dmar_global_lock); | |
| 5230 | + | |
| 5222 | 5231 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); |
| 5223 | 5232 | |
| 5224 | 5233 | intel_iommu_enabled = 1; |
| 5225 | − intel_iommu_debugfs_init(); | |
| 5226 | 5234 | |
| 5227 | 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 | 5708 | u64 phys = 0; |
| 5701 | 5709 | |
| 5702 | 5710 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); |
| 5703 | − if (pte) | |
| 5704 | − phys = dma_pte_addr(pte); | |
| 5711 | + if (pte && dma_pte_present(pte)) | |
| 5712 | + phys = dma_pte_addr(pte) + | |
| 5713 | + (iova & (BIT_MASK(level_to_offset_bits(level) + | |
| 5714 | + VTD_PAGE_SHIFT) - 1)); | |
| 5705 | 5715 | |
| 5706 | 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 | 468 | arm_lpae_iopte *ptep = data->pgd; |
| 469 | 469 | int ret, lvl = data->start_level; |
| 470 | 470 | arm_lpae_iopte prot; |
| 471 | − long iaext = (long)iova >> cfg->ias; | |
| 471 | + long iaext = (s64)iova >> cfg->ias; | |
| 472 | 472 | |
| 473 | 473 | /* If no access, then nothing to do */ |
| 474 | 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 | 645 | struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); |
| 646 | 646 | struct io_pgtable_cfg *cfg = &data->iop.cfg; |
| 647 | 647 | arm_lpae_iopte *ptep = data->pgd; |
| 648 | − long iaext = (long)iova >> cfg->ias; | |
| 648 | + long iaext = (s64)iova >> cfg->ias; | |
| 649 | 649 | |
| 650 | 650 | if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) |
| 651 | 651 | return 0; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80) |
| 35 | 35 | |
| 36 | 36 | #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) |
| 37 | +#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) | |
| 37 | 38 | |
| 38 | 39 | struct redist_region { |
| 39 | 40 | void __iomem *redist_base; |
| @@ -1464,6 +1465,15 @@ static bool gic_enable_quirk_msm8996(void *data) · 1424 unmodified lines | ||
| 1464 | 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 | 1477 | static bool gic_enable_quirk_hip06_07(void *data) |
| 1468 | 1478 | { |
| 1469 | 1479 | struct gic_chip_data *d = data; |
| @@ -1502,6 +1512,19 @@ static const struct gic_quirk gic_quirks[] = { · 32 unmodified lines | ||
| 1502 | 1512 | .mask = 0xffffffff, |
| 1503 | 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 | 1600 | pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); |
| 1578 | 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 | 1610 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, |
| 1583 | 1611 | &gic_data); |
| @@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = { · 311 unmodified lines | ||
| 312 | 312 | }; |
| 313 | 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 | 321 | static struct i2c_driver wf_ad7417_driver = { |
| 316 | 322 | .driver = { |
| 317 | 323 | .name = "wf_ad7417", |
| 324 | + .of_match_table = wf_ad7417_of_id, | |
| 318 | 325 | }, |
| 319 | 326 | .probe = wf_ad7417_probe, |
| 320 | 327 | .remove = wf_ad7417_remove, |
| @@ -580,9 +580,16 @@ static const struct i2c_device_id wf_fcu_id[] = { · 579 unmodified lines | ||
| 580 | 580 | }; |
| 581 | 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 | 589 | static struct i2c_driver wf_fcu_driver = { |
| 584 | 590 | .driver = { |
| 585 | 591 | .name = "wf_fcu", |
| 592 | + .of_match_table = wf_fcu_of_id, | |
| 586 | 593 | }, |
| 587 | 594 | .probe = wf_fcu_probe, |
| 588 | 595 | .remove = wf_fcu_remove, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/init.h> |
| 15 | 15 | #include <linux/wait.h> |
| 16 | 16 | #include <linux/i2c.h> |
| 17 | +#include <linux/of_device.h> | |
| 17 | 18 | #include <asm/prom.h> |
| 18 | 19 | #include <asm/machdep.h> |
| 19 | 20 | #include <asm/io.h> |
| @@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client, · 71 unmodified lines | ||
| 91 | 92 | const struct i2c_device_id *id) |
| 92 | 93 | { |
| 93 | 94 | struct wf_lm75_sensor *lm; |
| 94 | − int rc, ds1775 = id->driver_data; | |
| 95 | + int rc, ds1775; | |
| 95 | 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 | 103 | DBG("wf_lm75: creating %s device at address 0x%02x\n", |
| 98 | 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 | 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 | 180 | static struct i2c_driver wf_lm75_driver = { |
| 168 | 181 | .driver = { |
| 169 | 182 | .name = "wf_lm75", |
| 183 | + .of_match_table = wf_lm75_of_id, | |
| 170 | 184 | }, |
| 171 | 185 | .probe = wf_lm75_probe, |
| 172 | 186 | .remove = wf_lm75_remove, |
| @@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = { · 165 unmodified lines | ||
| 166 | 166 | }; |
| 167 | 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 | 175 | static struct i2c_driver wf_lm87_driver = { |
| 170 | 176 | .driver = { |
| 171 | 177 | .name = "wf_lm87", |
| 178 | + .of_match_table = wf_lm87_of_id, | |
| 172 | 179 | }, |
| 173 | 180 | .probe = wf_lm87_probe, |
| 174 | 181 | .remove = wf_lm87_remove, |
| @@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = { · 119 unmodified lines | ||
| 120 | 120 | }; |
| 121 | 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 | 129 | static struct i2c_driver wf_max6690_driver = { |
| 124 | 130 | .driver = { |
| 125 | 131 | .name = "wf_max6690", |
| 132 | + .of_match_table = wf_max6690_of_id, | |
| 126 | 133 | }, |
| 127 | 134 | .probe = wf_max6690_probe, |
| 128 | 135 | .remove = wf_max6690_remove, |
| @@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = { · 340 unmodified lines | ||
| 341 | 341 | }; |
| 342 | 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 | 350 | static struct i2c_driver wf_sat_driver = { |
| 345 | 351 | .driver = { |
| 346 | 352 | .name = "wf_smu_sat", |
| 353 | + .of_match_table = wf_sat_of_id, | |
| 347 | 354 | }, |
| 348 | 355 | .probe = wf_sat_probe, |
| 349 | 356 | .remove = wf_sat_remove, |
| @@ -394,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = { · 393 unmodified lines | ||
| 394 | 394 | void rts522a_init_params(struct rtsx_pcr *pcr) |
| 395 | 395 | { |
| 396 | 396 | rts5227_init_params(pcr); |
| 397 | − | |
| 397 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 20, 11); | |
| 398 | 398 | pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; |
| 399 | 399 | |
| 400 | 400 | pcr->option.ocp_en = 1; |
| @@ -618,6 +618,7 @@ static const struct pcr_ops rts524a_pcr_ops = { · 617 unmodified lines | ||
| 618 | 618 | void rts524a_init_params(struct rtsx_pcr *pcr) |
| 619 | 619 | { |
| 620 | 620 | rts5249_init_params(pcr); |
| 621 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); | |
| 621 | 622 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
| 622 | 623 | pcr->option.ltr_l1off_snooze_sspwrgate = |
| 623 | 624 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
| @@ -733,6 +734,7 @@ static const struct pcr_ops rts525a_pcr_ops = { · 109 unmodified lines | ||
| 733 | 734 | void rts525a_init_params(struct rtsx_pcr *pcr) |
| 734 | 735 | { |
| 735 | 736 | rts5249_init_params(pcr); |
| 737 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(25, 29, 11); | |
| 736 | 738 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
| 737 | 739 | pcr->option.ltr_l1off_snooze_sspwrgate = |
| 738 | 740 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
| @@ -662,7 +662,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr) · 661 unmodified lines | ||
| 662 | 662 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
| 663 | 663 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
| 664 | 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 | 666 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
| 667 | 667 | |
| 668 | 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 | 764 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
| 765 | 765 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
| 766 | 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 | 768 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
| 769 | 769 | |
| 770 | 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 | 712 | * chip is functional. |
| 713 | 713 | */ |
| 714 | 714 | err = at24_read(at24, 0, &test_byte, 1); |
| 715 | − pm_runtime_idle(dev); | |
| 716 | 715 | if (err) { |
| 717 | 716 | pm_runtime_disable(dev); |
| 718 | 717 | regulator_disable(at24->vcc_reg); |
| 719 | 718 | return -ENODEV; |
| 720 | 719 | } |
| 721 | 720 | |
| 721 | + pm_runtime_idle(dev); | |
| 722 | + | |
| 722 | 723 | if (writable) |
| 723 | 724 | dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n", |
| 724 | 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 | 1732 | * the erase operation does not exceed the max_busy_timeout, we should |
| 1733 | 1733 | * use R1B response. Or we need to prevent the host from doing hw busy |
| 1734 | 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 | 1740 | busy_timeout > card->host->max_busy_timeout) { |
| 1738 | 1741 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
| 1739 | 1742 | } else { |
| @@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host) · 1909 unmodified lines | ||
| 1910 | 1910 | * If the max_busy_timeout of the host is specified, validate it against |
| 1911 | 1911 | * the sleep cmd timeout. A failure means we need to prevent the host |
| 1912 | 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 | 1919 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 1917 | 1920 | } else { |
| 1918 | 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 | 542 | * If the max_busy_timeout of the host is specified, make sure it's |
| 543 | 543 | * enough to fit the used timeout_ms. In case it's not, let's instruct |
| 544 | 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 | 550 | use_r1b_resp = false; |
| 549 | 551 | |
| 550 | 552 | cmd.opcode = MMC_SWITCH; |
| @@ -606,19 +606,22 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host, · 605 unmodified lines | ||
| 606 | 606 | u8 sample_point, bool rx) |
| 607 | 607 | { |
| 608 | 608 | struct rtsx_pcr *pcr = host->pcr; |
| 609 | − | |
| 609 | + u16 SD_VP_CTL = 0; | |
| 610 | 610 | dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", |
| 611 | 611 | __func__, rx ? "RX" : "TX", sample_point); |
| 612 | 612 | |
| 613 | 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 | 616 | rtsx_pci_write_register(pcr, SD_VPRX_CTL, |
| 616 | 617 | PHASE_SELECT_MASK, sample_point); |
| 617 | − else | |
| 618 | + } else { | |
| 619 | + SD_VP_CTL = SD_VPTX_CTL; | |
| 618 | 620 | rtsx_pci_write_register(pcr, SD_VPTX_CTL, |
| 619 | 621 | PHASE_SELECT_MASK, sample_point); |
| 620 | − rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); | |
| 621 | − rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, | |
| 622 | + } | |
| 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 | 625 | PHASE_NOT_RESET); |
| 623 | 626 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, 0); |
| 624 | 627 | rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/pm.h> |
| 24 | 24 | #include <linux/pm_runtime.h> |
| 25 | 25 | #include <linux/delay.h> |
| 26 | +#include <linux/dmi.h> | |
| 26 | 27 | |
| 27 | 28 | #include <linux/mmc/host.h> |
| 28 | 29 | #include <linux/mmc/pm.h> |
| @@ -72,9 +73,16 @@ struct sdhci_acpi_host { · 43 unmodified lines | ||
| 72 | 73 | const struct sdhci_acpi_slot *slot; |
| 73 | 74 | struct platform_device *pdev; |
| 74 | 75 | bool use_runtime_pm; |
| 76 | + bool is_intel; | |
| 77 | + bool reset_signal_volt_on_suspend; | |
| 75 | 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 | 86 | static inline void *sdhci_acpi_priv(struct sdhci_acpi_host *c) |
| 79 | 87 | { |
| 80 | 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 | 399 | host->mmc_host_ops.start_signal_voltage_switch = |
| 392 | 400 | intel_start_signal_voltage_switch; |
| 393 | 401 | |
| 402 | + c->is_intel = true; | |
| 403 | + | |
| 394 | 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 | 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 | 690 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(struct acpi_device *adev) |
| 651 | 691 | { |
| 652 | 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 | 703 | struct device *dev = &pdev->dev; |
| 664 | 704 | const struct sdhci_acpi_slot *slot; |
| 665 | 705 | struct acpi_device *device, *child; |
| 706 | + const struct dmi_system_id *id; | |
| 666 | 707 | struct sdhci_acpi_host *c; |
| 667 | 708 | struct sdhci_host *host; |
| 668 | 709 | struct resource *iomem; |
| 669 | 710 | resource_size_t len; |
| 670 | 711 | size_t priv_size; |
| 712 | + int quirks = 0; | |
| 671 | 713 | int err; |
| 672 | 714 | |
| 673 | 715 | device = ACPI_COMPANION(dev); |
| 674 | 716 | if (!device) |
| 675 | 717 | return -ENODEV; |
| 676 | 718 | |
| 719 | + id = dmi_first_match(sdhci_acpi_quirks); | |
| 720 | + if (id) | |
| 721 | + quirks = (long)id->driver_data; | |
| 722 | + | |
| 677 | 723 | slot = sdhci_acpi_get_slot(device); |
| 678 | 724 | |
| 679 | 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 | 805 | dev_warn(dev, "failed to setup card detect gpio\n"); |
| 760 | 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 | 816 | err = sdhci_setup_host(host); |
| @@ -823,17 +875,39 @@ static int sdhci_acpi_remove(struct platform_device *pdev) · 58 unmodified lines | ||
| 823 | 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 | 894 | #ifdef CONFIG_PM_SLEEP |
| 827 | 895 | |
| 828 | 896 | static int sdhci_acpi_suspend(struct device *dev) |
| 829 | 897 | { |
| 830 | 898 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 831 | 899 | struct sdhci_host *host = c->host; |
| 900 | + int ret; | |
| 832 | 901 | |
| 833 | 902 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
| 834 | 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 | 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 | 928 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 855 | 929 | struct sdhci_host *host = c->host; |
| 930 | + int ret; | |
| 856 | 931 | |
| 857 | 932 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
| 858 | 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 | 943 | static int sdhci_acpi_runtime_resume(struct device *dev) |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/mmc/host.h> |
| 12 | 12 | #include <linux/mmc/mmc.h> |
| 13 | 13 | #include <linux/of.h> |
| 14 | +#include <linux/of_device.h> | |
| 14 | 15 | |
| 15 | 16 | #include "sdhci-pltfm.h" |
| 16 | 17 | |
| @@ -235,6 +236,11 @@ static const struct sdhci_ops sdhci_cdns_ops = { · 218 unmodified lines | ||
| 235 | 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 | 244 | static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { |
| 239 | 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 | 340 | static int sdhci_cdns_probe(struct platform_device *pdev) |
| 335 | 341 | { |
| 336 | 342 | struct sdhci_host *host; |
| 343 | + const struct sdhci_pltfm_data *data; | |
| 337 | 344 | struct sdhci_pltfm_host *pltfm_host; |
| 338 | 345 | struct sdhci_cdns_priv *priv; |
| 339 | 346 | struct clk *clk; |
| @@ -350,8 +357,12 @@ static int sdhci_cdns_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 350 | 357 | if (ret) |
| 351 | 358 | return ret; |
| 352 | 359 | |
| 360 | + data = of_device_get_match_data(dev); | |
| 361 | + if (!data) | |
| 362 | + data = &sdhci_cdns_pltfm_data; | |
| 363 | + | |
| 353 | 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 | 366 | struct_size(priv, phy_params, nr_phy_params)); |
| 356 | 367 | if (IS_ERR(host)) { |
| 357 | 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 | 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 | 449 | { .compatible = "cdns,sd4hc" }, |
| 436 | 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 | 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 | 137 | sdhci_at91_set_force_card_detect(host); |
| 137 | 138 | |
| 138 | 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 | 428 | * detection procedure using the SDMCC_CD signal is bypassed. |
| 428 | 429 | * This bit is reset when a software reset for all command is performed |
| 429 | 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 | 436 | sdhci_at91_set_force_card_detect(host); |
| 433 | 437 | |
| 434 | 438 | pm_runtime_put_autosuspend(&pdev->dev); |
| @@ -1192,6 +1192,9 @@ static int sdhci_omap_probe(struct platform_device *pdev) · 1191 unmodified lines | ||
| 1192 | 1192 | if (of_find_property(dev->of_node, "dmas", NULL)) |
| 1193 | 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 | 1198 | ret = sdhci_setup_host(host); |
| 1196 | 1199 | if (ret) |
| 1197 | 1200 | goto err_put_sync; |
| @@ -1552,6 +1552,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev) · 1551 unmodified lines | ||
| 1552 | 1552 | if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) |
| 1553 | 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 | 1558 | tegra_sdhci_parse_dt(host); |
| 1556 | 1559 | |
| 1557 | 1560 | tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", |
| @@ -149,6 +149,7 @@ config NET_FC · 148 unmodified lines | ||
| 149 | 149 | config IFB |
| 150 | 150 | tristate "Intermediate Functional Block support" |
| 151 | 151 | depends on NET_CLS_ACT |
| 152 | + select NET_REDIRECT | |
| 152 | 153 | ---help--- |
| 153 | 154 | This is an intermediate driver that allows sharing of |
| 154 | 155 | resources. |
| @@ -141,29 +141,29 @@ static ssize_t dbgfs_state(struct file *file, char __user *user_buf, · 140 unmodified lines | ||
| 141 | 141 | return 0; |
| 142 | 142 | |
| 143 | 143 | /* Print out debug information. */ |
| 144 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 145 | − "CAIF SPI debug information:\n"); | |
| 146 | − | |
| 147 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR); | |
| 148 | − | |
| 149 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 150 | − "STATE: %d\n", cfspi->dbg_state); | |
| 151 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 152 | − "Previous CMD: 0x%x\n", cfspi->pcmd); | |
| 153 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 154 | − "Current CMD: 0x%x\n", cfspi->cmd); | |
| 155 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 156 | − "Previous TX len: %d\n", cfspi->tx_ppck_len); | |
| 157 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 158 | − "Previous RX len: %d\n", cfspi->rx_ppck_len); | |
| 159 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 160 | − "Current TX len: %d\n", cfspi->tx_cpck_len); | |
| 161 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 162 | − "Current RX len: %d\n", cfspi->rx_cpck_len); | |
| 163 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 164 | − "Next TX len: %d\n", cfspi->tx_npck_len); | |
| 165 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 166 | − "Next RX len: %d\n", cfspi->rx_npck_len); | |
| 144 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 145 | + "CAIF SPI debug information:\n"); | |
| 146 | + | |
| 147 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR); | |
| 148 | + | |
| 149 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 150 | + "STATE: %d\n", cfspi->dbg_state); | |
| 151 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 152 | + "Previous CMD: 0x%x\n", cfspi->pcmd); | |
| 153 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 154 | + "Current CMD: 0x%x\n", cfspi->cmd); | |
| 155 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 156 | + "Previous TX len: %d\n", cfspi->tx_ppck_len); | |
| 157 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 158 | + "Previous RX len: %d\n", cfspi->rx_ppck_len); | |
| 159 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 160 | + "Current TX len: %d\n", cfspi->tx_cpck_len); | |
| 161 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 162 | + "Current RX len: %d\n", cfspi->rx_cpck_len); | |
| 163 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 164 | + "Next TX len: %d\n", cfspi->tx_npck_len); | |
| 165 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 166 | + "Next RX len: %d\n", cfspi->rx_npck_len); | |
| 167 | 167 | |
| 168 | 168 | if (len > DEBUGFS_BUF_SIZE) |
| 169 | 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 | 180 | int len = 0; |
| 181 | 181 | int i; |
| 182 | 182 | for (i = 0; i < count; i++) { |
| 183 | − len += snprintf((buf + len), (size - len), | |
| 183 | + len += scnprintf((buf + len), (size - len), | |
| 184 | 184 | "[0x" BYTE_HEX_FMT "]", |
| 185 | 185 | frm[i]); |
| 186 | 186 | if ((i == cut) && (count > (cut * 2))) { |
| 187 | 187 | /* Fast forward. */ |
| 188 | 188 | i = count - cut; |
| 189 | − len += snprintf((buf + len), (size - len), | |
| 190 | − "--- %zu bytes skipped ---\n", | |
| 191 | − count - (cut * 2)); | |
| 189 | + len += scnprintf((buf + len), (size - len), | |
| 190 | + "--- %zu bytes skipped ---\n", | |
| 191 | + count - (cut * 2)); | |
| 192 | 192 | } |
| 193 | 193 | |
| 194 | 194 | if ((!(i % 10)) && i) { |
| 195 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 196 | − "\n"); | |
| 195 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 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 | 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 | 214 | return 0; |
| 215 | 215 | |
| 216 | 216 | /* Print out debug information. */ |
| 217 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 218 | − "Current frame:\n"); | |
| 217 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 218 | + "Current frame:\n"); | |
| 219 | 219 | |
| 220 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 221 | − "Tx data (Len: %d):\n", cfspi->tx_cpck_len); | |
| 220 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 221 | + "Tx data (Len: %d):\n", cfspi->tx_cpck_len); | |
| 222 | 222 | |
| 223 | 223 | len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 224 | 224 | cfspi->xfer.va_tx[0], |
| 225 | 225 | (cfspi->tx_cpck_len + SPI_CMD_SZ), 100); |
| 226 | 226 | |
| 227 | − len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 228 | − "Rx data (Len: %d):\n", cfspi->rx_cpck_len); | |
| 227 | + len += scnprintf((buf + len), (DEBUGFS_BUF_SIZE - len), | |
| 228 | + "Rx data (Len: %d):\n", cfspi->rx_cpck_len); | |
| 229 | 229 | |
| 230 | 230 | len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), |
| 231 | 231 | cfspi->xfer.va_rx, |
| @@ -622,7 +622,10 @@ err_free_chan: · 621 unmodified lines | ||
| 622 | 622 | tty->disc_data = NULL; |
| 623 | 623 | clear_bit(SLF_INUSE, &sl->flags); |
| 624 | 624 | slc_free_netdev(sl->dev); |
| 625 | + /* do not call free_netdev before rtnl_unlock */ | |
| 626 | + rtnl_unlock(); | |
| 625 | 627 | free_netdev(sl->dev); |
| 628 | + return err; | |
| 626 | 629 | |
| 627 | 630 | err_exit: |
| 628 | 631 | rtnl_unlock(); |
| @@ -566,7 +566,7 @@ mt7530_mib_reset(struct dsa_switch *ds) · 565 unmodified lines | ||
| 566 | 566 | static void |
| 567 | 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 | 571 | if (enable) |
| 572 | 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 | 1502 | mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 | |
| 1503 | 1503 | PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN); |
| 1504 | 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 | 1507 | /* Are we connected to external phy */ |
| 1508 | 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 | 1015 | struct ena_rx_buffer *rx_info; |
| 1016 | 1016 | |
| 1017 | 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 | 1019 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1023 | 1020 | |
| 1024 | − | |
| 1025 | 1021 | rc = ena_alloc_rx_page(rx_ring, rx_info, |
| 1026 | 1022 | GFP_ATOMIC | __GFP_COMP); |
| 1027 | 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 | 1372 | struct ena_rx_buffer *rx_info; |
| 1377 | 1373 | u16 len, req_id, buf = 0; |
| 1378 | 1374 | void *va; |
| 1375 | + int rc; | |
| 1379 | 1376 | |
| 1380 | 1377 | len = ena_bufs[buf].len; |
| 1381 | 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 | 1384 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1383 | 1385 | |
| 1384 | 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 | 1453 | buf++; |
| 1452 | 1454 | len = ena_bufs[buf].len; |
| 1453 | 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 | 1461 | rx_info = &rx_ring->rx_buffer_info[req_id]; |
| 1455 | 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 | 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 | 1976 | netif_dbg(adapter, probe, adapter->netdev, |
| 1970 | 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 | 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 | 2076 | unsigned long flags = 0; |
| 2069 | 2077 | struct ena_irq *irq; |
| 2070 | 2078 | int rc = 0, i, k; |
| @@ -2075,7 +2083,7 @@ static int ena_request_io_irq(struct ena_adapter *adapter) · 4 unmodified lines | ||
| 2075 | 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 | 2087 | irq = &adapter->irq_tbl[i]; |
| 2080 | 2088 | rc = request_irq(irq->vector, irq->handler, flags, irq->name, |
| 2081 | 2089 | irq->data); |
| @@ -2116,6 +2124,7 @@ static void ena_free_mgmnt_irq(struct ena_adapter *adapter) · 34 unmodified lines | ||
| 2116 | 2124 | |
| 2117 | 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 | 2128 | struct ena_irq *irq; |
| 2120 | 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 | 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 | 2139 | irq = &adapter->irq_tbl[i]; |
| 2131 | 2140 | irq_set_affinity_hint(irq->vector, NULL); |
| 2132 | 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 | 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 | 2154 | int i; |
| 2145 | 2155 | |
| 2146 | 2156 | if (!netif_running(adapter->netdev)) |
| 2147 | 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 | 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 | 3485 | mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); |
| 3476 | 3486 | dev_err(&pdev->dev, "Device reset completed successfully\n"); |
| 3487 | + adapter->last_keep_alive_jiffies = jiffies; | |
| 3477 | 3488 | |
| 3478 | 3489 | return rc; |
| 3479 | 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 | 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 | |
| 4325 | − * that it should release a PCI device. | |
| 4336 | + * __ena_shutoff is a helper routine that does the real work on shutdown and | |
| 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 | 4342 | struct ena_adapter *adapter = pci_get_drvdata(pdev); |
| 4330 | 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 | 4357 | cancel_work_sync(&adapter->reset_task); |
| 4345 | 4358 | |
| 4346 | − rtnl_lock(); | |
| 4359 | + rtnl_lock(); /* lock released inside the below if-else block */ | |
| 4347 | 4360 | ena_destroy_device(adapter, true); |
| 4348 | − rtnl_unlock(); | |
| 4349 | − | |
| 4350 | − unregister_netdev(netdev); | |
| 4351 | − | |
| 4352 | − free_netdev(netdev); | |
| 4361 | + if (shutdown) { | |
| 4362 | + netif_device_detach(netdev); | |
| 4363 | + dev_close(netdev); | |
| 4364 | + rtnl_unlock(); | |
| 4365 | + } else { | |
| 4366 | + rtnl_unlock(); | |
| 4367 | + unregister_netdev(netdev); | |
| 4368 | + free_netdev(netdev); | |
| 4369 | + } | |
| 4353 | 4370 | |
| 4354 | 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 | 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 | 4408 | #ifdef CONFIG_PM |
| 4368 | 4409 | /* ena_suspend - PM suspend callback |
| 4369 | 4410 | * @pdev: PCI device information struct |
| @@ -4413,6 +4454,7 @@ static struct pci_driver ena_pci_driver = { · 43 unmodified lines | ||
| 4413 | 4454 | .id_table = ena_pci_tbl, |
| 4414 | 4455 | .probe = ena_probe, |
| 4415 | 4456 | .remove = ena_remove, |
| 4457 | + .shutdown = ena_shutdown, | |
| 4416 | 4458 | #ifdef CONFIG_PM |
| 4417 | 4459 | .suspend = ena_suspend, |
| 4418 | 4460 | .resume = ena_resume, |
| @@ -6860,12 +6860,12 @@ skip_rdma: · 6859 unmodified lines | ||
| 6860 | 6860 | } |
| 6861 | 6861 | ena |= FUNC_BACKING_STORE_CFG_REQ_DFLT_ENABLES; |
| 6862 | 6862 | rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); |
| 6863 | − if (rc) | |
| 6863 | + if (rc) { | |
| 6864 | 6864 | netdev_err(bp->dev, "Failed configuring context mem, rc = %d.\n", |
| 6865 | 6865 | rc); |
| 6866 | − else | |
| 6867 | − ctx->flags |= BNXT_CTX_FLAG_INITED; | |
| 6868 | − | |
| 6866 | + return rc; | |
| 6867 | + } | |
| 6868 | + ctx->flags |= BNXT_CTX_FLAG_INITED; | |
| 6869 | 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 | 7384 | pri2cos = &resp2->pri0_cos_queue_id; |
| 7385 | 7385 | for (i = 0; i < 8; i++) { |
| 7386 | 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 | 7395 | for (j = 0; j < bp->max_q; j++) { |
| 7389 | 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 | 7400 | bp->pri2cos_valid = 1; |
| 7394 | 7401 | } |
| 7402 | +qstats_done: | |
| 7395 | 7403 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 7396 | 7404 | return rc; |
| 7397 | 7405 | } |
| @@ -11644,6 +11652,10 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) · 4246 unmodified lines | ||
| 11644 | 11652 | bp->rx_nr_rings++; |
| 11645 | 11653 | bp->cp_nr_rings++; |
| 11646 | 11654 | } |
| 11655 | + if (rc) { | |
| 11656 | + bp->tx_nr_rings = 0; | |
| 11657 | + bp->rx_nr_rings = 0; | |
| 11658 | + } | |
| 11647 | 11659 | return rc; |
| 11648 | 11660 | } |
| 11649 | 11661 | |
| @@ -11929,12 +11941,12 @@ init_err_pci_clean: · 279 unmodified lines | ||
| 11929 | 11941 | bnxt_hwrm_func_drv_unrgtr(bp); |
| 11930 | 11942 | bnxt_free_hwrm_short_cmd_req(bp); |
| 11931 | 11943 | bnxt_free_hwrm_resources(bp); |
| 11932 | − bnxt_free_ctx_mem(bp); | |
| 11933 | − kfree(bp->ctx); | |
| 11934 | − bp->ctx = NULL; | |
| 11935 | 11944 | kfree(bp->fw_health); |
| 11936 | 11945 | bp->fw_health = NULL; |
| 11937 | 11946 | bnxt_cleanup_pci(bp); |
| 11947 | + bnxt_free_ctx_mem(bp); | |
| 11948 | + kfree(bp->ctx); | |
| 11949 | + bp->ctx = NULL; | |
| 11938 | 11950 | |
| 11939 | 11951 | init_err_free: |
| 11940 | 11952 | free_netdev(dev); |
| @@ -1718,7 +1718,7 @@ struct bnxt { · 1717 unmodified lines | ||
| 1718 | 1718 | u16 fw_rx_stats_ext_size; |
| 1719 | 1719 | u16 fw_tx_stats_ext_size; |
| 1720 | 1720 | u16 hw_ring_stats_size; |
| 1721 | − u8 pri2cos[8]; | |
| 1721 | + u8 pri2cos_idx[8]; | |
| 1722 | 1722 | u8 pri2cos_valid; |
| 1723 | 1723 | |
| 1724 | 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 | 473 | struct bnxt *bp = netdev_priv(dev); |
| 474 | 474 | struct ieee_ets *my_ets = bp->ieee_ets; |
| 475 | + int rc; | |
| 475 | 476 | |
| 476 | 477 | ets->ets_cap = bp->max_tc; |
| 477 | 478 | |
| 478 | 479 | if (!my_ets) { |
| 479 | − int rc; | |
| 480 | − | |
| 481 | 480 | if (bp->dcbx_cap & DCB_CAP_DCBX_HOST) |
| 482 | 481 | return 0; |
| 483 | 482 | |
| 484 | 483 | my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL); |
| 485 | 484 | if (!my_ets) |
| 486 | − return 0; | |
| 485 | + return -ENOMEM; | |
| 487 | 486 | rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets); |
| 488 | 487 | if (rc) |
| 489 | − return 0; | |
| 488 | + goto error; | |
| 490 | 489 | rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets); |
| 491 | 490 | if (rc) |
| 492 | − return 0; | |
| 491 | + goto error; | |
| 492 | + | |
| 493 | + /* cache result */ | |
| 494 | + bp->ieee_ets = my_ets; | |
| 493 | 495 | } |
| 494 | 496 | |
| 495 | 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 | 500 | memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); |
| 499 | 501 | memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); |
| 500 | 502 | return 0; |
| 503 | +error: | |
| 504 | + kfree(my_ets); | |
| 505 | + return rc; | |
| 501 | 506 | } |
| 502 | 507 | |
| 503 | 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 | 589 | if (bp->pri2cos_valid) { |
| 590 | 590 | for (i = 0; i < 8; i++, j++) { |
| 591 | 591 | long n = bnxt_rx_bytes_pri_arr[i].base_off + |
| 592 | − bp->pri2cos[i]; | |
| 592 | + bp->pri2cos_idx[i]; | |
| 593 | 593 | |
| 594 | 594 | buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); |
| 595 | 595 | } |
| 596 | 596 | for (i = 0; i < 8; i++, j++) { |
| 597 | 597 | long n = bnxt_rx_pkts_pri_arr[i].base_off + |
| 598 | − bp->pri2cos[i]; | |
| 598 | + bp->pri2cos_idx[i]; | |
| 599 | 599 | |
| 600 | 600 | buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); |
| 601 | 601 | } |
| 602 | 602 | for (i = 0; i < 8; i++, j++) { |
| 603 | 603 | long n = bnxt_tx_bytes_pri_arr[i].base_off + |
| 604 | − bp->pri2cos[i]; | |
| 604 | + bp->pri2cos_idx[i]; | |
| 605 | 605 | |
| 606 | 606 | buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); |
| 607 | 607 | } |
| 608 | 608 | for (i = 0; i < 8; i++, j++) { |
| 609 | 609 | long n = bnxt_tx_pkts_pri_arr[i].base_off + |
| 610 | − bp->pri2cos[i]; | |
| 610 | + bp->pri2cos_idx[i]; | |
| 611 | 611 | |
| 612 | 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 | 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 | 98 | static inline void dmadesc_set_addr(struct bcmgenet_priv *priv, |
| 105 | 99 | void __iomem *d, |
| 106 | 100 | dma_addr_t addr) |
| @@ -509,61 +503,6 @@ static int bcmgenet_set_link_ksettings(struct net_device *dev, · 402 unmodified lines | ||
| 509 | 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 | 506 | static int bcmgenet_set_features(struct net_device *dev, |
| 568 | 507 | netdev_features_t features) |
| 569 | 508 | { |
| @@ -579,9 +518,6 @@ static int bcmgenet_set_features(struct net_device *dev, · 9 unmodified lines | ||
| 579 | 518 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 580 | 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 | 521 | clk_disable_unprepare(priv->clk); |
| 586 | 522 | |
| 587 | 523 | return ret; |
| @@ -1474,8 +1410,8 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev) · 886 unmodified lines | ||
| 1474 | 1410 | /* Reallocate the SKB to put enough headroom in front of it and insert |
| 1475 | 1411 | * the transmit checksum offsets in the descriptors |
| 1476 | 1412 | */ |
| 1477 | −static struct sk_buff *bcmgenet_put_tx_csum(struct net_device *dev, | |
| 1478 | − struct sk_buff *skb) | |
| 1413 | +static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev, | |
| 1414 | + struct sk_buff *skb) | |
| 1479 | 1415 | { |
| 1480 | 1416 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 1481 | 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 | 1526 | GENET_CB(skb)->bytes_sent = skb->len; |
| 1591 | 1527 | |
| 1592 | − /* set the SKB transmit checksum */ | |
| 1593 | − if (priv->desc_64b_en) { | |
| 1594 | − skb = bcmgenet_put_tx_csum(dev, skb); | |
| 1595 | − if (!skb) { | |
| 1596 | − ret = NETDEV_TX_OK; | |
| 1597 | − goto out; | |
| 1598 | − } | |
| 1528 | + /* add the Transmit Status Block */ | |
| 1529 | + skb = bcmgenet_add_tsb(dev, skb); | |
| 1530 | + if (!skb) { | |
| 1531 | + ret = NETDEV_TX_OK; | |
| 1532 | + goto out; | |
| 1599 | 1533 | } |
| 1600 | 1534 | |
| 1601 | 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 | 1709 | while ((rxpktprocessed < rxpkttoprocess) && |
| 1776 | 1710 | (rxpktprocessed < budget)) { |
| 1711 | + struct status_64 *status; | |
| 1712 | + __be16 rx_csum; | |
| 1713 | + | |
| 1777 | 1714 | cb = &priv->rx_cbs[ring->read_ptr]; |
| 1778 | 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 | 1719 | goto next; |
| 1783 | 1720 | } |
| 1784 | 1721 | |
| 1785 | − if (!priv->desc_64b_en) { | |
| 1786 | − dma_length_status = | |
| 1787 | − dmadesc_get_length_status(priv, cb->bd_addr); | |
| 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; | |
| 1722 | + status = (struct status_64 *)skb->data; | |
| 1723 | + dma_length_status = status->length_status; | |
| 1724 | + if (dev->features & NETIF_F_RXCSUM) { | |
| 1794 | 1725 | rx_csum = (__force __be16)(status->rx_csum & 0xffff); |
| 1795 | − if (priv->desc_rxchk_en) { | |
| 1796 | − skb->csum = (__force __wsum)ntohs(rx_csum); | |
| 1797 | − skb->ip_summed = CHECKSUM_COMPLETE; | |
| 1798 | − } | |
| 1726 | + skb->csum = (__force __wsum)ntohs(rx_csum); | |
| 1727 | + skb->ip_summed = CHECKSUM_COMPLETE; | |
| 1799 | 1728 | } |
| 1800 | 1729 | |
| 1801 | 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 | 1768 | } /* error packet */ |
| 1840 | 1769 | |
| 1841 | 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 */ | |
| 1848 | − skb_pull(skb, 2); | |
| 1849 | − len -= 2; | |
| 1772 | + /* remove RSB and hardware 2bytes added for IP alignment */ | |
| 1773 | + skb_pull(skb, 66); | |
| 1774 | + len -= 66; | |
| 1850 | 1775 | |
| 1851 | 1776 | if (priv->crc_fwd_en) { |
| 1852 | 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 | 1889 | u32 reg; |
| 1965 | 1890 | |
| 1966 | 1891 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 1892 | + if (reg & CMD_SW_RESET) | |
| 1893 | + return; | |
| 1967 | 1894 | if (enable) |
| 1968 | 1895 | reg |= mask; |
| 1969 | 1896 | else |
| @@ -1983,11 +1910,9 @@ static void reset_umac(struct bcmgenet_priv *priv) · 13 unmodified lines | ||
| 1983 | 1910 | bcmgenet_rbuf_ctrl_set(priv, 0); |
| 1984 | 1911 | udelay(10); |
| 1985 | 1912 | |
| 1986 | − /* disable MAC while updating its registers */ | |
| 1987 | − bcmgenet_umac_writel(priv, 0, UMAC_CMD); | |
| 1988 | − | |
| 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); | |
| 1913 | + /* issue soft reset and disable MAC while updating its registers */ | |
| 1914 | + bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); | |
| 1915 | + udelay(2); | |
| 1991 | 1916 | } |
| 1992 | 1917 | |
| 1993 | 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 | 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 | 1971 | reg = bcmgenet_rbuf_readl(priv, RBUF_CTRL); |
| 2042 | − reg |= RBUF_ALIGN_2B; | |
| 1972 | + reg |= RBUF_ALIGN_2B | RBUF_64B_EN; | |
| 2043 | 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 | 1987 | if (!GENET_IS_V1(priv) && !GENET_IS_V2(priv)) |
| 2046 | 1988 | bcmgenet_rbuf_writel(priv, 1, RBUF_TBUF_SIZE_CTRL); |
| 2047 | 1989 | |
| @@ -273,6 +273,7 @@ struct bcmgenet_mib_counters { · 272 unmodified lines | ||
| 273 | 273 | #define RBUF_FLTR_LEN_SHIFT 8 |
| 274 | 274 | |
| 275 | 275 | #define TBUF_CTRL 0x00 |
| 276 | +#define TBUF_64B_EN (1 << 0) | |
| 276 | 277 | #define TBUF_BP_MC 0x0C |
| 277 | 278 | #define TBUF_ENERGY_CTRL 0x14 |
| 278 | 279 | #define TBUF_EEE_EN (1 << 0) |
| @@ -662,8 +663,6 @@ struct bcmgenet_priv { · 383 unmodified lines | ||
| 662 | 663 | unsigned int irq0_stat; |
| 663 | 664 | |
| 664 | 665 | /* HW descriptors/checksum variables */ |
| 665 | − bool desc_64b_en; | |
| 666 | − bool desc_rxchk_en; | |
| 667 | 666 | bool crc_fwd_en; |
| 668 | 667 | |
| 669 | 668 | u32 dma_max_burst_length; |
| @@ -132,8 +132,12 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, · 131 unmodified lines | ||
| 132 | 132 | return -EINVAL; |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | − /* disable RX */ | |
| 135 | + /* Can't suspend with WoL if MAC is still in reset */ | |
| 136 | 136 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 137 | + if (reg & CMD_SW_RESET) | |
| 138 | + reg &= ~CMD_SW_RESET; | |
| 139 | + | |
| 140 | + /* disable RX */ | |
| 137 | 141 | reg &= ~CMD_RX_EN; |
| 138 | 142 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); |
| 139 | 143 | mdelay(10); |
| @@ -95,6 +95,12 @@ void bcmgenet_mii_setup(struct net_device *dev) · 94 unmodified lines | ||
| 95 | 95 | CMD_HD_EN | |
| 96 | 96 | CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE); |
| 97 | 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 | 104 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); |
| 99 | 105 | } else { |
| 100 | 106 | /* done if nothing has changed */ |
| @@ -181,38 +187,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) · 80 unmodified lines | ||
| 181 | 187 | const char *phy_name = NULL; |
| 182 | 188 | u32 id_mode_dis = 0; |
| 183 | 189 | u32 port_ctrl; |
| 184 | − int bmcr = -1; | |
| 185 | − int ret; | |
| 186 | 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 | 192 | switch (priv->phy_interface) { |
| 217 | 193 | case PHY_INTERFACE_MODE_INTERNAL: |
| 218 | 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 | 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 | 261 | priv->ext_phy = !priv->internal_phy && |
| 290 | 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 | 1033 | adapter->tids.tid_tab[i]; |
| 1034 | 1034 | |
| 1035 | 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 | 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 | 1041 | f = (struct filter_entry *)adapter->tids.tid_tab[i]; |
| 1042 | 1042 | |
| 1043 | 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 | 246 | FW_PTP_CMD_PORTID_V(0)); |
| 247 | 247 | c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16)); |
| 248 | 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 | 252 | c.u.ts.tm = cpu_to_be64(delta); |
| 250 | 253 | |
| 251 | 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 | 1307 | int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq, |
| 1308 | 1308 | int maxreclaim) |
| 1309 | 1309 | { |
| 1310 | + unsigned int reclaimed, hw_cidx; | |
| 1310 | 1311 | struct sge_txq *q = &eq->q; |
| 1311 | − unsigned int reclaimed; | |
| 1312 | + int hw_in_use; | |
| 1312 | 1313 | |
| 1313 | 1314 | if (!q->in_use || !__netif_tx_trylock(eq->txq)) |
| 1314 | 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 | 1317 | /* Reclaim pending completed TX Descriptors. */ |
| 1317 | 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 | 1325 | /* If the TX Queue is currently stopped and there's now more than half |
| 1320 | 1326 | * the queue available, restart it. Otherwise bail out since the rest |
| 1321 | 1327 | * of what we want do here is with the possibility of shipping any |
| 1322 | 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 | 1331 | netif_tx_wake_queue(eq->txq); |
| 1326 | 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 | 1497 | * has opened up. |
| 1492 | 1498 | */ |
| 1493 | 1499 | eth_txq_stop(q); |
| 1494 | − | |
| 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; | |
| 1500 | + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; | |
| 1504 | 1501 | } |
| 1505 | 1502 | |
| 1506 | 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 | 1807 | * has opened up. |
| 1811 | 1808 | */ |
| 1812 | 1809 | eth_txq_stop(txq); |
| 1813 | − | |
| 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; | |
| 1810 | + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; | |
| 1823 | 1811 | } |
| 1824 | 1812 | |
| 1825 | 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 | 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 | 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 | 778 | /* Set full duplex */ |
| 779 | 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 | 782 | /* Configure RGMII in manual mode */ |
| 783 | 783 | tmp &= ~IF_MODE_RGMII_AUTO; |
| 784 | 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 | 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 | 394 | spin_lock_bh(&cmdq->cmdq_lock); |
| 394 | 395 | |
| 395 | 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 | 624 | if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info))) |
| 624 | 625 | return -EBUSY; |
| 625 | 626 | |
| 627 | + dma_rmb(); | |
| 628 | + | |
| 626 | 629 | errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL); |
| 627 | 630 | |
| 628 | 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 | 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 | 364 | * clear_io_resource - set the IO resources as not active in the NIC |
| 409 | 365 | * @hwdev: the NIC HW device |
| @@ -423,11 +379,8 @@ static int clear_io_resources(struct hinic_hwdev *hwdev) · 13 unmodified lines | ||
| 423 | 379 | return -EINVAL; |
| 424 | 380 | } |
| 425 | 381 | |
| 426 | − err = wait_for_io_stopped(hwdev); | |
| 427 | − if (err) { | |
| 428 | − dev_err(&pdev->dev, "IO has not stopped yet\n"); | |
| 429 | − return err; | |
| 430 | − } | |
| 382 | + /* sleep 100ms to wait for firmware stopping I/O */ | |
| 383 | + msleep(100); | |
| 431 | 384 | |
| 432 | 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 | 188 | * eq_update_ci - update the HW cons idx of event queue |
| 189 | 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 | 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 | 203 | val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) | |
| 204 | 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 | 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 | 235 | if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped) |
| 236 | 236 | break; |
| 237 | 237 | |
| 238 | + dma_rmb(); | |
| 239 | + | |
| 238 | 240 | event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE); |
| 239 | 241 | if (event >= HINIC_MAX_AEQ_EVENTS) { |
| 240 | 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 | 349 | else if (eq->type == HINIC_CEQ) |
| 348 | 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 | 706 | set_eq_ctrls(eq); |
| 705 | − eq_update_ci(eq); | |
| 707 | + eq_update_ci(eq, EQ_ARMED); | |
| 706 | 708 | |
| 707 | 709 | err = alloc_eq_pages(eq); |
| 708 | 710 | if (err) { |
| @@ -752,18 +754,28 @@ err_req_irq: · 43 unmodified lines | ||
| 752 | 754 | **/ |
| 753 | 755 | static void remove_eq(struct hinic_eq *eq) |
| 754 | 756 | { |
| 755 | − struct msix_entry *entry = &eq->msix_entry; | |
| 756 | − | |
| 757 | − free_irq(entry->vector, eq); | |
| 757 | + hinic_set_msix_state(eq->hwif, eq->msix_entry.entry, | |
| 758 | + HINIC_MSIX_DISABLE); | |
| 759 | + free_irq(eq->msix_entry.vector, eq); | |
| 758 | 760 | |
| 759 | 761 | if (eq->type == HINIC_AEQ) { |
| 760 | 762 | struct hinic_eq_work *aeq_work = &eq->aeq_work; |
| 761 | 763 | |
| 762 | 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 | 768 | } else if (eq->type == HINIC_CEQ) { |
| 764 | 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 | 779 | free_eq_pages(eq); |
| 768 | 780 | } |
| 769 | 781 | |
| @@ -43,7 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | #define MSG_NOT_RESP 0xFFFF |
| 45 | 45 | |
| 46 | −#define MGMT_MSG_TIMEOUT 1000 | |
| 46 | +#define MGMT_MSG_TIMEOUT 5000 | |
| 47 | 47 | |
| 48 | 48 | #define mgmt_to_pfhwdev(pf_mgmt) \ |
| 49 | 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 | 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 | 272 | dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id); |
| 272 | 273 | err = -ETIMEDOUT; |
| 273 | 274 | goto unlock_sync_msg; |
| @@ -350,6 +350,9 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget) · 349 unmodified lines | ||
| 350 | 350 | if (!rq_wqe) |
| 351 | 351 | break; |
| 352 | 352 | |
| 353 | + /* make sure we read rx_done before packet length */ | |
| 354 | + dma_rmb(); | |
| 355 | + | |
| 353 | 356 | cqe = rq->cqe[ci]; |
| 354 | 357 | status = be32_to_cpu(cqe->status); |
| 355 | 358 | hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge); |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 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 | 50 | #define MAX_PAYLOAD_OFFSET 221 |
| 51 | 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 | 622 | do { |
| 623 | 623 | hw_ci = HW_CONS_IDX(sq) & wq->mask; |
| 624 | 624 | |
| 625 | + dma_rmb(); | |
| 626 | + | |
| 625 | 627 | /* Reading a WQEBB to get real WQE size and consumer index. */ |
| 626 | 628 | sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci); |
| 627 | 629 | if ((!sq_wqe) || |
| @@ -364,8 +364,8 @@ static int orion_mdio_probe(struct platform_device *pdev) · 363 unmodified lines | ||
| 364 | 364 | writel(MVMDIO_ERR_INT_SMI_DONE, |
| 365 | 365 | dev->regs + MVMDIO_ERR_INT_MASK); |
| 366 | 366 | |
| 367 | − } else if (dev->err_interrupt < 0) { | |
| 368 | − ret = dev->err_interrupt; | |
| 367 | + } else if (dev->err_interrupt == -EPROBE_DEFER) { | |
| 368 | + ret = -EPROBE_DEFER; | |
| 369 | 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 | 3109 | /* For the case where the last mvneta_poll did not process all |
| 3110 | 3110 | * RX packets |
| 3111 | 3111 | */ |
| 3112 | − rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); | |
| 3113 | − | |
| 3114 | 3112 | cause_rx_tx |= pp->neta_armada3700 ? pp->cause_rx_tx : |
| 3115 | 3113 | port->cause_rx_tx; |
| 3116 | 3114 | |
| 3115 | + rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); | |
| 3117 | 3116 | if (rx_queue) { |
| 3118 | 3117 | rx_queue = rx_queue - 1; |
| 3119 | 3118 | if (pp->bm_priv) |
| @@ -906,59 +906,59 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, · 905 unmodified lines | ||
| 906 | 906 | int len = 0; |
| 907 | 907 | |
| 908 | 908 | mlx4_err(dev, "%s", str); |
| 909 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 910 | − "port = %d prio = 0x%x qp = 0x%x ", | |
| 911 | − rule->port, rule->priority, rule->qpn); | |
| 909 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 910 | + "port = %d prio = 0x%x qp = 0x%x ", | |
| 911 | + rule->port, rule->priority, rule->qpn); | |
| 912 | 912 | |
| 913 | 913 | list_for_each_entry(cur, &rule->list, list) { |
| 914 | 914 | switch (cur->id) { |
| 915 | 915 | case MLX4_NET_TRANS_RULE_ID_ETH: |
| 916 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 917 | − "dmac = %pM ", &cur->eth.dst_mac); | |
| 916 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 917 | + "dmac = %pM ", &cur->eth.dst_mac); | |
| 918 | 918 | if (cur->eth.ether_type) |
| 919 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 920 | − "ethertype = 0x%x ", | |
| 921 | − be16_to_cpu(cur->eth.ether_type)); | |
| 919 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 920 | + "ethertype = 0x%x ", | |
| 921 | + be16_to_cpu(cur->eth.ether_type)); | |
| 922 | 922 | if (cur->eth.vlan_id) |
| 923 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 924 | − "vlan-id = %d ", | |
| 925 | − be16_to_cpu(cur->eth.vlan_id)); | |
| 923 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 924 | + "vlan-id = %d ", | |
| 925 | + be16_to_cpu(cur->eth.vlan_id)); | |
| 926 | 926 | break; |
| 927 | 927 | |
| 928 | 928 | case MLX4_NET_TRANS_RULE_ID_IPV4: |
| 929 | 929 | if (cur->ipv4.src_ip) |
| 930 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 931 | − "src-ip = %pI4 ", | |
| 932 | − &cur->ipv4.src_ip); | |
| 930 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 931 | + "src-ip = %pI4 ", | |
| 932 | + &cur->ipv4.src_ip); | |
| 933 | 933 | if (cur->ipv4.dst_ip) |
| 934 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 935 | − "dst-ip = %pI4 ", | |
| 936 | − &cur->ipv4.dst_ip); | |
| 934 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 935 | + "dst-ip = %pI4 ", | |
| 936 | + &cur->ipv4.dst_ip); | |
| 937 | 937 | break; |
| 938 | 938 | |
| 939 | 939 | case MLX4_NET_TRANS_RULE_ID_TCP: |
| 940 | 940 | case MLX4_NET_TRANS_RULE_ID_UDP: |
| 941 | 941 | if (cur->tcp_udp.src_port) |
| 942 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 943 | − "src-port = %d ", | |
| 944 | − be16_to_cpu(cur->tcp_udp.src_port)); | |
| 942 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 943 | + "src-port = %d ", | |
| 944 | + be16_to_cpu(cur->tcp_udp.src_port)); | |
| 945 | 945 | if (cur->tcp_udp.dst_port) |
| 946 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 947 | − "dst-port = %d ", | |
| 948 | − be16_to_cpu(cur->tcp_udp.dst_port)); | |
| 946 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 947 | + "dst-port = %d ", | |
| 948 | + be16_to_cpu(cur->tcp_udp.dst_port)); | |
| 949 | 949 | break; |
| 950 | 950 | |
| 951 | 951 | case MLX4_NET_TRANS_RULE_ID_IB: |
| 952 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 953 | − "dst-gid = %pI6\n", cur->ib.dst_gid); | |
| 954 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 955 | − "dst-gid-mask = %pI6\n", | |
| 956 | − cur->ib.dst_gid_msk); | |
| 952 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 953 | + "dst-gid = %pI6\n", cur->ib.dst_gid); | |
| 954 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 955 | + "dst-gid-mask = %pI6\n", | |
| 956 | + cur->ib.dst_gid_msk); | |
| 957 | 957 | break; |
| 958 | 958 | |
| 959 | 959 | case MLX4_NET_TRANS_RULE_ID_VXLAN: |
| 960 | − len += snprintf(buf + len, BUF_SIZE - len, | |
| 961 | − "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); | |
| 960 | + len += scnprintf(buf + len, BUF_SIZE - len, | |
| 961 | + "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); | |
| 962 | 962 | break; |
| 963 | 963 | case MLX4_NET_TRANS_RULE_ID_IPV6: |
| 964 | 964 | break; |
| @@ -967,7 +967,7 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, · 2 unmodified lines | ||
| 967 | 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 | 971 | mlx4_err(dev, "%s", buf); |
| 972 | 972 | |
| 973 | 973 | if (len >= BUF_SIZE) |
| @@ -371,6 +371,7 @@ enum { · 370 unmodified lines | ||
| 371 | 371 | |
| 372 | 372 | struct mlx5e_sq_wqe_info { |
| 373 | 373 | u8 opcode; |
| 374 | + u8 num_wqebbs; | |
| 374 | 375 | |
| 375 | 376 | /* Auxiliary data for different opcodes. */ |
| 376 | 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 | 1078 | void mlx5e_activate_rq(struct mlx5e_rq *rq); |
| 1078 | 1079 | void mlx5e_deactivate_rq(struct mlx5e_rq *rq); |
| 1079 | 1080 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq); |
| 1081 | +void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq); | |
| 1080 | 1082 | void mlx5e_activate_icosq(struct mlx5e_icosq *icosq); |
| 1081 | 1083 | void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq); |
| 1082 | 1084 | |
| @@ -11,8 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | static inline bool cqe_syndrome_needs_recover(u8 syndrome) |
| 13 | 13 | { |
| 14 | − return syndrome == MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR || | |
| 15 | − syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || | |
| 14 | + return syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || | |
| 16 | 15 | syndrome == MLX5_CQE_SYNDROME_LOCAL_PROT_ERR || |
| 17 | 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 | 90 | goto out; |
| 91 | 91 | |
| 92 | 92 | mlx5e_reset_icosq_cc_pc(icosq); |
| 93 | − mlx5e_free_rx_descs(rq); | |
| 93 | + mlx5e_free_rx_in_progress_descs(rq); | |
| 94 | 94 | clear_bit(MLX5E_SQ_STATE_RECOVERING, &icosq->state); |
| 95 | 95 | mlx5e_activate_icosq(icosq); |
| 96 | 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 | 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 | 185 | mlx5_wq_ll_reset(&rq->mpwqe.wq); |
| 186 | − else | |
| 186 | + rq->mpwqe.actual_wq_head = 0; | |
| 187 | + } else { | |
| 187 | 188 | mlx5_wq_cyc_reset(&rq->wqe.wq); |
| 189 | + } | |
| 188 | 190 | } |
| 189 | 191 | |
| 190 | 192 | /* SW parser related functions */ |
| @@ -38,8 +38,8 @@ enum { · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | enum { |
| 40 | 40 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0, |
| 41 | − MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 1, | |
| 42 | − MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 2, | |
| 41 | + MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 1, | |
| 42 | + MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 2, | |
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | 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 | 218 | * this packet was already acknowledged and its record info |
| 219 | 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 | 223 | if (unlikely(tls_record_is_start_marker(record))) { |
| 224 | 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 | 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 | 840 | void mlx5e_free_rx_descs(struct mlx5e_rq *rq) |
| 818 | 841 | { |
| 819 | 842 | __be16 wqe_ix_be; |
| @@ -821,14 +844,8 @@ void mlx5e_free_rx_descs(struct mlx5e_rq *rq) · 1 unmodified line | ||
| 821 | 844 | |
| 822 | 845 | if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { |
| 823 | 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 */ | |
| 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 | − } | |
| 848 | + mlx5e_free_rx_in_progress_descs(rq); | |
| 832 | 849 | |
| 833 | 850 | while (!mlx5_wq_ll_is_empty(wq)) { |
| 834 | 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 | 479 | /* fill sq frag edge with nops to avoid wqe wrapping two pages */ |
| 480 | 480 | for (; wi < edge_wi; wi++) { |
| 481 | 481 | wi->opcode = MLX5_OPCODE_NOP; |
| 482 | + wi->num_wqebbs = 1; | |
| 482 | 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 | 528 | umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); |
| 528 | 529 | |
| 529 | 530 | sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_UMR; |
| 531 | + sq->db.ico_wqe[pi].num_wqebbs = MLX5E_UMR_WQEBBS; | |
| 530 | 532 | sq->db.ico_wqe[pi].umr.rq = rq; |
| 531 | 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 | 626 | ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc); |
| 625 | 627 | wi = &sq->db.ico_wqe[ci]; |
| 628 | + sqcc += wi->num_wqebbs; | |
| 626 | 629 | |
| 627 | 630 | if (last_wqe && unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) { |
| 628 | 631 | netdev_WARN_ONCE(cq->channel->netdev, |
| @@ -633,16 +636,12 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq) · 4 unmodified lines | ||
| 633 | 636 | break; |
| 634 | 637 | } |
| 635 | 638 | |
| 636 | − if (likely(wi->opcode == MLX5_OPCODE_UMR)) { | |
| 637 | − sqcc += MLX5E_UMR_WQEBBS; | |
| 639 | + if (likely(wi->opcode == MLX5_OPCODE_UMR)) | |
| 638 | 640 | wi->umr.rq->mpwqe.umr_completed++; |
| 639 | − } else if (likely(wi->opcode == MLX5_OPCODE_NOP)) { | |
| 640 | − sqcc++; | |
| 641 | − } else { | |
| 641 | + else if (unlikely(wi->opcode != MLX5_OPCODE_NOP)) | |
| 642 | 642 | netdev_WARN_ONCE(cq->channel->netdev, |
| 643 | 643 | "Bad OPCODE in ICOSQ WQE info: 0x%x\n", |
| 644 | 644 | wi->opcode); |
| 645 | − } | |
| 646 | 645 | |
| 647 | 646 | } while (!last_wqe); |
| 648 | 647 | |
| @@ -2714,10 +2714,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, · 2713 unmodified lines | ||
| 2714 | 2714 | continue; |
| 2715 | 2715 | |
| 2716 | 2716 | if (f->field_bsize == 32) { |
| 2717 | − mask_be32 = *(__be32 *)&mask; | |
| 2717 | + mask_be32 = (__be32)mask; | |
| 2718 | 2718 | mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); |
| 2719 | 2719 | } else if (f->field_bsize == 16) { |
| 2720 | − mask_be16 = *(__be16 *)&mask; | |
| 2720 | + mask_be32 = (__be32)mask; | |
| 2721 | + mask_be16 = *(__be16 *)&mask_be32; | |
| 2721 | 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 | 79 | u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); |
| 80 | 80 | |
| 81 | 81 | sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP; |
| 82 | + sq->db.ico_wqe[pi].num_wqebbs = 1; | |
| 82 | 83 | nopwqe = mlx5e_post_nop(wq, sq->sqn, &sq->pc); |
| 83 | 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 | 615 | break; |
| 616 | 616 | |
| 617 | 617 | if (i == MLX5_MAX_PORTS) { |
| 618 | − if (ldev->nb.notifier_call) | |
| 618 | + if (ldev->nb.notifier_call) { | |
| 619 | 619 | unregister_netdevice_notifier_net(&init_net, &ldev->nb); |
| 620 | + ldev->nb.notifier_call = NULL; | |
| 621 | + } | |
| 620 | 622 | mlx5_lag_mp_cleanup(ldev); |
| 621 | 623 | cancel_delayed_work_sync(&ldev->bond_work); |
| 622 | 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 | 934 | action->rewrite.data = (void *)ops; |
| 935 | 935 | action->rewrite.num_of_actions = i; |
| 936 | − action->rewrite.chunk->byte_size = i * sizeof(*ops); | |
| 937 | 936 | |
| 938 | 937 | ret = mlx5dr_send_postsend_action(dmn, action); |
| 939 | 938 | if (ret) { |
| @@ -558,7 +558,8 @@ int mlx5dr_send_postsend_action(struct mlx5dr_domain *dmn, · 557 unmodified lines | ||
| 558 | 558 | int ret; |
| 559 | 559 | |
| 560 | 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 | 563 | send_info.write.lkey = 0; |
| 563 | 564 | send_info.remote_addr = action->rewrite.chunk->mr_addr; |
| 564 | 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 | 1071 | MLX5_SET64(hca_vport_context, ctx, port_guid, req->port_guid); |
| 1072 | 1072 | if (req->field_select & MLX5_HCA_VPORT_SEL_NODE_GUID) |
| 1073 | 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 | 1077 | err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out)); |
| 1075 | 1078 | ex: |
| 1076 | 1079 | kfree(in); |
| @@ -1331,36 +1331,64 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci, · 1330 unmodified lines | ||
| 1331 | 1331 | mbox->mapaddr); |
| 1332 | 1332 | } |
| 1333 | 1333 | |
| 1334 | −static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, | |
| 1335 | − const struct pci_device_id *id) | |
| 1334 | +static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci, | |
| 1335 | + const struct pci_device_id *id, | |
| 1336 | + u32 *p_sys_status) | |
| 1336 | 1337 | { |
| 1337 | 1338 | unsigned long end; |
| 1338 | − char mrsr_pl[MLXSW_REG_MRSR_LEN]; | |
| 1339 | − int err; | |
| 1339 | + u32 val; | |
| 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 | 1341 | if (id->device == PCI_DEVICE_ID_MELLANOX_SWITCHX2) { |
| 1346 | 1342 | msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); |
| 1347 | 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 | 1347 | msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS); |
| 1352 | 1348 | |
| 1353 | 1349 | end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); |
| 1354 | 1350 | do { |
| 1355 | − u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY); | |
| 1356 | − | |
| 1351 | + val = mlxsw_pci_read32(mlxsw_pci, FW_READY); | |
| 1357 | 1352 | if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC) |
| 1358 | 1353 | return 0; |
| 1359 | 1354 | cond_resched(); |
| 1360 | 1355 | } while (time_before(jiffies, end)); |
| 1356 | + | |
| 1357 | + *p_sys_status = val & MLXSW_PCI_FW_READY_MASK; | |
| 1358 | + | |
| 1361 | 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 | 1392 | static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci) |
| 1365 | 1393 | { |
| 1366 | 1394 | int err; |
| @@ -3572,7 +3572,7 @@ MLXSW_ITEM32(reg, qeec, mase, 0x10, 31, 1); · 3571 unmodified lines | ||
| 3572 | 3572 | * When in bytes mode, value is specified in units of 1000bps. |
| 3573 | 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 | 3577 | /* reg_qeec_de |
| 3578 | 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 | 2045 | if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \ |
| 2046 | 2046 | (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\ |
| 2047 | 2047 | if ((mask & VXGE_DEBUG_MASK) == mask) \ |
| 2048 | − printk(fmt "\n", __VA_ARGS__); \ | |
| 2048 | + printk(fmt "\n", ##__VA_ARGS__); \ | |
| 2049 | 2049 | } while (0) |
| 2050 | 2050 | #else |
| 2051 | 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 | 453 | #if (VXGE_DEBUG_LL_CONFIG & VXGE_DEBUG_MASK) |
| 454 | 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 | 456 | #else |
| 457 | 457 | #define vxge_debug_ll_config(level, fmt, ...) |
| 458 | 458 | #endif |
| 459 | 459 | |
| 460 | 460 | #if (VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) |
| 461 | 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 | 463 | #else |
| 464 | 464 | #define vxge_debug_init(level, fmt, ...) |
| 465 | 465 | #endif |
| 466 | 466 | |
| 467 | 467 | #if (VXGE_DEBUG_TX & VXGE_DEBUG_MASK) |
| 468 | 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 | 470 | #else |
| 471 | 471 | #define vxge_debug_tx(level, fmt, ...) |
| 472 | 472 | #endif |
| 473 | 473 | |
| 474 | 474 | #if (VXGE_DEBUG_RX & VXGE_DEBUG_MASK) |
| 475 | 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 | 477 | #else |
| 478 | 478 | #define vxge_debug_rx(level, fmt, ...) |
| 479 | 479 | #endif |
| 480 | 480 | |
| 481 | 481 | #if (VXGE_DEBUG_MEM & VXGE_DEBUG_MASK) |
| 482 | 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 | 484 | #else |
| 485 | 485 | #define vxge_debug_mem(level, fmt, ...) |
| 486 | 486 | #endif |
| 487 | 487 | |
| 488 | 488 | #if (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK) |
| 489 | 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 | 491 | #else |
| 492 | 492 | #define vxge_debug_entryexit(level, fmt, ...) |
| 493 | 493 | #endif |
| 494 | 494 | |
| 495 | 495 | #if (VXGE_DEBUG_INTR & VXGE_DEBUG_MASK) |
| 496 | 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 | 498 | #else |
| 499 | 499 | #define vxge_debug_intr(level, fmt, ...) |
| 500 | 500 | #endif |
| @@ -616,7 +616,7 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) · 615 unmodified lines | ||
| 616 | 616 | if (bar->iomem) { |
| 617 | 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 | 620 | atomic_inc(&bar->refcnt); |
| 621 | 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 | 662 | /* Configure, and lock, BAR0.1 for PCIe XPB (MSI-X PBA) */ |
| 663 | 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 | 665 | atomic_inc(&bar->refcnt); |
| 666 | 666 | bars_free--; |
| 667 | 667 | |
| @@ -680,8 +680,8 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) · 12 unmodified lines | ||
| 680 | 680 | bar->iomem = ioremap(nfp_bar_resource_start(bar), |
| 681 | 681 | nfp_bar_resource_len(bar)); |
| 682 | 682 | if (bar->iomem) { |
| 683 | − msg += snprintf(msg, end - msg, | |
| 684 | − "0.%d: Explicit%d, ", 4 + i, i); | |
| 683 | + msg += scnprintf(msg, end - msg, | |
| 684 | + "0.%d: Explicit%d, ", 4 + i, i); | |
| 685 | 685 | atomic_inc(&bar->refcnt); |
| 686 | 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 | 2 | /* Copyright (c) 2017-2019 Pensando Systems, Inc. All rights reserved. */ |
| 3 | 3 | |
| 4 | 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 | 953 | int i; |
| 954 | 954 | #define REMAIN(__x) (sizeof(buf) - (__x)) |
| 955 | 955 | |
| 956 | − i = snprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", | |
| 957 | − lif->rx_mode, rx_mode); | |
| 956 | + i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:", | |
| 957 | + lif->rx_mode, rx_mode); | |
| 958 | 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 | 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 | 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 | 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 | 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 | 968 | netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf); |
| 969 | 969 | |
| 970 | 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 | 2 | /* Copyright (c) 2018-2019 Pensando Systems, Inc. All rights reserved. */ |
| 3 | 3 | |
| 4 | 4 | #ifndef IONIC_REGS_H |
| @@ -5091,7 +5091,7 @@ static int rtl_alloc_irq(struct rtl8169_private *tp) · 5090 unmodified lines | ||
| 5091 | 5091 | RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); |
| 5092 | 5092 | rtl_lock_config_regs(tp); |
| 5093 | 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 | 5095 | flags = PCI_IRQ_LEGACY; |
| 5096 | 5096 | break; |
| 5097 | 5097 | default: |
| @@ -212,12 +212,14 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd, · 211 unmodified lines | ||
| 212 | 212 | * progress on a NIC at any one time. So no need for locking. |
| 213 | 213 | */ |
| 214 | 214 | for (i = 0; i < hdr_len / 4 && bytes < PAGE_SIZE; i++) |
| 215 | − bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 216 | − " %08x", le32_to_cpu(hdr[i].u32[0])); | |
| 215 | + bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 216 | + " %08x", | |
| 217 | + le32_to_cpu(hdr[i].u32[0])); | |
| 217 | 218 | |
| 218 | 219 | for (i = 0; i < inlen / 4 && bytes < PAGE_SIZE; i++) |
| 219 | − bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 220 | − " %08x", le32_to_cpu(inbuf[i].u32[0])); | |
| 220 | + bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 221 | + " %08x", | |
| 222 | + le32_to_cpu(inbuf[i].u32[0])); | |
| 221 | 223 | |
| 222 | 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 | 305 | for (i = 0; i < hdr_len && bytes < PAGE_SIZE; i++) { |
| 304 | 306 | efx->type->mcdi_read_response(efx, &hdr, (i * 4), 4); |
| 305 | − bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 306 | − " %08x", le32_to_cpu(hdr.u32[0])); | |
| 307 | + bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 308 | + " %08x", le32_to_cpu(hdr.u32[0])); | |
| 307 | 309 | } |
| 308 | 310 | |
| 309 | 311 | for (i = 0; i < data_len && bytes < PAGE_SIZE; i++) { |
| 310 | 312 | efx->type->mcdi_read_response(efx, &hdr, |
| 311 | 313 | mcdi->resp_hdr_len + (i * 4), 4); |
| 312 | − bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 313 | − " %08x", le32_to_cpu(hdr.u32[0])); | |
| 314 | + bytes += scnprintf(buf + bytes, PAGE_SIZE - bytes, | |
| 315 | + " %08x", le32_to_cpu(hdr.u32[0])); | |
| 314 | 316 | } |
| 315 | 317 | |
| 316 | 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 | 1421 | ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); |
| 1420 | − offset = snprintf(buf, len, "%u.%u.%u.%u", | |
| 1421 | − le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]), | |
| 1422 | − le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3])); | |
| 1422 | + offset = scnprintf(buf, len, "%u.%u.%u.%u", | |
| 1423 | + le16_to_cpu(ver_words[0]), | |
| 1424 | + le16_to_cpu(ver_words[1]), | |
| 1425 | + le16_to_cpu(ver_words[2]), | |
| 1426 | + le16_to_cpu(ver_words[3])); | |
| 1423 | 1427 | |
| 1424 | 1428 | /* EF10 may have multiple datapath firmware variants within a |
| 1425 | 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 | 1431 | if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) { |
| 1428 | 1432 | struct efx_ef10_nic_data *nic_data = efx->nic_data; |
| 1429 | 1433 | |
| 1430 | − offset += snprintf(buf + offset, len - offset, " rx%x tx%x", | |
| 1431 | − nic_data->rx_dpcpu_fw_id, | |
| 1432 | − nic_data->tx_dpcpu_fw_id); | |
| 1434 | + offset += scnprintf(buf + offset, len - offset, " rx%x tx%x", | |
| 1435 | + nic_data->rx_dpcpu_fw_id, | |
| 1436 | + nic_data->tx_dpcpu_fw_id); | |
| 1433 | 1437 | |
| 1434 | 1438 | /* It's theoretically possible for the string to exceed 31 |
| 1435 | 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 | 1412 | ret = rk_gmac_clk_init(plat_dat); |
| 1413 | 1413 | if (ret) |
| 1414 | − return ret; | |
| 1414 | + goto err_remove_config_dt; | |
| 1415 | 1415 | |
| 1416 | 1416 | ret = rk_gmac_powerup(plat_dat->bsp_priv); |
| 1417 | 1417 | if (ret) |
| @@ -661,16 +661,22 @@ int stmmac_get_platform_resources(struct platform_device *pdev, · 660 unmodified lines | ||
| 661 | 661 | * In case the wake up interrupt is not passed from the platform |
| 662 | 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 | 666 | if (stmmac_res->wol_irq < 0) { |
| 666 | 667 | if (stmmac_res->wol_irq == -EPROBE_DEFER) |
| 667 | 668 | return -EPROBE_DEFER; |
| 669 | + dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n"); | |
| 668 | 670 | stmmac_res->wol_irq = stmmac_res->irq; |
| 669 | 671 | } |
| 670 | 672 | |
| 671 | − stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); | |
| 672 | − if (stmmac_res->lpi_irq == -EPROBE_DEFER) | |
| 673 | − return -EPROBE_DEFER; | |
| 673 | + stmmac_res->lpi_irq = | |
| 674 | + platform_get_irq_byname_optional(pdev, "eth_lpi"); | |
| 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 | 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 | 1845 | if (!net_eq(dev_net(geneve->dev), net)) |
| 1846 | 1846 | unregister_netdevice_queue(geneve->dev, head); |
| 1847 | 1847 | } |
| 1848 | − | |
| 1849 | − WARN_ON_ONCE(!list_empty(&gn->sock_list)); | |
| 1850 | 1848 | } |
| 1851 | 1849 | |
| 1852 | 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 | 1859 | /* unregister the devices gathered above */ |
| 1862 | 1860 | unregister_netdevice_many(&list); |
| 1863 | 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 | 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 | 77 | while ((skb = __skb_dequeue(&txp->tq)) != NULL) { |
| 78 | − skb->tc_redirected = 0; | |
| 78 | + skb->redirected = 0; | |
| 79 | 79 | skb->tc_skip_classify = 1; |
| 80 | 80 | |
| 81 | 81 | u64_stats_update_begin(&txp->tsync); |
| @@ -96,7 +96,7 @@ static void ifb_ri_tasklet(unsigned long _txp) · 14 unmodified lines | ||
| 96 | 96 | rcu_read_unlock(); |
| 97 | 97 | skb->skb_iif = txp->dev->ifindex; |
| 98 | 98 | |
| 99 | − if (!skb->tc_from_ingress) { | |
| 99 | + if (!skb->from_ingress) { | |
| 100 | 100 | dev_queue_xmit(skb); |
| 101 | 101 | } else { |
| 102 | 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 | 243 | txp->rx_bytes += skb->len; |
| 244 | 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 | 247 | dev_kfree_skb(skb); |
| 248 | 248 | dev->stats.rx_dropped++; |
| 249 | 249 | return NETDEV_TX_OK; |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <net/macsec.h> |
| 21 | 21 | #include <linux/phy.h> |
| 22 | 22 | #include <linux/byteorder/generic.h> |
| 23 | +#include <linux/if_arp.h> | |
| 23 | 24 | |
| 24 | 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 | 3857 | real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); |
| 3857 | 3858 | if (!real_dev) |
| 3858 | 3859 | return -ENODEV; |
| 3860 | + if (real_dev->type != ARPHRD_ETHER) | |
| 3861 | + return -EINVAL; | |
| 3859 | 3862 | |
| 3860 | 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 | 29 | return -ENOMEM; |
| 30 | 30 | |
| 31 | 31 | p = buf; |
| 32 | − p += snprintf(p, bufsize - (p - buf), | |
| 33 | − "SA count=%u tx=%u\n", | |
| 34 | − ipsec->count, ipsec->tx); | |
| 32 | + p += scnprintf(p, bufsize - (p - buf), | |
| 33 | + "SA count=%u tx=%u\n", | |
| 34 | + ipsec->count, ipsec->tx); | |
| 35 | 35 | |
| 36 | 36 | for (i = 0; i < NSIM_IPSEC_MAX_SA_COUNT; i++) { |
| 37 | 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 | 39 | if (!sap->used) |
| 40 | 40 | continue; |
| 41 | 41 | |
| 42 | − p += snprintf(p, bufsize - (p - buf), | |
| 43 | − "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", | |
| 44 | − i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], | |
| 45 | − sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); | |
| 46 | − p += snprintf(p, bufsize - (p - buf), | |
| 47 | − "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", | |
| 48 | − i, be32_to_cpu(sap->xs->id.spi), | |
| 49 | − sap->xs->id.proto, sap->salt, sap->crypt); | |
| 50 | − p += snprintf(p, bufsize - (p - buf), | |
| 51 | − "sa[%i] key=0x%08x %08x %08x %08x\n", | |
| 52 | − i, sap->key[0], sap->key[1], | |
| 53 | − sap->key[2], sap->key[3]); | |
| 42 | + p += scnprintf(p, bufsize - (p - buf), | |
| 43 | + "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", | |
| 44 | + i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], | |
| 45 | + sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); | |
| 46 | + p += scnprintf(p, bufsize - (p - buf), | |
| 47 | + "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", | |
| 48 | + i, be32_to_cpu(sap->xs->id.spi), | |
| 49 | + sap->xs->id.proto, sap->salt, sap->crypt); | |
| 50 | + p += scnprintf(p, bufsize - (p - buf), | |
| 51 | + "sa[%i] key=0x%08x %08x %08x %08x\n", | |
| 52 | + i, sap->key[0], sap->key[1], | |
| 53 | + sap->key[2], sap->key[3]); | |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | len = simple_read_from_buffer(buffer, count, ppos, buf, p - buf); |
| @@ -30,7 +30,8 @@ · 29 unmodified lines | ||
| 30 | 30 | #define DP83867_CTRL 0x1f |
| 31 | 31 | |
| 32 | 32 | /* Extended Registers */ |
| 33 | −#define DP83867_CFG4 0x0031 | |
| 33 | +#define DP83867_FLD_THR_CFG 0x002e | |
| 34 | +#define DP83867_CFG4 0x0031 | |
| 34 | 35 | #define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6)) |
| 35 | 36 | #define DP83867_CFG4_SGMII_ANEG_TIMER_11MS (3 << 5) |
| 36 | 37 | #define DP83867_CFG4_SGMII_ANEG_TIMER_800US (2 << 5) |
| @@ -93,6 +94,7 @@ · 56 unmodified lines | ||
| 93 | 94 | #define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK GENMASK(2, 0) |
| 94 | 95 | #define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT 0 |
| 95 | 96 | #define DP83867_STRAP_STS2_CLK_SKEW_NONE BIT(2) |
| 97 | +#define DP83867_STRAP_STS2_STRAP_FLD BIT(10) | |
| 96 | 98 | |
| 97 | 99 | /* PHY CTRL bits */ |
| 98 | 100 | #define DP83867_PHYCR_TX_FIFO_DEPTH_SHIFT 14 |
| @@ -145,6 +147,9 @@ · 46 unmodified lines | ||
| 145 | 147 | /* CFG4 bits */ |
| 146 | 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 | 153 | enum { |
| 149 | 154 | DP83867_PORT_MIRROING_KEEP, |
| 150 | 155 | DP83867_PORT_MIRROING_EN, |
| @@ -622,6 +627,20 @@ static int dp83867_config_init(struct phy_device *phydev) · 471 unmodified lines | ||
| 622 | 627 | phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, |
| 623 | 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 | 644 | if (phy_interface_is_rgmii(phydev) || |
| 626 | 645 | phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
| 627 | 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 | 242 | return -ENOMEM; |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | − priv->clk = devm_clk_get(&pdev->dev, NULL); | |
| 246 | − if (PTR_ERR(priv->clk) == -EPROBE_DEFER) | |
| 245 | + priv->clk = devm_clk_get_optional(&pdev->dev, NULL); | |
| 246 | + if (IS_ERR(priv->clk)) | |
| 247 | 247 | return PTR_ERR(priv->clk); |
| 248 | − else | |
| 249 | − priv->clk = NULL; | |
| 250 | 248 | |
| 251 | 249 | ret = clk_prepare_enable(priv->clk); |
| 252 | 250 | if (ret) |
| @@ -282,8 +282,13 @@ static int mdio_mux_iproc_suspend(struct device *dev) · 281 unmodified lines | ||
| 282 | 282 | static int mdio_mux_iproc_resume(struct device *dev) |
| 283 | 283 | { |
| 284 | 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 | 292 | mdio_mux_iproc_config(md); |
| 288 | 293 | |
| 289 | 294 | return 0; |
| @@ -572,13 +572,15 @@ static void sfp_upstream_clear(struct sfp_bus *bus) · 571 unmodified lines | ||
| 572 | 572 | * the sfp_bus structure, incrementing its reference count. This must |
| 573 | 573 | * be put via sfp_bus_put() when done. |
| 574 | 574 | * |
| 575 | − * Returns: on success, a pointer to the sfp_bus structure, | |
| 576 | − * %NULL if no SFP is specified, | |
| 577 | − * on failure, an error pointer value: | |
| 578 | − * corresponding to the errors detailed for | |
| 579 | − * fwnode_property_get_reference_args(). | |
| 580 | − * %-ENOMEM if we failed to allocate the bus. | |
| 581 | − * an error from the upstream's connect_phy() method. | |
| 575 | + * Returns: | |
| 576 | + * - on success, a pointer to the sfp_bus structure, | |
| 577 | + * - %NULL if no SFP is specified, | |
| 578 | + * - on failure, an error pointer value: | |
| 579 | + * | |
| 580 | + * - corresponding to the errors detailed for | |
| 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 | 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 | 614 | * the SFP bus using sfp_register_upstream(). This takes a reference on the |
| 613 | 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, | |
| 616 | − * %NULL if no SFP is specified, | |
| 617 | − * on failure, an error pointer value: | |
| 618 | − * corresponding to the errors detailed for | |
| 619 | − * fwnode_property_get_reference_args(). | |
| 620 | − * %-ENOMEM if we failed to allocate the bus. | |
| 621 | − * an error from the upstream's connect_phy() method. | |
| 617 | + * Returns: | |
| 618 | + * - on success, a pointer to the sfp_bus structure, | |
| 619 | + * - %NULL if no SFP is specified, | |
| 620 | + * - on failure, an error pointer value: | |
| 621 | + * | |
| 622 | + * - corresponding to the errors detailed for | |
| 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 | 627 | int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, |
| 624 | 628 | const struct sfp_upstream_ops *ops) |
| @@ -1210,6 +1210,7 @@ static const struct usb_device_id products[] = { · 1209 unmodified lines | ||
| 1210 | 1210 | {QMI_FIXED_INTF(0x1435, 0xd182, 5)}, /* Wistron NeWeb D18 */ |
| 1211 | 1211 | {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ |
| 1212 | 1212 | {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ |
| 1213 | + {QMI_FIXED_INTF(0x1690, 0x7588, 4)}, /* ASKEY WWHC050 */ | |
| 1213 | 1214 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ |
| 1214 | 1215 | {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ |
| 1215 | 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 | 2779 | /* Setup stats when device is created */ |
| 2780 | 2780 | static int vxlan_init(struct net_device *dev) |
| 2781 | 2781 | { |
| 2782 | + struct vxlan_dev *vxlan = netdev_priv(dev); | |
| 2783 | + int err; | |
| 2784 | + | |
| 2782 | 2785 | dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
| 2783 | 2786 | if (!dev->tstats) |
| 2784 | 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 | 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 | 3053 | vxlan->dev = dev; |
| 3045 | 3054 | |
| 3046 | − gro_cells_init(&vxlan->gro_cells, dev); | |
| 3047 | − | |
| 3048 | 3055 | for (h = 0; h < FDB_HASH_SIZE; ++h) { |
| 3049 | 3056 | spin_lock_init(&vxlan->hash_lock[h]); |
| 3050 | 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 | 122 | u32 mtu; |
| 123 | 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 | 126 | ret = -EPROTONOSUPPORT; |
| 127 | 127 | net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name); |
| 128 | 128 | goto err; |
| @@ -411,11 +411,7 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs) · 410 unmodified lines | ||
| 411 | 411 | |
| 412 | 412 | peer = wg_peer_create(wg, public_key, preshared_key); |
| 413 | 413 | if (IS_ERR(peer)) { |
| 414 | − /* Similar to the above, if the key is invalid, we skip | |
| 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); | |
| 414 | + ret = PTR_ERR(peer); | |
| 419 | 415 | peer = NULL; |
| 420 | 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 | 565 | private_key); |
| 570 | 566 | list_for_each_entry_safe(peer, temp, &wg->peer_list, |
| 571 | 567 | peer_list) { |
| 572 | − BUG_ON(!wg_noise_precompute_static_static(peer)); | |
| 568 | + wg_noise_precompute_static_static(peer); | |
| 573 | 569 | wg_noise_expire_current_peer_keypairs(peer); |
| 574 | 570 | } |
| 575 | 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 | 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 | 49 | down_write(&peer->handshake.lock); |
| 52 | − if (peer->handshake.static_identity->has_identity) { | |
| 53 | − ret = curve25519( | |
| 54 | − peer->handshake.precomputed_static_static, | |
| 50 | + if (!peer->handshake.static_identity->has_identity || | |
| 51 | + !curve25519(peer->handshake.precomputed_static_static, | |
| 55 | 52 | peer->handshake.static_identity->static_private, |
| 56 | − peer->handshake.remote_static); | |
| 57 | − } else { | |
| 58 | − u8 empty[NOISE_PUBLIC_KEY_LEN] = { 0 }; | |
| 59 | − | |
| 60 | − ret = curve25519(empty, empty, peer->handshake.remote_static); | |
| 53 | + peer->handshake.remote_static)) | |
| 61 | 54 | memset(peer->handshake.precomputed_static_static, 0, |
| 62 | 55 | NOISE_PUBLIC_KEY_LEN); |
| 63 | − } | |
| 64 | 56 | up_write(&peer->handshake.lock); |
| 65 | − return ret; | |
| 66 | 57 | } |
| 67 | 58 | |
| 68 | −bool wg_noise_handshake_init(struct noise_handshake *handshake, | |
| 69 | − struct noise_static_identity *static_identity, | |
| 70 | − const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], | |
| 71 | − const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], | |
| 72 | − struct wg_peer *peer) | |
| 59 | +void wg_noise_handshake_init(struct noise_handshake *handshake, | |
| 60 | + struct noise_static_identity *static_identity, | |
| 61 | + const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], | |
| 62 | + const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], | |
| 63 | + struct wg_peer *peer) | |
| 73 | 64 | { |
| 74 | 65 | memset(handshake, 0, sizeof(*handshake)); |
| 75 | 66 | init_rwsem(&handshake->lock); |
| @@ -81,7 +72,7 @@ bool wg_noise_handshake_init(struct noise_handshake *handshake, · 5 unmodified lines | ||
| 81 | 72 | NOISE_SYMMETRIC_KEY_LEN); |
| 82 | 73 | handshake->static_identity = static_identity; |
| 83 | 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 | 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 | 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 | 410 | static void mix_hash(u8 hash[NOISE_HASH_LEN], const u8 *src, size_t src_len) |
| 407 | 411 | { |
| 408 | 412 | struct blake2s_state blake; |
| @@ -531,10 +535,9 @@ wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst, · 122 unmodified lines | ||
| 531 | 535 | NOISE_PUBLIC_KEY_LEN, key, handshake->hash); |
| 532 | 536 | |
| 533 | 537 | /* ss */ |
| 534 | − kdf(handshake->chaining_key, key, NULL, | |
| 535 | − handshake->precomputed_static_static, NOISE_HASH_LEN, | |
| 536 | − NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, | |
| 537 | − handshake->chaining_key); | |
| 538 | + if (!mix_precomputed_dh(handshake->chaining_key, key, | |
| 539 | + handshake->precomputed_static_static)) | |
| 540 | + goto out; | |
| 538 | 541 | |
| 539 | 542 | /* {t} */ |
| 540 | 543 | tai64n_now(timestamp); |
| @@ -595,9 +598,9 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src, · 54 unmodified lines | ||
| 595 | 598 | handshake = &peer->handshake; |
| 596 | 599 | |
| 597 | 600 | /* ss */ |
| 598 | − kdf(chaining_key, key, NULL, handshake->precomputed_static_static, | |
| 599 | − NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, | |
| 600 | − chaining_key); | |
| 601 | + if (!mix_precomputed_dh(chaining_key, key, | |
| 602 | + handshake->precomputed_static_static)) | |
| 603 | + goto out; | |
| 601 | 604 | |
| 602 | 605 | /* {t} */ |
| 603 | 606 | if (!message_decrypt(t, src->encrypted_timestamp, |
| @@ -94,11 +94,11 @@ struct noise_handshake { · 93 unmodified lines | ||
| 94 | 94 | struct wg_device; |
| 95 | 95 | |
| 96 | 96 | void wg_noise_init(void); |
| 97 | −bool wg_noise_handshake_init(struct noise_handshake *handshake, | |
| 98 | − struct noise_static_identity *static_identity, | |
| 99 | − const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], | |
| 100 | − const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], | |
| 101 | − struct wg_peer *peer); | |
| 97 | +void wg_noise_handshake_init(struct noise_handshake *handshake, | |
| 98 | + struct noise_static_identity *static_identity, | |
| 99 | + const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN], | |
| 100 | + const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN], | |
| 101 | + struct wg_peer *peer); | |
| 102 | 102 | void wg_noise_handshake_clear(struct noise_handshake *handshake); |
| 103 | 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 | 116 | void wg_noise_set_static_identity_private_key( |
| 117 | 117 | struct noise_static_identity *static_identity, |
| 118 | 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 | 121 | bool |
| 122 | 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 | 34 | return ERR_PTR(ret); |
| 35 | 35 | peer->device = wg; |
| 36 | 36 | |
| 37 | − if (!wg_noise_handshake_init(&peer->handshake, &wg->static_identity, | |
| 38 | − public_key, preshared_key, peer)) { | |
| 39 | − ret = -EKEYREJECTED; | |
| 40 | − goto err_1; | |
| 41 | − } | |
| 37 | + wg_noise_handshake_init(&peer->handshake, &wg->static_identity, | |
| 38 | + public_key, preshared_key, peer); | |
| 42 | 39 | if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL)) |
| 43 | 40 | goto err_1; |
| 44 | 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 | 66 | #define PACKET_PEER(skb) (PACKET_CB(skb)->keypair->entry.peer) |
| 67 | 67 | |
| 68 | 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 | 71 | if (skb_network_header(skb) >= skb->head && |
| 72 | 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 | 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 | 90 | static inline void wg_reset_packet(struct sk_buff *skb) |
| 85 | 91 | { |
| 86 | 92 | skb_scrub_packet(skb, true); |
| @@ -94,8 +100,8 @@ static inline void wg_reset_packet(struct sk_buff *skb) · 7 unmodified lines | ||
| 94 | 100 | skb->dev = NULL; |
| 95 | 101 | #ifdef CONFIG_NET_SCHED |
| 96 | 102 | skb->tc_index = 0; |
| 97 | − skb_reset_tc(skb); | |
| 98 | 103 | #endif |
| 104 | + skb_reset_redirect(skb); | |
| 99 | 105 | skb->hdr_len = skb_headroom(skb); |
| 100 | 106 | skb_reset_mac_header(skb); |
| 101 | 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 | 56 | size_t data_offset, data_len, header_len; |
| 57 | 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 | 60 | skb_transport_header(skb) < skb->head || |
| 61 | 61 | (skb_transport_header(skb) + sizeof(struct udphdr)) > |
| 62 | 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 | 389 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 390 | 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 | 392 | if (skb->protocol == htons(ETH_P_IP)) { |
| 393 | 393 | len = ntohs(ip_hdr(skb)->tot_len); |
| 394 | 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 | 587 | wg_packet_consume_data(wg, skb); |
| 588 | 588 | break; |
| 589 | 589 | default: |
| 590 | − net_dbg_skb_ratelimited("%s: Invalid packet from %pISpfsc\n", | |
| 591 | − wg->dev->name, skb); | |
| 590 | + WARN(1, "Non-exhaustive parsing of packet header lead to unknown packet type!\n"); | |
| 592 | 591 | goto err; |
| 593 | 592 | } |
| 594 | 593 | return; |
| @@ -300,6 +300,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = { · 299 unmodified lines | ||
| 300 | 300 | * HT size; mac80211 would otherwise pick the HE max (256) by default. |
| 301 | 301 | */ |
| 302 | 302 | .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, |
| 303 | + .tx_with_siso_diversity = true, | |
| 303 | 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 | 327 | * HT size; mac80211 would otherwise pick the HE max (256) by default. |
| 327 | 328 | */ |
| 328 | 329 | .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, |
| 330 | + .tx_with_siso_diversity = true, | |
| 329 | 331 | .num_rbds = IWL_NUM_RBDS_22000_HE, |
| 330 | 332 | }; |
| 331 | 333 | |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * GPL LICENSE SUMMARY |
| 7 | 7 | * |
| 8 | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | − * Copyright (C) 2019 Intel Corporation | |
| 9 | + * Copyright (C) 2019 - 2020 Intel Corporation | |
| 10 | 10 | * |
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -27,7 +27,7 @@ · 14 unmodified lines | ||
| 27 | 27 | * BSD LICENSE |
| 28 | 28 | * |
| 29 | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | − * Copyright (C) 2019 Intel Corporation | |
| 30 | + * Copyright (C) 2019 - 2020 Intel Corporation | |
| 31 | 31 | * All rights reserved. |
| 32 | 32 | * |
| 33 | 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 | 492 | IWL_EXPORT_SYMBOL(iwl_validate_sar_geo_profile); |
| 493 | 493 | |
| 494 | −void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | |
| 495 | − struct iwl_per_chain_offset_group *table) | |
| 494 | +int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | |
| 495 | + struct iwl_per_chain_offset_group *table) | |
| 496 | 496 | { |
| 497 | 497 | int ret, i, j; |
| 498 | 498 | |
| 499 | 499 | if (!iwl_sar_geo_support(fwrt)) |
| 500 | − return; | |
| 500 | + return -EOPNOTSUPP; | |
| 501 | 501 | |
| 502 | 502 | ret = iwl_sar_get_wgds_table(fwrt); |
| 503 | 503 | if (ret < 0) { |
| @@ -505,7 +505,7 @@ void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, · 1 unmodified line | ||
| 505 | 505 | "Geo SAR BIOS table invalid or unavailable. (%d)\n", |
| 506 | 506 | ret); |
| 507 | 507 | /* we don't fail if the table is not available */ |
| 508 | − return; | |
| 508 | + return -ENOENT; | |
| 509 | 509 | } |
| 510 | 510 | |
| 511 | 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 | 530 | i, j, value[1], value[2], value[0]); |
| 531 | 531 | } |
| 532 | 532 | } |
| 533 | + | |
| 534 | + return 0; | |
| 533 | 535 | } |
| 534 | 536 | IWL_EXPORT_SYMBOL(iwl_sar_geo_init); |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * GPL LICENSE SUMMARY |
| 7 | 7 | * |
| 8 | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | − * Copyright(c) 2018 - 2019 Intel Corporation | |
| 9 | + * Copyright(c) 2018 - 2020 Intel Corporation | |
| 10 | 10 | * |
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -27,7 +27,7 @@ · 14 unmodified lines | ||
| 27 | 27 | * BSD LICENSE |
| 28 | 28 | * |
| 29 | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | − * Copyright(c) 2018 - 2019 Intel Corporation | |
| 30 | + * Copyright(c) 2018 - 2020 Intel Corporation | |
| 31 | 31 | * All rights reserved. |
| 32 | 32 | * |
| 33 | 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 | 171 | int iwl_validate_sar_geo_profile(struct iwl_fw_runtime *fwrt, |
| 172 | 172 | struct iwl_host_cmd *cmd); |
| 173 | 173 | |
| 174 | −void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | |
| 175 | − struct iwl_per_chain_offset_group *table); | |
| 174 | +int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | |
| 175 | + struct iwl_per_chain_offset_group *table); | |
| 176 | + | |
| 176 | 177 | #else /* CONFIG_ACPI */ |
| 177 | 178 | |
| 178 | 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 | 244 | return -ENOENT; |
| 244 | 245 | } |
| 245 | 246 | |
| 246 | −static inline void iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | |
| 247 | − struct iwl_per_chain_offset_group *table) | |
| 247 | +static inline int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, | |
| 248 | + struct iwl_per_chain_offset_group *table) | |
| 248 | 249 | { |
| 250 | + return -ENOENT; | |
| 249 | 251 | } |
| 250 | 252 | |
| 251 | 253 | #endif /* CONFIG_ACPI */ |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
| 9 | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | 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 | 13 | * This program is free software; you can redistribute it and/or modify |
| 14 | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -31,7 +31,7 @@ · 16 unmodified lines | ||
| 31 | 31 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
| 32 | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 33 | 33 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 34 | − * Copyright(c) 2018 - 2019 Intel Corporation | |
| 34 | + * Copyright(c) 2018 - 2020 Intel Corporation | |
| 35 | 35 | * All rights reserved. |
| 36 | 36 | * |
| 37 | 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 | 1409 | goto out; |
| 1410 | 1410 | } |
| 1411 | 1411 | |
| 1412 | − /* | |
| 1413 | − * region register have absolute value so apply rxf offset after | |
| 1414 | − * reading the registers | |
| 1415 | − */ | |
| 1416 | − offs += rxf_data.offset; | |
| 1412 | + offs = rxf_data.offset; | |
| 1417 | 1413 | |
| 1418 | 1414 | /* Lock fence */ |
| 1419 | 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 | 2490 | goto out; |
| 2495 | 2491 | } |
| 2496 | 2492 | |
| 2497 | − if (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 | − } | |
| 2493 | + iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, true); | |
| 2501 | 2494 | |
| 2502 | 2495 | IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n"); |
| 2503 | 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 | 2655 | return 0; |
| 2663 | 2656 | } |
| 2664 | 2657 | |
| 2665 | −int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, | |
| 2666 | − struct iwl_fw_dbg_params *params, | |
| 2667 | − bool stop) | |
| 2658 | +void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, | |
| 2659 | + struct iwl_fw_dbg_params *params, | |
| 2660 | + bool stop) | |
| 2668 | 2661 | { |
| 2669 | 2662 | int ret = 0; |
| 2670 | 2663 | |
| 2671 | 2664 | if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) |
| 2672 | − return 0; | |
| 2665 | + return; | |
| 2673 | 2666 | |
| 2674 | 2667 | if (fw_has_capa(&fwrt->fw->ucode_capa, |
| 2675 | 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 | 2679 | iwl_fw_set_dbg_rec_on(fwrt); |
| 2687 | 2680 | } |
| 2688 | 2681 | #endif |
| 2689 | − | |
| 2690 | − return ret; | |
| 2691 | 2682 | } |
| 2692 | 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 | 239 | _iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \ |
| 240 | 240 | iwl_fw_dbg_get_trigger((fwrt)->fw,\ |
| 241 | 241 | (trig))) |
| 242 | −int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, | |
| 243 | − struct iwl_fw_dbg_params *params, | |
| 244 | − bool stop); | |
| 242 | +void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, | |
| 243 | + struct iwl_fw_dbg_params *params, | |
| 244 | + bool stop); | |
| 245 | 245 | |
| 246 | 246 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 247 | 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 | 1467 | kmemdup(pieces->dbg_conf_tlv[i], |
| 1468 | 1468 | pieces->dbg_conf_tlv_len[i], |
| 1469 | 1469 | GFP_KERNEL); |
| 1470 | − if (!pieces->dbg_conf_tlv_len[i]) | |
| 1470 | + if (!pieces->dbg_conf_tlv[i]) | |
| 1471 | 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 | 762 | u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT); |
| 763 | 763 | union geo_tx_power_profiles_cmd cmd; |
| 764 | 764 | u16 len; |
| 765 | + int ret; | |
| 765 | 766 | |
| 766 | 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 | 777 | cmd.geo_cmd.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); |
| 771 | 778 | |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * GPL LICENSE SUMMARY |
| 7 | 7 | * |
| 8 | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | − * Copyright(c) 2018 - 2019 Intel Corporation | |
| 9 | + * Copyright(c) 2018 - 2020 Intel Corporation | |
| 10 | 10 | * |
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -27,7 +27,7 @@ · 14 unmodified lines | ||
| 27 | 27 | * BSD LICENSE |
| 28 | 28 | * |
| 29 | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | − * Copyright(c) 2018 - 2019 Intel Corporation | |
| 30 | + * Copyright(c) 2018 - 2020 Intel Corporation | |
| 31 | 31 | * All rights reserved. |
| 32 | 32 | * |
| 33 | 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 | 147 | (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) |
| 148 | 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 | 155 | if (sband->iftype_data && sband->iftype_data->he_cap.has_he && |
| 152 | 156 | !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & |
| 153 | 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 | 196 | u16 supp; |
| 193 | 197 | int i, highest_mcs; |
| 198 | + u8 nss = sta->rx_nss; | |
| 194 | 199 | |
| 195 | − for (i = 0; i < sta->rx_nss; i++) { | |
| 196 | − if (i == IWL_TLC_NSS_MAX) | |
| 197 | − break; | |
| 200 | + /* the station support only a single receive chain */ | |
| 201 | + if (sta->smps_mode == IEEE80211_SMPS_STATIC) | |
| 202 | + nss = 1; | |
| 198 | 203 | |
| 204 | + for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { | |
| 199 | 205 | highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); |
| 200 | 206 | if (!highest_mcs) |
| 201 | 207 | continue; |
| @@ -241,8 +247,13 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, · 39 unmodified lines | ||
| 241 | 247 | u16 tx_mcs_160 = |
| 242 | 248 | le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); |
| 243 | 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 | 257 | u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; |
| 247 | 258 | u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; |
| 248 | 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 | 314 | cmd->mode = IWL_TLC_MNG_MODE_HT; |
| 304 | 315 | cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = |
| 305 | 316 | cpu_to_le16(ht_cap->mcs.rx_mask[0]); |
| 306 | − cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = | |
| 307 | − cpu_to_le16(ht_cap->mcs.rx_mask[1]); | |
| 317 | + | |
| 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 | 785 | if (!le32_to_cpu(notif->status)) { |
| 786 | 786 | iwl_mvm_te_check_disconnect(mvm, vif, |
| 787 | 787 | "Session protection failure"); |
| 788 | + spin_lock_bh(&mvm->time_event_lock); | |
| 788 | 789 | iwl_mvm_te_clear_data(mvm, te_data); |
| 790 | + spin_unlock_bh(&mvm->time_event_lock); | |
| 789 | 791 | } |
| 790 | 792 | |
| 791 | 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 | 804 | iwl_mvm_te_check_disconnect(mvm, vif, |
| 803 | 805 | "No beacon heard and the session protection is over already..."); |
| 806 | + spin_lock_bh(&mvm->time_event_lock); | |
| 804 | 807 | iwl_mvm_te_clear_data(mvm, te_data); |
| 808 | + spin_unlock_bh(&mvm->time_event_lock); | |
| 805 | 809 | } |
| 806 | 810 | |
| 807 | 811 | goto out_unlock; |
| @@ -939,7 +939,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { · 938 unmodified lines | ||
| 939 | 939 | IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), |
| 940 | 940 | IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), |
| 941 | 941 | IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), |
| 942 | − | |
| 943 | 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 | 561 | rxmcs == DESC92C_RATE11M) |
| 562 | 562 | |
| 563 | 563 | struct phy_status_rpt { |
| 564 | + u8 padding[2]; | |
| 564 | 565 | u8 ch_corr[2]; |
| 565 | 566 | u8 cck_sig_qual_ofdm_pwdb_all; |
| 566 | 567 | u8 cck_agc_rpt_ofdm_cfosho_a; |
| @@ -6274,7 +6274,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) · 6273 unmodified lines | ||
| 6274 | 6274 | wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | |
| 6275 | 6275 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
| 6276 | 6276 | WIPHY_FLAG_HAS_CHANNEL_SWITCH | |
| 6277 | −+ WIPHY_FLAG_IBSS_RSN; | |
| 6277 | + WIPHY_FLAG_IBSS_RSN; | |
| 6278 | 6278 | |
| 6279 | 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 | 184 | const struct firmware *fw; |
| 185 | 185 | struct sk_buff *skb; |
| 186 | 186 | unsigned long len; |
| 187 | − u8 max_size, payload_size; | |
| 187 | + int max_size, payload_size; | |
| 188 | 188 | int rc = 0; |
| 189 | 189 | |
| 190 | 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 | 208 | while (len) { |
| 209 | 209 | |
| 210 | − payload_size = min_t(unsigned long, (unsigned long) max_size, | |
| 211 | − len); | |
| 210 | + payload_size = min_t(unsigned long, max_size, len); | |
| 212 | 211 | |
| 213 | 212 | skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size), |
| 214 | 213 | GFP_KERNEL); |
| @@ -850,9 +850,11 @@ out_free_tagset: · 849 unmodified lines | ||
| 850 | 850 | if (new) |
| 851 | 851 | blk_mq_free_tag_set(ctrl->ctrl.admin_tagset); |
| 852 | 852 | out_free_async_qe: |
| 853 | − nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, | |
| 854 | − sizeof(struct nvme_command), DMA_TO_DEVICE); | |
| 855 | − ctrl->async_event_sqe.data = NULL; | |
| 853 | + if (ctrl->async_event_sqe.data) { | |
| 854 | + nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, | |
| 855 | + sizeof(struct nvme_command), DMA_TO_DEVICE); | |
| 856 | + ctrl->async_event_sqe.data = NULL; | |
| 857 | + } | |
| 856 | 858 | out_free_queue: |
| 857 | 859 | nvme_rdma_free_queue(&ctrl->queues[0]); |
| 858 | 860 | return error; |
| @@ -515,7 +515,7 @@ static int nvmet_try_send_data_pdu(struct nvmet_tcp_cmd *cmd) · 514 unmodified lines | ||
| 515 | 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 | 520 | struct nvmet_tcp_queue *queue = cmd->queue; |
| 521 | 521 | int ret; |
| @@ -523,9 +523,15 @@ static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd) · 1 unmodified line | ||
| 523 | 523 | while (cmd->cur_sg) { |
| 524 | 524 | struct page *page = sg_page(cmd->cur_sg); |
| 525 | 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 | 533 | ret = kernel_sendpage(cmd->queue->sock, page, cmd->offset, |
| 528 | − left, MSG_DONTWAIT | MSG_MORE); | |
| 534 | + left, flags); | |
| 529 | 535 | if (ret <= 0) |
| 530 | 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 | 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 | 670 | if (ret <= 0) |
| 665 | 671 | goto done_send; |
| 666 | 672 | } |
| @@ -327,6 +327,7 @@ config RTC_DRV_MAX6900 · 326 unmodified lines | ||
| 327 | 327 | config RTC_DRV_MAX8907 |
| 328 | 328 | tristate "Maxim MAX8907" |
| 329 | 329 | depends on MFD_MAX8907 || COMPILE_TEST |
| 330 | + select REGMAP_IRQ | |
| 330 | 331 | help |
| 331 | 332 | If you say yes here you will get support for the |
| 332 | 333 | RTC of Maxim MAX8907 PMIC. |
| @@ -178,6 +178,8 @@ struct dasd_block *dasd_alloc_block(void) · 177 unmodified lines | ||
| 178 | 178 | (unsigned long) block); |
| 179 | 179 | INIT_LIST_HEAD(&block->ccw_queue); |
| 180 | 180 | spin_lock_init(&block->queue_lock); |
| 181 | + INIT_LIST_HEAD(&block->format_list); | |
| 182 | + spin_lock_init(&block->format_lock); | |
| 181 | 183 | timer_setup(&block->timer, dasd_block_timeout, 0); |
| 182 | 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 | 1782 | if (dasd_ese_needs_format(cqr->block, irb)) { |
| 1781 | 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 | 1785 | cqr->status = DASD_CQR_SUCCESS; |
| 1784 | 1786 | cqr->stopclk = now; |
| 1785 | 1787 | dasd_device_clear_timer(device); |
| 1786 | 1788 | dasd_schedule_device_bh(device); |
| 1787 | 1789 | return; |
| 1788 | 1790 | } |
| 1789 | − fcqr = device->discipline->ese_format(device, cqr); | |
| 1791 | + fcqr = device->discipline->ese_format(device, cqr, irb); | |
| 1790 | 1792 | if (IS_ERR(fcqr)) { |
| 1793 | + if (PTR_ERR(fcqr) == -EINVAL) { | |
| 1794 | + cqr->status = DASD_CQR_ERROR; | |
| 1795 | + return; | |
| 1796 | + } | |
| 1791 | 1797 | /* |
| 1792 | 1798 | * If we can't format now, let the request go |
| 1793 | 1799 | * one extra round. Maybe we can format later. |
| 1794 | 1800 | */ |
| 1795 | 1801 | cqr->status = DASD_CQR_QUEUED; |
| 1802 | + dasd_schedule_device_bh(device); | |
| 1803 | + return; | |
| 1796 | 1804 | } else { |
| 1797 | 1805 | fcqr->status = DASD_CQR_QUEUED; |
| 1798 | 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 | 2757 | struct request *req; |
| 2750 | 2758 | blk_status_t error = BLK_STS_OK; |
| 2759 | + unsigned int proc_bytes; | |
| 2751 | 2760 | int status; |
| 2752 | 2761 | |
| 2753 | 2762 | req = (struct request *) cqr->callback_data; |
| 2754 | 2763 | dasd_profile_end(cqr->block, cqr, req); |
| 2755 | 2764 | |
| 2765 | + proc_bytes = cqr->proc_bytes; | |
| 2756 | 2766 | status = cqr->block->base->discipline->free_cp(cqr, req); |
| 2757 | 2767 | if (status < 0) |
| 2758 | 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 | 2793 | blk_mq_end_request(req, error); |
| 2784 | 2794 | blk_mq_run_hw_queues(req->q, true); |
| 2785 | 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 | 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 | 249 | static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, |
| 211 | 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 | 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 | 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 | 3064 | struct dasd_device *device = cqr->startdev; |
| 2995 | 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 | 3069 | private->count--; |
| 2998 | 3070 | dasd_ffree_request(cqr, device); |
| 2999 | 3071 | } |
| 3000 | 3072 | |
| 3001 | 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 | 3077 | struct dasd_eckd_private *private; |
| 3078 | + struct dasd_format_entry *format; | |
| 3005 | 3079 | struct format_data_t fdata; |
| 3006 | 3080 | unsigned int recs_per_trk; |
| 3007 | 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 | 3085 | struct request *req; |
| 3012 | 3086 | sector_t first_trk; |
| 3013 | 3087 | sector_t last_trk; |
| 3088 | + sector_t curr_trk; | |
| 3014 | 3089 | int rc; |
| 3015 | 3090 | |
| 3016 | 3091 | req = cqr->callback_data; |
| 3017 | − base = cqr->block->base; | |
| 3092 | + block = cqr->block; | |
| 3093 | + base = block->base; | |
| 3018 | 3094 | private = base->private; |
| 3019 | − block = base->block; | |
| 3020 | 3095 | blksize = block->bp_block; |
| 3021 | 3096 | recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
| 3097 | + format = &startdev->format_entry; | |
| 3022 | 3098 | |
| 3023 | 3099 | first_trk = blk_rq_pos(req) >> block->s2b_shift; |
| 3024 | 3100 | sector_div(first_trk, recs_per_trk); |
| 3025 | 3101 | last_trk = |
| 3026 | 3102 | (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; |
| 3027 | 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; | |
| 3030 | − fdata.stop_unit = last_trk; | |
| 3108 | + if (curr_trk < first_trk || curr_trk > 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 | 3121 | fdata.blksize = blksize; |
| 3032 | 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 | 3134 | return fcqr; |
| 3045 | 3135 | |
| 3046 | 3136 | fcqr->callback = dasd_eckd_ese_format_cb; |
| 3137 | + fcqr->callback_data = (void *) format; | |
| 3047 | 3138 | |
| 3048 | 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 | 3143 | * When data is read from an unformatted area of an ESE volume, this function |
| 3053 | 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 | 3159 | unsigned int blksize, off; |
| 3160 | + unsigned int recs_per_trk; | |
| 3058 | 3161 | struct dasd_device *base; |
| 3059 | 3162 | struct req_iterator iter; |
| 3163 | + struct dasd_block *block; | |
| 3164 | + unsigned int skip_block; | |
| 3165 | + unsigned int blk_count; | |
| 3060 | 3166 | struct request *req; |
| 3061 | 3167 | struct bio_vec bv; |
| 3168 | + sector_t curr_trk; | |
| 3169 | + sector_t end_blk; | |
| 3062 | 3170 | char *dst; |
| 3171 | + int rc; | |
| 3063 | 3172 | |
| 3064 | 3173 | req = (struct request *) cqr->callback_data; |
| 3065 | 3174 | base = cqr->block->base; |
| 3066 | 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 | 3209 | rq_for_each_segment(bv, req, iter) { |
| 3069 | 3210 | dst = page_address(bv.bv_page) + bv.bv_offset; |
| 3070 | 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 | 3217 | dst += off; |
| 3073 | 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 | 188 | void (*callback)(struct dasd_ccw_req *, void *data); |
| 189 | 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 | 388 | int (*ext_pool_warn_thrshld)(struct dasd_device *); |
| 388 | 389 | int (*ext_pool_oos)(struct dasd_device *); |
| 389 | 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 | − void (*ese_read)(struct dasd_ccw_req *); | |
| 391 | + struct dasd_ccw_req *(*ese_format)(struct dasd_device *, | |
| 392 | + struct dasd_ccw_req *, struct irb *); | |
| 393 | + int (*ese_read)(struct dasd_ccw_req *, struct irb *); | |
| 392 | 394 | }; |
| 393 | 395 | |
| 394 | 396 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
| @@ -474,6 +476,11 @@ struct dasd_profile { · 79 unmodified lines | ||
| 474 | 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 | 484 | struct dasd_device { |
| 478 | 485 | /* Block device stuff. */ |
| 479 | 486 | struct dasd_block *block; |
| @@ -539,6 +546,7 @@ struct dasd_device { · 59 unmodified lines | ||
| 539 | 546 | struct dentry *debugfs_dentry; |
| 540 | 547 | struct dentry *hosts_dentry; |
| 541 | 548 | struct dasd_profile profile; |
| 549 | + struct dasd_format_entry format_entry; | |
| 542 | 550 | }; |
| 543 | 551 | |
| 544 | 552 | struct dasd_block { |
| @@ -564,6 +572,9 @@ struct dasd_block { · 19 unmodified lines | ||
| 564 | 572 | |
| 565 | 573 | struct dentry *debugfs_dentry; |
| 566 | 574 | struct dasd_profile profile; |
| 575 | + | |
| 576 | + struct list_head format_list; | |
| 577 | + spinlock_t format_lock; | |
| 567 | 578 | }; |
| 568 | 579 | |
| 569 | 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 | 9950 | ioa_cfg->max_devs_supported = ipr_max_devs; |
| 9951 | 9951 | |
| 9952 | 9952 | if (ioa_cfg->sis64) { |
| 9953 | + host->max_channel = IPR_MAX_SIS64_BUSES; | |
| 9953 | 9954 | host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; |
| 9954 | 9955 | host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; |
| 9955 | 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 | 9959 | + ((sizeof(struct ipr_config_table_entry64) |
| 9959 | 9960 | * ioa_cfg->max_devs_supported))); |
| 9960 | 9961 | } else { |
| 9962 | + host->max_channel = IPR_VSET_BUS; | |
| 9961 | 9963 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; |
| 9962 | 9964 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; |
| 9963 | 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 | 9969 | * ioa_cfg->max_devs_supported))); |
| 9968 | 9970 | } |
| 9969 | 9971 | |
| 9970 | − host->max_channel = IPR_VSET_BUS; | |
| 9971 | 9972 | host->unique_id = host->host_no; |
| 9972 | 9973 | host->max_cmd_len = IPR_MAX_CDB_LEN; |
| 9973 | 9974 | host->can_queue = ioa_cfg->max_cmds; |
| @@ -1300,6 +1300,7 @@ struct ipr_resource_entry { · 1299 unmodified lines | ||
| 1300 | 1300 | #define IPR_ARRAY_VIRTUAL_BUS 0x1 |
| 1301 | 1301 | #define IPR_VSET_VIRTUAL_BUS 0x2 |
| 1302 | 1302 | #define IPR_IOAFP_VIRTUAL_BUS 0x3 |
| 1303 | +#define IPR_MAX_SIS64_BUSES 0x4 | |
| 1303 | 1304 | |
| 1304 | 1305 | #define IPR_GET_RES_PHYS_LOC(res) \ |
| 1305 | 1306 | (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) |
| @@ -3884,18 +3884,25 @@ EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_exit); · 3883 unmodified lines | ||
| 3884 | 3884 | void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) |
| 3885 | 3885 | { |
| 3886 | 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 | 3890 | return; |
| 3890 | 3891 | |
| 3891 | 3892 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 3892 | − if (hba->ahit == ahit) | |
| 3893 | − goto out_unlock; | |
| 3894 | − hba->ahit = ahit; | |
| 3895 | − if (!pm_runtime_suspended(hba->dev)) | |
| 3896 | − ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); | |
| 3897 | −out_unlock: | |
| 3893 | + if (hba->ahit != ahit) { | |
| 3894 | + hba->ahit = ahit; | |
| 3895 | + update = true; | |
| 3896 | + } | |
| 3898 | 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 | 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 | 1321 | .compatible = "qcom,slim-ngd-v1.5.0", |
| 1322 | 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 | 19 | #include <signal.h> |
| 20 | 20 | |
| 21 | 21 | #define MAX_NUM_DEVICES 10 |
| 22 | +#define MAX_SYSFS_PREFIX 0x80 | |
| 22 | 23 | #define MAX_SYSFS_PATH 0x200 |
| 23 | 24 | #define CSV_MAX_LINE 0x1000 |
| 24 | 25 | #define SYSFS_MAX_INT 0x20 |
| @@ -67,7 +68,7 @@ struct loopback_results { · 42 unmodified lines | ||
| 67 | 68 | }; |
| 68 | 69 | |
| 69 | 70 | struct loopback_device { |
| 70 | − char name[MAX_SYSFS_PATH]; | |
| 71 | + char name[MAX_STR_LEN]; | |
| 71 | 72 | char sysfs_entry[MAX_SYSFS_PATH]; |
| 72 | 73 | char debugfs_entry[MAX_SYSFS_PATH]; |
| 73 | 74 | struct loopback_results results; |
| @@ -93,8 +94,8 @@ struct loopback_test { · 19 unmodified lines | ||
| 93 | 94 | int stop_all; |
| 94 | 95 | int poll_count; |
| 95 | 96 | char test_name[MAX_STR_LEN]; |
| 96 | − char sysfs_prefix[MAX_SYSFS_PATH]; | |
| 97 | − char debugfs_prefix[MAX_SYSFS_PATH]; | |
| 97 | + char sysfs_prefix[MAX_SYSFS_PREFIX]; | |
| 98 | + char debugfs_prefix[MAX_SYSFS_PREFIX]; | |
| 98 | 99 | struct timespec poll_timeout; |
| 99 | 100 | struct loopback_device devices[MAX_NUM_DEVICES]; |
| 100 | 101 | struct loopback_results aggregate_results; |
| @@ -637,7 +638,7 @@ baddir: · 536 unmodified lines | ||
| 637 | 638 | static int open_poll_files(struct loopback_test *t) |
| 638 | 639 | { |
| 639 | 640 | struct loopback_device *dev; |
| 640 | − char buf[MAX_STR_LEN]; | |
| 641 | + char buf[MAX_SYSFS_PATH + MAX_STR_LEN]; | |
| 641 | 642 | char dummy; |
| 642 | 643 | int fds_idx = 0; |
| 643 | 644 | int i; |
| @@ -655,7 +656,7 @@ static int open_poll_files(struct loopback_test *t) · 11 unmodified lines | ||
| 655 | 656 | goto err; |
| 656 | 657 | } |
| 657 | 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 | 660 | t->fds[fds_idx].revents = 0; |
| 660 | 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 | 751 | for (i = 0; i < t->poll_count; i++) { |
| 751 | − if (t->fds[i].revents & EPOLLPRI) { | |
| 752 | + if (t->fds[i].revents & POLLPRI) { | |
| 752 | 753 | /* Dummy read to clear the event */ |
| 753 | 754 | read(t->fds[i].fd, &dummy, 1); |
| 754 | 755 | number_of_events++; |
| @@ -907,10 +908,10 @@ int main(int argc, char *argv[]) · 152 unmodified lines | ||
| 907 | 908 | t.iteration_max = atoi(optarg); |
| 908 | 909 | break; |
| 909 | 910 | case 'S': |
| 910 | − snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", optarg); | |
| 911 | + snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg); | |
| 911 | 912 | break; |
| 912 | 913 | case 'D': |
| 913 | − snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", optarg); | |
| 914 | + snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg); | |
| 914 | 915 | break; |
| 915 | 916 | case 'm': |
| 916 | 917 | t.mask = atol(optarg); |
| @@ -961,10 +962,10 @@ int main(int argc, char *argv[]) · 44 unmodified lines | ||
| 961 | 962 | } |
| 962 | 963 | |
| 963 | 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 | 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 | 970 | ret = find_loopback_devices(&t); |
| 970 | 971 | if (ret) |
| @@ -38,6 +38,7 @@ static const struct usb_device_id rtw_usb_id_tbl[] = { · 37 unmodified lines | ||
| 38 | 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ |
| 39 | 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ |
| 40 | 40 | {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ |
| 41 | + {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */ | |
| 41 | 42 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ |
| 42 | 43 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ |
| 43 | 44 | {} /* Terminating entry */ |
| @@ -561,7 +561,7 @@ static u_long get_word(struct vc_data *vc) · 560 unmodified lines | ||
| 561 | 561 | return 0; |
| 562 | 562 | } else if (tmpx < vc->vc_cols - 2 && |
| 563 | 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 | 565 | tmp_pos += 2; |
| 566 | 566 | tmpx++; |
| 567 | 567 | } else { |
| @@ -140,6 +140,7 @@ int hif_shutdown(struct wfx_dev *wdev) · 139 unmodified lines | ||
| 140 | 140 | else |
| 141 | 141 | control_reg_write(wdev, 0); |
| 142 | 142 | mutex_unlock(&wdev->hif_cmd.lock); |
| 143 | + mutex_unlock(&wdev->hif_cmd.key_renew_lock); | |
| 143 | 144 | kfree(hif); |
| 144 | 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 | 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 | 295 | int ret; |
| 295 | 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 | 308 | body->basic_rate_set = |
| 308 | 309 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); |
| 309 | 310 | memcpy(body->bssid, conf->bssid, sizeof(body->bssid)); |
| 310 | − if (!conf->ibss_joined && ssidie) { | |
| 311 | − body->ssid_length = cpu_to_le32(ssidie[1]); | |
| 312 | − memcpy(body->ssid, &ssidie[2], ssidie[1]); | |
| 311 | + if (!conf->ibss_joined && ssid) { | |
| 312 | + body->ssid_length = cpu_to_le32(ssidlen); | |
| 313 | + memcpy(body->ssid, ssid, ssidlen); | |
| 313 | 314 | } |
| 314 | 315 | wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body)); |
| 315 | 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 | 428 | struct hif_msg *hif; |
| 428 | 429 | struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif); |
| 429 | 430 | |
| 430 | − body->dtim_period = conf->dtim_period, | |
| 431 | − body->short_preamble = conf->use_short_preamble, | |
| 432 | − body->channel_number = cpu_to_le16(channel->hw_value), | |
| 431 | + body->dtim_period = conf->dtim_period; | |
| 432 | + body->short_preamble = conf->use_short_preamble; | |
| 433 | + body->channel_number = cpu_to_le16(channel->hw_value); | |
| 433 | 434 | body->beacon_interval = cpu_to_le32(conf->beacon_int); |
| 434 | 435 | body->basic_rate_set = |
| 435 | 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 | 46 | int chan_start, int chan_num); |
| 47 | 47 | int hif_stop_scan(struct wfx_vif *wvif); |
| 48 | 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 | 50 | int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); |
| 51 | 51 | int hif_set_bss_params(struct wfx_vif *wvif, |
| 52 | 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 | 193 | static inline int hif_set_association_mode(struct wfx_vif *wvif, |
| 194 | − struct ieee80211_bss_conf *info, | |
| 195 | − struct ieee80211_sta_ht_cap *ht_cap) | |
| 194 | + struct ieee80211_bss_conf *info) | |
| 196 | 195 | { |
| 197 | 196 | int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates); |
| 197 | + struct ieee80211_sta *sta = NULL; | |
| 198 | 198 | struct hif_mib_set_association_mode val = { |
| 199 | 199 | .preambtype_use = 1, |
| 200 | 200 | .mode = 1, |
| @@ -204,12 +204,17 @@ static inline int hif_set_association_mode(struct wfx_vif *wvif, · 3 unmodified lines | ||
| 204 | 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 | 211 | // FIXME: it is strange to not retrieve all information from bss_info |
| 208 | − if (ht_cap && ht_cap->ht_supported) { | |
| 209 | − val.mpdu_start_spacing = ht_cap->ampdu_density; | |
| 212 | + if (sta && sta->ht_cap.ht_supported) { | |
| 213 | + val.mpdu_start_spacing = sta->ht_cap.ampdu_density; | |
| 210 | 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 | 219 | return hif_write_mib(wvif->wdev, wvif->id, |
| 215 | 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 | 491 | static void wfx_do_join(struct wfx_vif *wvif) |
| 492 | 492 | { |
| 493 | 493 | int ret; |
| 494 | − const u8 *ssidie; | |
| 495 | 494 | struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; |
| 496 | 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 | 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 | 516 | if (!wvif->beacon_int) |
| 515 | 517 | wvif->beacon_int = 1; |
| 516 | 518 | |
| 517 | − rcu_read_lock(); | |
| 519 | + rcu_read_lock(); // protect ssidie | |
| 518 | 520 | if (!conf->ibss_joined) |
| 519 | 521 | ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); |
| 520 | − else | |
| 521 | − ssidie = NULL; | |
| 522 | + if (ssidie) { | |
| 523 | + ssidlen = ssidie[1]; | |
| 524 | + memcpy(ssid, &ssidie[2], ssidie[1]); | |
| 525 | + } | |
| 526 | + rcu_read_unlock(); | |
| 522 | 527 | |
| 523 | 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 | 533 | wfx_set_mfp(wvif, bss); |
| 529 | 534 | |
| 530 | − /* Perform actual join */ | |
| 531 | 535 | wvif->wdev->tx_burst_idx = -1; |
| 532 | − ret = hif_join(wvif, conf, wvif->channel, ssidie); | |
| 533 | − rcu_read_unlock(); | |
| 536 | + ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); | |
| 534 | 537 | if (ret) { |
| 535 | 538 | ieee80211_connection_loss(wvif->vif); |
| 536 | 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 | 608 | int i; |
| 606 | 609 | |
| 607 | 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 | 614 | // FIXME: see note in wfx_sta_add() |
| 610 | 615 | if (vif->type == NL80211_IFTYPE_STATION) |
| 611 | 616 | return 0; |
| @@ -689,6 +694,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, · 77 unmodified lines | ||
| 689 | 694 | wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]); |
| 690 | 695 | else |
| 691 | 696 | wvif->bss_params.operational_rate_set = -1; |
| 697 | + rcu_read_unlock(); | |
| 692 | 698 | if (sta && |
| 693 | 699 | info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) |
| 694 | 700 | hif_dual_cts_protection(wvif, true); |
| @@ -701,8 +707,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, · 6 unmodified lines | ||
| 701 | 707 | wvif->bss_params.beacon_lost_count = 20; |
| 702 | 708 | wvif->bss_params.aid = info->aid; |
| 703 | 709 | |
| 704 | − hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL); | |
| 705 | − rcu_read_unlock(); | |
| 710 | + hif_set_association_mode(wvif, info); | |
| 706 | 711 | |
| 707 | 712 | if (!info->ibss_joined) { |
| 708 | 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 | 954 | ret = tb_port_read(port, &phy, TB_CFG_PORT, |
| 955 | 955 | port->cap_phy + LANE_ADP_CS_0, 1); |
| 956 | 956 | if (ret) |
| 957 | − return ret; | |
| 957 | + return false; | |
| 958 | 958 | |
| 959 | 959 | widths = (phy & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> |
| 960 | 960 | LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT; |
| @@ -1589,9 +1589,7 @@ void tty_kclose(struct tty_struct *tty) · 1588 unmodified lines | ||
| 1589 | 1589 | tty_debug_hangup(tty, "freeing structure\n"); |
| 1590 | 1590 | /* |
| 1591 | 1591 | * The release_tty function takes care of the details of clearing |
| 1592 | − * the slots and preserving the termios structure. The tty_unlock_pair | |
| 1593 | − * should be safe as we keep a kref while the tty is locked (so the | |
| 1594 | − * unlock never unlocks a freed tty). | |
| 1592 | + * the slots and preserving the termios structure. | |
| 1595 | 1593 | */ |
| 1596 | 1594 | mutex_lock(&tty_mutex); |
| 1597 | 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 | 1619 | tty_debug_hangup(tty, "freeing structure\n"); |
| 1622 | 1620 | /* |
| 1623 | 1621 | * The release_tty function takes care of the details of clearing |
| 1624 | − * the slots and preserving the termios structure. The tty_unlock_pair | |
| 1625 | − * should be safe as we keep a kref while the tty is locked (so the | |
| 1626 | − * unlock never unlocks a freed tty). | |
| 1622 | + * the slots and preserving the termios structure. | |
| 1627 | 1623 | */ |
| 1628 | 1624 | mutex_lock(&tty_mutex); |
| 1629 | 1625 | release_tty(tty, idx); |
| @@ -2734,9 +2730,11 @@ static int compat_tty_tiocgserial(struct tty_struct *tty, · 1104 unmodified lines | ||
| 2734 | 2730 | struct serial_struct32 v32; |
| 2735 | 2731 | struct serial_struct v; |
| 2736 | 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 | 2738 | return -ENOTTY; |
| 2741 | 2739 | err = tty->ops->get_serial(tty, &v); |
| 2742 | 2740 | if (!err) { |
| @@ -1530,18 +1530,19 @@ static const struct usb_ep_ops usb_ep_ops = { · 1529 unmodified lines | ||
| 1530 | 1530 | static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) |
| 1531 | 1531 | { |
| 1532 | 1532 | struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); |
| 1533 | − unsigned long flags; | |
| 1534 | 1533 | |
| 1535 | 1534 | if (is_active) { |
| 1536 | 1535 | pm_runtime_get_sync(&_gadget->dev); |
| 1537 | 1536 | hw_device_reset(ci); |
| 1538 | − spin_lock_irqsave(&ci->lock, flags); | |
| 1537 | + spin_lock_irq(&ci->lock); | |
| 1539 | 1538 | if (ci->driver) { |
| 1540 | 1539 | hw_device_state(ci, ci->ep0out->qh.dma); |
| 1541 | 1540 | usb_gadget_set_state(_gadget, USB_STATE_POWERED); |
| 1541 | + spin_unlock_irq(&ci->lock); | |
| 1542 | 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 | 1546 | } else { |
| 1546 | 1547 | usb_udc_vbus_handler(_gadget, false); |
| 1547 | 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 | 897 | ss->xmit_fifo_size = acm->writesize; |
| 898 | 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 | 900 | ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
| 901 | 901 | ASYNC_CLOSING_WAIT_NONE : |
| 902 | − acm->port.closing_wait / 10; | |
| 902 | + jiffies_to_msecs(acm->port.closing_wait) / 10; | |
| 903 | 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 | 908 | struct acm *acm = tty->driver_data; |
| 909 | 909 | unsigned int closing_wait, close_delay; |
| 910 | + unsigned int old_closing_wait, old_close_delay; | |
| 910 | 911 | int retval = 0; |
| 911 | 912 | |
| 912 | − close_delay = ss->close_delay * 10; | |
| 913 | + close_delay = msecs_to_jiffies(ss->close_delay * 10); | |
| 913 | 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 | 924 | mutex_lock(&acm->port.mutex); |
| 917 | 925 | |
| 918 | − if (!capable(CAP_SYS_ADMIN)) { | |
| 919 | − if ((close_delay != acm->port.close_delay) || | |
| 920 | − (closing_wait != acm->port.closing_wait)) | |
| 926 | + if ((ss->close_delay != old_close_delay) || | |
| 927 | + (ss->closing_wait != old_closing_wait)) { | |
| 928 | + if (!capable(CAP_SYS_ADMIN)) | |
| 921 | 929 | retval = -EPERM; |
| 922 | − else | |
| 923 | − retval = -EOPNOTSUPP; | |
| 924 | − } else { | |
| 925 | − acm->port.close_delay = close_delay; | |
| 926 | − acm->port.closing_wait = closing_wait; | |
| 927 | − } | |
| 930 | + else { | |
| 931 | + acm->port.close_delay = close_delay; | |
| 932 | + acm->port.closing_wait = closing_wait; | |
| 933 | + } | |
| 934 | + } else | |
| 935 | + retval = -EOPNOTSUPP; | |
| 928 | 936 | |
| 929 | 937 | mutex_unlock(&acm->port.mutex); |
| 930 | 938 | return retval; |
| @@ -378,6 +378,12 @@ static const struct usb_device_id usb_quirk_list[] = { · 377 unmodified lines | ||
| 378 | 378 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = |
| 379 | 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 | 387 | /* Action Semiconductor flash disk */ |
| 382 | 388 | { USB_DEVICE(0x10d6, 0x2200), .driver_info = |
| 383 | 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 | 136 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
| 137 | 137 | |
| 138 | 138 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
| 139 | − (pdev->device == 0x15e0 || | |
| 139 | + (pdev->device == 0x145c || | |
| 140 | + pdev->device == 0x15e0 || | |
| 140 | 141 | pdev->device == 0x15e1 || |
| 141 | 142 | pdev->device == 0x43bb)) |
| 142 | 143 | xhci->quirks |= XHCI_SUSPEND_DELAY; |
| @@ -445,6 +445,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); · 444 unmodified lines | ||
| 445 | 445 | static struct platform_driver usb_xhci_driver = { |
| 446 | 446 | .probe = xhci_plat_probe, |
| 447 | 447 | .remove = xhci_plat_remove, |
| 448 | + .shutdown = usb_hcd_platform_shutdown, | |
| 448 | 449 | .driver = { |
| 449 | 450 | .name = "xhci-hcd", |
| 450 | 451 | .pm = &xhci_plat_pm_ops, |
| @@ -289,23 +289,12 @@ DECLARE_EVENT_CLASS(xhci_log_urb, · 288 unmodified lines | ||
| 289 | 289 | ), |
| 290 | 290 | TP_printk("ep%d%s-%s: urb %p pipe %u slot %d length %d/%d sgs %d/%d stream %d flags %08x", |
| 291 | 291 | __entry->epnum, __entry->dir_in ? "in" : "out", |
| 292 | − ({ char *s; | |
| 293 | − switch (__entry->type) { | |
| 294 | − case USB_ENDPOINT_XFER_INT: | |
| 295 | − s = "intr"; | |
| 296 | − break; | |
| 297 | − case USB_ENDPOINT_XFER_CONTROL: | |
| 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, | |
| 292 | + __print_symbolic(__entry->type, | |
| 293 | + { USB_ENDPOINT_XFER_INT, "intr" }, | |
| 294 | + { USB_ENDPOINT_XFER_CONTROL, "control" }, | |
| 295 | + { USB_ENDPOINT_XFER_BULK, "bulk" }, | |
| 296 | + { USB_ENDPOINT_XFER_ISOC, "isoc" }), | |
| 297 | + __entry->urb, __entry->pipe, __entry->slot_id, | |
| 309 | 298 | __entry->actual, __entry->length, __entry->num_mapped_sgs, |
| 310 | 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 | 1183 | .driver_info = NCTRL(0) }, |
| 1184 | 1184 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff), /* Telit ME910G1 */ |
| 1185 | 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 | 1188 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), |
| 1187 | 1189 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1188 | 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 | 99 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
| 100 | 100 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
| 101 | 101 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) }, |
| 102 | + { USB_DEVICE(HP_VENDOR_ID, HP_LD381_PRODUCT_ID) }, | |
| 102 | 103 | { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, |
| 103 | 104 | { USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) }, |
| 104 | 105 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, |
| @@ -130,6 +130,7 @@ · 129 unmodified lines | ||
| 130 | 130 | #define HP_LM920_PRODUCT_ID 0x026b |
| 131 | 131 | #define HP_TD620_PRODUCT_ID 0x0956 |
| 132 | 132 | #define HP_LD960_PRODUCT_ID 0x0b39 |
| 133 | +#define HP_LD381_PRODUCT_ID 0x0f7f | |
| 133 | 134 | #define HP_LCM220_PRODUCT_ID 0x3139 |
| 134 | 135 | #define HP_LCM960_PRODUCT_ID 0x3239 |
| 135 | 136 | #define HP_LD220_PRODUCT_ID 0x3524 |
| @@ -271,6 +271,9 @@ void ucsi_displayport_remove_partner(struct typec_altmode *alt) · 270 unmodified lines | ||
| 271 | 271 | return; |
| 272 | 272 | |
| 273 | 273 | dp = typec_altmode_get_drvdata(alt); |
| 274 | + if (!dp) | |
| 275 | + return; | |
| 276 | + | |
| 274 | 277 | dp->data.conf = 0; |
| 275 | 278 | dp->data.status = 0; |
| 276 | 279 | dp->initialized = false; |
| @@ -285,6 +288,8 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, · 8 unmodified lines | ||
| 285 | 288 | struct typec_altmode *alt; |
| 286 | 289 | struct ucsi_dp *dp; |
| 287 | 290 | |
| 291 | + mutex_lock(&con->lock); | |
| 292 | + | |
| 288 | 293 | /* We can't rely on the firmware with the capabilities. */ |
| 289 | 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 | 298 | desc->vdo |= all_assignments << 16; |
| 294 | 299 | |
| 295 | 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 | 303 | return alt; |
| 304 | + } | |
| 298 | 305 | |
| 299 | 306 | dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL); |
| 300 | 307 | if (!dp) { |
| 301 | 308 | typec_unregister_altmode(alt); |
| 309 | + mutex_unlock(&con->lock); | |
| 302 | 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 | 319 | alt->ops = &ucsi_displayport_ops; |
| 312 | 320 | typec_altmode_set_drvdata(alt, dp); |
| 313 | 321 | |
| 322 | + mutex_unlock(&con->lock); | |
| 323 | + | |
| 314 | 324 | return alt; |
| 315 | 325 | } |
| @@ -1,10 +1,12 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | /* iTCO Vendor Specific Support hooks */ |
| 3 | 3 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT |
| 4 | +extern int iTCO_vendorsupport; | |
| 4 | 5 | extern void iTCO_vendor_pre_start(struct resource *, unsigned int); |
| 5 | 6 | extern void iTCO_vendor_pre_stop(struct resource *); |
| 6 | 7 | extern int iTCO_vendor_check_noreboot_on(void); |
| 7 | 8 | #else |
| 9 | +#define iTCO_vendorsupport 0 | |
| 8 | 10 | #define iTCO_vendor_pre_start(acpibase, heartbeat) {} |
| 9 | 11 | #define iTCO_vendor_pre_stop(acpibase) {} |
| 10 | 12 | #define iTCO_vendor_check_noreboot_on() 1 |
| @@ -39,8 +39,10 @@ · 38 unmodified lines | ||
| 39 | 39 | /* Broken BIOS */ |
| 40 | 40 | #define BROKEN_BIOS 911 |
| 41 | 41 | |
| 42 | −static int vendorsupport; | |
| 43 | −module_param(vendorsupport, int, 0); | |
| 42 | +int iTCO_vendorsupport; | |
| 43 | +EXPORT_SYMBOL(iTCO_vendorsupport); | |
| 44 | + | |
| 45 | +module_param_named(vendorsupport, iTCO_vendorsupport, int, 0); | |
| 44 | 46 | MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" |
| 45 | 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 | 154 | void iTCO_vendor_pre_start(struct resource *smires, |
| 153 | 155 | unsigned int heartbeat) |
| 154 | 156 | { |
| 155 | − switch (vendorsupport) { | |
| 157 | + switch (iTCO_vendorsupport) { | |
| 156 | 158 | case SUPERMICRO_OLD_BOARD: |
| 157 | 159 | supermicro_old_pre_start(smires); |
| 158 | 160 | break; |
| @@ -165,7 +167,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_start); · 6 unmodified lines | ||
| 165 | 167 | |
| 166 | 168 | void iTCO_vendor_pre_stop(struct resource *smires) |
| 167 | 169 | { |
| 168 | − switch (vendorsupport) { | |
| 170 | + switch (iTCO_vendorsupport) { | |
| 169 | 171 | case SUPERMICRO_OLD_BOARD: |
| 170 | 172 | supermicro_old_pre_stop(smires); |
| 171 | 173 | break; |
| @@ -178,7 +180,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_stop); · 6 unmodified lines | ||
| 178 | 180 | |
| 179 | 181 | int iTCO_vendor_check_noreboot_on(void) |
| 180 | 182 | { |
| 181 | − switch (vendorsupport) { | |
| 183 | + switch (iTCO_vendorsupport) { | |
| 182 | 184 | case SUPERMICRO_OLD_BOARD: |
| 183 | 185 | return 0; |
| 184 | 186 | default: |
| @@ -189,13 +191,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); · 4 unmodified lines | ||
| 189 | 191 | |
| 190 | 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 | 195 | pr_warn("Option vendorsupport=%d is no longer supported, " |
| 194 | 196 | "please use the w83627hf_wdt driver instead\n", |
| 195 | 197 | SUPERMICRO_NEW_BOARD); |
| 196 | 198 | return -EINVAL; |
| 197 | 199 | } |
| 198 | − pr_info("vendor-support=%d\n", vendorsupport); | |
| 200 | + pr_info("vendor-support=%d\n", iTCO_vendorsupport); | |
| 199 | 201 | return 0; |
| 200 | 202 | } |
| 201 | 203 | |
| @@ -459,13 +459,25 @@ static int iTCO_wdt_probe(struct platform_device *pdev) · 458 unmodified lines | ||
| 459 | 459 | if (!p->tco_res) |
| 460 | 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 | 462 | p->iTCO_version = pdata->version; |
| 467 | 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 | 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 | 504 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ |
| 493 | 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 | 507 | if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { |
| 504 | 508 | /* |
| 505 | 509 | * Bit 13: TCO_EN -> 0 |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | void afs_put_addrlist(struct afs_addr_list *alist) |
| 20 | 20 | { |
| 21 | 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 | 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 | 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 | 521 | if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) |
| 511 | 522 | afs_send_empty_reply(call); |
| 512 | 523 | else |
| 513 | − rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | |
| 514 | − 1, 1, "K-1"); | |
| 524 | + afs_abort_service_call(call, 1, 1, "K-1"); | |
| 515 | 525 | |
| 516 | 526 | afs_put_call(call); |
| 517 | 527 | _leave(""); |
| @@ -81,7 +81,7 @@ enum afs_call_state { · 80 unmodified lines | ||
| 81 | 81 | * List of server addresses. |
| 82 | 82 | */ |
| 83 | 83 | struct afs_addr_list { |
| 84 | − struct rcu_head rcu; /* Must be first */ | |
| 84 | + struct rcu_head rcu; | |
| 85 | 85 | refcount_t usage; |
| 86 | 86 | u32 version; /* Version */ |
| 87 | 87 | unsigned char max_addrs; |
| @@ -154,7 +154,7 @@ struct afs_call { · 66 unmodified lines | ||
| 154 | 154 | }; |
| 155 | 155 | unsigned char unmarshall; /* unmarshalling phase */ |
| 156 | 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 | 158 | bool send_pages; /* T if data from mapping should be sent */ |
| 159 | 159 | bool need_attention; /* T if RxRPC poked us */ |
| 160 | 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 | 1209 | ok = true; |
| 1210 | 1210 | } |
| 1211 | 1211 | spin_unlock_bh(&call->state_lock); |
| 1212 | − if (ok) | |
| 1212 | + if (ok) { | |
| 1213 | 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 | 19 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); |
| 20 | 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 | 21 | static void afs_process_async_call(struct work_struct *); |
| 23 | 22 | static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long); |
| 24 | 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 | 168 | int n = atomic_dec_return(&call->usage); |
| 170 | 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 | 172 | __builtin_return_address(0)); |
| 174 | 173 | |
| 175 | 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 | 401 | /* If the call is going to be asynchronous, we need an extra ref for |
| 403 | 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 | 405 | afs_get_call(call, afs_call_trace_get); |
| 406 | + call->drop_ref = true; | |
| 407 | + } | |
| 407 | 408 | |
| 408 | 409 | /* create a call */ |
| 409 | 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 | 414 | afs_wake_up_async_call : |
| 414 | 415 | afs_wake_up_call_waiter), |
| 415 | 416 | call->upgrade, |
| 416 | − call->intr, | |
| 417 | + (call->intr ? RXRPC_PREINTERRUPTIBLE : | |
| 418 | + RXRPC_UNINTERRUPTIBLE), | |
| 417 | 419 | call->debug_id); |
| 418 | 420 | if (IS_ERR(rxcall)) { |
| 419 | 421 | ret = PTR_ERR(rxcall); |
| @@ -584,8 +586,6 @@ static void afs_deliver_to_call(struct afs_call *call) · 164 unmodified lines | ||
| 584 | 586 | done: |
| 585 | 587 | if (call->type->done) |
| 586 | 588 | call->type->done(call); |
| 587 | − if (state == AFS_CALL_COMPLETE && call->incoming) | |
| 588 | − afs_put_call(call); | |
| 589 | 589 | out: |
| 590 | 590 | _leave(""); |
| 591 | 591 | return; |
| @@ -604,11 +604,7 @@ call_complete: · 12 unmodified lines | ||
| 604 | 604 | long afs_wait_for_call_to_complete(struct afs_call *call, |
| 605 | 605 | struct afs_addr_cursor *ac) |
| 606 | 606 | { |
| 607 | − signed long rtt2, timeout; | |
| 608 | 607 | long ret; |
| 609 | − bool stalled = false; | |
| 610 | − u64 rtt; | |
| 611 | − u32 life, last_life; | |
| 612 | 608 | bool rxrpc_complete = false; |
| 613 | 609 | |
| 614 | 610 | DECLARE_WAITQUEUE(myself, current); |
| @@ -619,14 +615,6 @@ long afs_wait_for_call_to_complete(struct afs_call *call, · 4 unmodified lines | ||
| 619 | 615 | if (ret < 0) |
| 620 | 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 | 618 | add_wait_queue(&call->waitq, &myself); |
| 631 | 619 | for (;;) { |
| 632 | 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 | 625 | call->need_attention = false; |
| 638 | 626 | __set_current_state(TASK_RUNNING); |
| 639 | 627 | afs_deliver_to_call(call); |
| 640 | − timeout = rtt2; | |
| 641 | 628 | continue; |
| 642 | 629 | } |
| 643 | 630 | |
| 644 | 631 | if (afs_check_call_state(call, AFS_CALL_COMPLETE)) |
| 645 | 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 | 635 | /* rxrpc terminated the call. */ |
| 649 | 636 | rxrpc_complete = true; |
| 650 | 637 | break; |
| 651 | 638 | } |
| 652 | 639 | |
| 653 | − if (call->intr && timeout == 0 && | |
| 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); | |
| 640 | + schedule(); | |
| 671 | 641 | } |
| 672 | 642 | |
| 673 | 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 | 706 | u = atomic_fetch_add_unless(&call->usage, 1, 0); |
| 737 | 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 | 709 | atomic_read(&call->net->nr_outstanding_calls), |
| 740 | 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 | 718 | * Perform I/O processing on an asynchronous call. The work item carries a ref |
| 764 | 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 | 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 | 732 | afs_put_call(call); |
| 788 | 733 | _leave(""); |
| 789 | 734 | } |
| @@ -810,6 +755,7 @@ void afs_charge_preallocation(struct work_struct *work) · 20 unmodified lines | ||
| 810 | 755 | if (!call) |
| 811 | 756 | break; |
| 812 | 757 | |
| 758 | + call->drop_ref = true; | |
| 813 | 759 | call->async = true; |
| 814 | 760 | call->state = AFS_CALL_SV_AWAIT_OP_ID; |
| 815 | 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 | 856 | found_raid1c34 = true; |
| 857 | 857 | up_read(&sinfo->groups_sem); |
| 858 | 858 | } |
| 859 | − if (found_raid56) | |
| 859 | + if (!found_raid56) | |
| 860 | 860 | btrfs_clear_fs_incompat(fs_info, RAID56); |
| 861 | − if (found_raid1c34) | |
| 861 | + if (!found_raid1c34) | |
| 862 | 862 | btrfs_clear_fs_incompat(fs_info, RAID1C34); |
| 863 | 863 | } |
| 864 | 864 | } |
| @@ -9496,6 +9496,10 @@ out_fail: · 9495 unmodified lines | ||
| 9496 | 9496 | ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root, &ctx); |
| 9497 | 9497 | if (ret) |
| 9498 | 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 | 9504 | if (commit_transaction) { |
| 9501 | 9505 | ret = btrfs_commit_transaction(trans); |
| @@ -1169,7 +1169,8 @@ try_again: · 1168 unmodified lines | ||
| 1169 | 1169 | rc = posix_lock_file(file, flock, NULL); |
| 1170 | 1170 | up_write(&cinode->lock_sem); |
| 1171 | 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 | 1174 | if (!rc) |
| 1174 | 1175 | goto try_again; |
| 1175 | 1176 | locks_delete_block(flock); |
| @@ -2191,7 +2191,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat, · 2190 unmodified lines | ||
| 2191 | 2191 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) |
| 2192 | 2192 | stat->gid = current_fsgid(); |
| 2193 | 2193 | } |
| 2194 | − return rc; | |
| 2194 | + return 0; | |
| 2195 | 2195 | } |
| 2196 | 2196 | |
| 2197 | 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 | 2222 | goto qdf_free; |
| 2223 | 2223 | } |
| 2224 | 2224 | |
| 2225 | + atomic_inc(&tcon->num_remote_opens); | |
| 2226 | + | |
| 2225 | 2227 | qd_rsp = (struct smb2_query_directory_rsp *)rsp_iov[1].iov_base; |
| 2226 | 2228 | if (qd_rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { |
| 2227 | 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 | 3419 | if (rc) |
| 3418 | 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 | 3423 | rc = -EINVAL; |
| 3422 | 3424 | goto out; |
| 3423 | 3425 | } |
| @@ -1854,9 +1854,9 @@ fetch_events: · 1853 unmodified lines | ||
| 1854 | 1854 | waiter = true; |
| 1855 | 1855 | init_waitqueue_entry(&wait, current); |
| 1856 | 1856 | |
| 1857 | − spin_lock_irq(&ep->wq.lock); | |
| 1857 | + write_lock_irq(&ep->lock); | |
| 1858 | 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 | 1862 | for (;;) { |
| @@ -1904,9 +1904,9 @@ send_events: · 41 unmodified lines | ||
| 1904 | 1904 | goto fetch_events; |
| 1905 | 1905 | |
| 1906 | 1906 | if (waiter) { |
| 1907 | − spin_lock_irq(&ep->wq.lock); | |
| 1907 | + write_lock_irq(&ep->lock); | |
| 1908 | 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 | 1912 | return res; |
| @@ -540,9 +540,14 @@ static int alloc_fd(unsigned start, unsigned flags) · 539 unmodified lines | ||
| 540 | 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 | 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 | 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 | 276 | void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) |
| 277 | 277 | { |
| 278 | 278 | struct fuse_iqueue *fiq = &fc->iq; |
| 279 | − bool async; | |
| 280 | 279 | |
| 281 | 280 | if (test_and_set_bit(FR_FINISHED, &req->flags)) |
| 282 | 281 | goto put_request; |
| 283 | 282 | |
| 284 | − async = req->args->end; | |
| 285 | 283 | /* |
| 286 | 284 | * test_and_set_bit() implies smp_mb() between bit |
| 287 | 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 | 322 | wake_up(&req->waitq); |
| 325 | 323 | } |
| 326 | 324 | |
| 327 | − if (async) | |
| 325 | + if (test_bit(FR_ASYNC, &req->flags)) | |
| 328 | 326 | req->args->end(fc, req->args, req->out.h.error); |
| 329 | 327 | put_request: |
| 330 | 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 | 469 | req->in.h.opcode = args->opcode; |
| 472 | 470 | req->in.h.nodeid = args->nodeid; |
| 473 | 471 | req->args = args; |
| 472 | + if (args->end) | |
| 473 | + __set_bit(FR_ASYNC, &req->flags); | |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 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 | 301 | * FR_SENT: request is in userspace, waiting for an answer |
| 302 | 302 | * FR_FINISHED: request is finished |
| 303 | 303 | * FR_PRIVATE: request is on private list |
| 304 | + * FR_ASYNC: request is asynchronous | |
| 304 | 305 | */ |
| 305 | 306 | enum fuse_req_flag { |
| 306 | 307 | FR_ISREPLY, |
| @@ -314,6 +315,7 @@ enum fuse_req_flag { · 7 unmodified lines | ||
| 314 | 315 | FR_SENT, |
| 315 | 316 | FR_FINISHED, |
| 316 | 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 | 138 | inode->i_sb = sb; |
| 139 | 139 | inode->i_blkbits = sb->s_blocksize_bits; |
| 140 | 140 | inode->i_flags = 0; |
| 141 | + atomic64_set(&inode->i_sequence, 0); | |
| 141 | 142 | atomic_set(&inode->i_count, 1); |
| 142 | 143 | inode->i_op = &empty_iops; |
| 143 | 144 | inode->i_fop = &no_open_fops; |
| @@ -191,7 +191,6 @@ struct fixed_file_data { · 190 unmodified lines | ||
| 191 | 191 | struct llist_head put_llist; |
| 192 | 192 | struct work_struct ref_work; |
| 193 | 193 | struct completion done; |
| 194 | − struct rcu_head rcu; | |
| 195 | 194 | }; |
| 196 | 195 | |
| 197 | 196 | struct io_ring_ctx { |
| @@ -344,6 +343,7 @@ struct io_accept { · 146 unmodified lines | ||
| 344 | 343 | struct sockaddr __user *addr; |
| 345 | 344 | int __user *addr_len; |
| 346 | 345 | int flags; |
| 346 | + unsigned long nofile; | |
| 347 | 347 | }; |
| 348 | 348 | |
| 349 | 349 | struct io_sync { |
| @@ -398,6 +398,7 @@ struct io_open { · 48 unmodified lines | ||
| 398 | 398 | struct filename *filename; |
| 399 | 399 | struct statx __user *buffer; |
| 400 | 400 | struct open_how how; |
| 401 | + unsigned long nofile; | |
| 401 | 402 | }; |
| 402 | 403 | |
| 403 | 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 | 2579 | return ret; |
| 2579 | 2580 | } |
| 2580 | 2581 | |
| 2582 | + req->open.nofile = rlimit(RLIMIT_NOFILE); | |
| 2581 | 2583 | req->flags |= REQ_F_NEED_CLEANUP; |
| 2582 | 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 | 2621 | return ret; |
| 2620 | 2622 | } |
| 2621 | 2623 | |
| 2624 | + req->open.nofile = rlimit(RLIMIT_NOFILE); | |
| 2622 | 2625 | req->flags |= REQ_F_NEED_CLEANUP; |
| 2623 | 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 | 2640 | if (ret) |
| 2638 | 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 | 2644 | if (ret < 0) |
| 2642 | 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 | 3325 | accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); |
| 3323 | 3326 | accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); |
| 3324 | 3327 | accept->flags = READ_ONCE(sqe->accept_flags); |
| 3328 | + accept->nofile = rlimit(RLIMIT_NOFILE); | |
| 3325 | 3329 | return 0; |
| 3326 | 3330 | #else |
| 3327 | 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 | 3343 | file_flags = force_nonblock ? O_NONBLOCK : 0; |
| 3340 | 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 | 3347 | if (ret == -EAGAIN && force_nonblock) |
| 3343 | 3348 | return -EAGAIN; |
| 3344 | 3349 | if (ret == -ERESTARTSYS) |
| @@ -4132,6 +4137,9 @@ static int io_req_defer_prep(struct io_kiocb *req, · 787 unmodified lines | ||
| 4132 | 4137 | { |
| 4133 | 4138 | ssize_t ret = 0; |
| 4134 | 4139 | |
| 4140 | + if (!sqe) | |
| 4141 | + return 0; | |
| 4142 | + | |
| 4135 | 4143 | if (io_op_defs[req->opcode].file_table) { |
| 4136 | 4144 | ret = io_grab_files(req); |
| 4137 | 4145 | if (unlikely(ret)) |
| @@ -4908,6 +4916,11 @@ err_req: · 770 unmodified lines | ||
| 4908 | 4916 | if (sqe_flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) { |
| 4909 | 4917 | req->flags |= REQ_F_LINK; |
| 4910 | 4918 | INIT_LIST_HEAD(&req->link_list); |
| 4919 | + | |
| 4920 | + if (io_alloc_async_ctx(req)) { | |
| 4921 | + ret = -EAGAIN; | |
| 4922 | + goto err_req; | |
| 4923 | + } | |
| 4911 | 4924 | ret = io_req_defer_prep(req, sqe); |
| 4912 | 4925 | if (ret) |
| 4913 | 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 | 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, | |
| 5337 | − rcu); | |
| 5338 | − percpu_ref_exit(&data->refs); | |
| 5339 | − kfree(data); | |
| 5340 | −} | |
| 5349 | + struct fixed_file_data *data; | |
| 5350 | + | |
| 5351 | + data = container_of(work, struct fixed_file_data, ref_work); | |
| 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 | |
| 5346 | − * existing call_rcu() for switching to atomic. One way to do that | |
| 5347 | − * is to have this rcu callback queue the final put and free, as we | |
| 5348 | − * could otherwise have a pre-existing atomic switch complete _after_ | |
| 5349 | − * the free callback we queued. | |
| 5354 | + * Ensure any percpu-ref atomic switch callback has run, it could have | |
| 5355 | + * been in progress when the files were being unregistered. Once | |
| 5356 | + * that's done, we can safely exit and free the ref and containing | |
| 5357 | + * data structure. | |
| 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 | 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 | 5379 | for (i = 0; i < nr_tables; i++) |
| 5370 | 5380 | kfree(data->table[i].files); |
| 5371 | 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 | 5384 | ctx->file_data = NULL; |
| 5374 | 5385 | ctx->nr_user_files = 0; |
| 5375 | 5386 | return 0; |
| @@ -725,7 +725,6 @@ static void __locks_delete_block(struct file_lock *waiter) · 724 unmodified lines | ||
| 725 | 725 | { |
| 726 | 726 | locks_delete_global_blocked(waiter); |
| 727 | 727 | list_del_init(&waiter->fl_blocked_member); |
| 728 | − waiter->fl_blocker = NULL; | |
| 729 | 728 | } |
| 730 | 729 | |
| 731 | 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 | 739 | waiter->fl_lmops->lm_notify(waiter); |
| 741 | 740 | else |
| 742 | 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 | 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 | 787 | spin_lock(&blocked_lock_lock); |
| 757 | 788 | if (waiter->fl_blocker) |
| 758 | 789 | status = 0; |
| 759 | 790 | __locks_wake_up_blocks(waiter); |
| 760 | 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 | 798 | spin_unlock(&blocked_lock_lock); |
| 762 | 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 | 1387 | error = posix_lock_inode(inode, fl, NULL); |
| 1351 | 1388 | if (error != FILE_LOCK_DEFERRED) |
| 1352 | 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 | 1392 | if (error) |
| 1355 | 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 | 1473 | error = posix_lock_inode(inode, &fl, NULL); |
| 1436 | 1474 | if (error != FILE_LOCK_DEFERRED) |
| 1437 | 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 | 1478 | if (!error) { |
| 1440 | 1479 | /* |
| 1441 | 1480 | * If we've been sleeping someone might have |
| @@ -1638,7 +1677,8 @@ restart: · 196 unmodified lines | ||
| 1638 | 1677 | |
| 1639 | 1678 | locks_dispose_list(&dispose); |
| 1640 | 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 | 1683 | percpu_down_read(&file_rwsem); |
| 1644 | 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 | 2162 | error = flock_lock_inode(inode, fl); |
| 2123 | 2163 | if (error != FILE_LOCK_DEFERRED) |
| 2124 | 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 | 2167 | if (error) |
| 2127 | 2168 | break; |
| 2128 | 2169 | } |
| @@ -2399,7 +2440,8 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd, · 270 unmodified lines | ||
| 2399 | 2440 | error = vfs_lock_file(filp, cmd, fl, NULL); |
| 2400 | 2441 | if (error != FILE_LOCK_DEFERRED) |
| 2401 | 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 | 2445 | if (error) |
| 2404 | 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 | 153 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) |
| 154 | 154 | goto error_0; |
| 155 | 155 | |
| 156 | + clp->cl_minorversion = cl_init->minorversion; | |
| 156 | 157 | clp->cl_nfs_mod = cl_init->nfs_mod; |
| 157 | 158 | if (!try_module_get(clp->cl_nfs_mod->owner)) |
| 158 | 159 | goto error_dealloc; |
| @@ -832,6 +832,8 @@ static int nfs_parse_source(struct fs_context *fc, · 831 unmodified lines | ||
| 832 | 832 | if (len > maxnamlen) |
| 833 | 833 | goto out_hostname; |
| 834 | 834 | |
| 835 | + kfree(ctx->nfs_server.hostname); | |
| 836 | + | |
| 835 | 837 | /* N.B. caller will free nfs_server.hostname in all cases */ |
| 836 | 838 | ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL); |
| 837 | 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 | 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 | 1252 | return 0; |
| 1244 | 1253 | |
| 1245 | 1254 | out_no_device_name: |
| @@ -31,6 +31,7 @@ static DEFINE_SPINLOCK(nfs_fscache_keys_lock); · 30 unmodified lines | ||
| 31 | 31 | struct nfs_server_key { |
| 32 | 32 | struct { |
| 33 | 33 | uint16_t nfsversion; /* NFS protocol version */ |
| 34 | + uint32_t minorversion; /* NFSv4 minor version */ | |
| 34 | 35 | uint16_t family; /* address family */ |
| 35 | 36 | __be16 port; /* IP port */ |
| 36 | 37 | } hdr; |
| @@ -55,6 +56,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp) · 18 unmodified lines | ||
| 55 | 56 | |
| 56 | 57 | memset(&key, 0, sizeof(key)); |
| 57 | 58 | key.hdr.nfsversion = clp->rpc_ops->version; |
| 59 | + key.hdr.minorversion = clp->cl_minorversion; | |
| 58 | 60 | key.hdr.family = clp->cl_addr.ss_family; |
| 59 | 61 | |
| 60 | 62 | switch (clp->cl_addr.ss_family) { |
| @@ -153,7 +153,7 @@ struct vfsmount *nfs_d_automount(struct path *path) · 152 unmodified lines | ||
| 153 | 153 | /* Open a new filesystem context, transferring parameters from the |
| 154 | 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 | 157 | if (IS_ERR(fc)) |
| 158 | 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 | 216 | INIT_LIST_HEAD(&clp->cl_ds_clients); |
| 217 | 217 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); |
| 218 | 218 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; |
| 219 | − clp->cl_minorversion = cl_init->minorversion; | |
| 220 | 219 | clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; |
| 221 | 220 | clp->cl_mig_gen = 1; |
| 222 | 221 | #if IS_ENABLED(CONFIG_NFS_V4_1) |
| @@ -93,6 +93,7 @@ config OVERLAY_FS_XINO_AUTO · 92 unmodified lines | ||
| 93 | 93 | bool "Overlayfs: auto enable inode number mapping" |
| 94 | 94 | default n |
| 95 | 95 | depends on OVERLAY_FS |
| 96 | + depends on 64BIT | |
| 96 | 97 | help |
| 97 | 98 | If this config option is enabled then overlay filesystems will use |
| 98 | 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 | 244 | if (iocb->ki_flags & IOCB_WRITE) { |
| 245 | 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 | 250 | file_end_write(iocb->ki_filp); |
| 248 | 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 | 349 | goto out; |
| 347 | 350 | |
| 348 | 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 | 355 | aio_req->fd = real; |
| 350 | 356 | real.flags = 0; |
| 351 | 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 | 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 | 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 | 1411 | if (ofs->config.xino == OVL_XINO_ON) |
| 1412 | 1412 | pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n"); |
| 1413 | 1413 | ofs->xino_mode = 0; |
| 1414 | + } else if (ofs->config.xino == OVL_XINO_OFF) { | |
| 1415 | + ofs->xino_mode = -1; | |
| 1414 | 1416 | } else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) { |
| 1415 | 1417 | /* |
| 1416 | 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 | 1625 | sb->s_stack_depth = 0; |
| 1624 | 1626 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
| 1625 | 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 | 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 | 1636 | /* alloc/destroy_inode needed for setting up traps in inode cache */ |
| 1630 | 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 | 509 | struct inode *inode = d_inode(dentry); |
| 510 | 510 | int err; |
| 511 | 511 | |
| 512 | − err = ovl_inode_lock(inode); | |
| 512 | + err = ovl_inode_lock_interruptible(inode); | |
| 513 | 513 | if (!err && ovl_already_copied_up_locked(dentry, flags)) { |
| 514 | 514 | err = 1; /* Already copied up */ |
| 515 | 515 | ovl_inode_unlock(inode); |
| @@ -764,7 +764,7 @@ int ovl_nlink_start(struct dentry *dentry) · 248 unmodified lines | ||
| 764 | 764 | return err; |
| 765 | 765 | } |
| 766 | 766 | |
| 767 | − err = ovl_inode_lock(inode); | |
| 767 | + err = ovl_inode_lock_interruptible(inode); | |
| 768 | 768 | if (err) |
| 769 | 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 | 178 | * amount of readable data in the zone. |
| 179 | 179 | */ |
| 180 | 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 | 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 | 197 | zone->wp = zone->start; |
| 197 | 198 | return 0; |
| 198 | 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 | 208 | if (warn) |
| 201 | 209 | zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n", |
| 202 | 210 | inode->i_ino); |
| 203 | 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 | 218 | inode->i_mode &= ~0222; |
| 205 | − /* fallthrough */ | |
| 219 | + return i_size_read(inode); | |
| 206 | 220 | default: |
| 207 | 221 | if (zi->i_ztype == ZONEFS_ZTYPE_CNV) |
| 208 | 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 | 245 | * as there is no inconsistency between the inode size and the amount of |
| 232 | 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 | 249 | isize = i_size_read(inode); |
| 236 | 250 | if (zone->cond != BLK_ZONE_COND_OFFLINE && |
| 237 | 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 | 288 | if (zone->cond != BLK_ZONE_COND_OFFLINE) { |
| 275 | 289 | zone->cond = BLK_ZONE_COND_OFFLINE; |
| 276 | 290 | data_size = zonefs_check_zone_condition(inode, zone, |
| 277 | − false); | |
| 291 | + false, false); | |
| 278 | 292 | } |
| 279 | 293 | } else if (zone->cond == BLK_ZONE_COND_READONLY || |
| 280 | 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 | 297 | if (zone->cond != BLK_ZONE_COND_READONLY) { |
| 284 | 298 | zone->cond = BLK_ZONE_COND_READONLY; |
| 285 | 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 | 989 | zi->i_zsector = zone->start; |
| 976 | 990 | zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE, |
| 977 | 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 | 994 | inode->i_uid = sbi->s_uid; |
| 981 | 995 | inode->i_gid = sbi->s_gid; |
| @@ -122,8 +122,8 @@ · 121 unmodified lines | ||
| 122 | 122 | #define IMX8MN_CLK_I2C1 105 |
| 123 | 123 | #define IMX8MN_CLK_I2C2 106 |
| 124 | 124 | #define IMX8MN_CLK_I2C3 107 |
| 125 | −#define IMX8MN_CLK_I2C4 118 | |
| 126 | −#define IMX8MN_CLK_UART1 119 | |
| 125 | +#define IMX8MN_CLK_I2C4 108 | |
| 126 | +#define IMX8MN_CLK_UART1 109 | |
| 127 | 127 | #define IMX8MN_CLK_UART2 110 |
| 128 | 128 | #define IMX8MN_CLK_UART3 111 |
| 129 | 129 | #define IMX8MN_CLK_UART4 112 |
| @@ -69,19 +69,23 @@ struct dmar_pci_notify_info { · 68 unmodified lines | ||
| 69 | 69 | extern struct rw_semaphore dmar_global_lock; |
| 70 | 70 | extern struct list_head dmar_drhd_units; |
| 71 | 71 | |
| 72 | −#define for_each_drhd_unit(drhd) \ | |
| 73 | − list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) | |
| 72 | +#define for_each_drhd_unit(drhd) \ | |
| 73 | + list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ | |
| 74 | + dmar_rcu_check()) | |
| 74 | 75 | |
| 75 | 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 | 79 | if (drhd->ignored) {} else |
| 78 | 80 | |
| 79 | 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 | 84 | if (i=drhd->iommu, drhd->ignored) {} else |
| 82 | 85 | |
| 83 | 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 | 89 | if (i=drhd->iommu, 0) {} else |
| 86 | 90 | |
| 87 | 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 | 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 | 31 | #else |
| 34 | 32 | |
| 35 | 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 | 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 | 65 | #endif /* IS_ENABLED(CONFIG_NET_DSA_TAG_8021Q) */ |
| 73 | 66 | |
| 74 | 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 | 85 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); |
| 86 | 86 | extern void set_close_on_exec(unsigned int fd, int flag); |
| 87 | 87 | extern bool get_close_on_exec(unsigned int fd); |
| 88 | +extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile); | |
| 88 | 89 | extern int get_unused_fd_flags(unsigned flags); |
| 89 | 90 | extern void put_unused_fd(unsigned int fd); |
| 90 | 91 | |
| @@ -698,6 +698,7 @@ struct inode { · 697 unmodified lines | ||
| 698 | 698 | struct rcu_head i_rcu; |
| 699 | 699 | }; |
| 700 | 700 | atomic64_t i_version; |
| 701 | + atomic64_t i_sequence; /* see futex */ | |
| 701 | 702 | atomic_t i_count; |
| 702 | 703 | atomic_t i_dio_count; |
| 703 | 704 | atomic_t i_writecount; |
| @@ -31,23 +31,26 @@ struct task_struct; · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | union futex_key { |
| 33 | 33 | struct { |
| 34 | + u64 i_seq; | |
| 34 | 35 | unsigned long pgoff; |
| 35 | − struct inode *inode; | |
| 36 | − int offset; | |
| 36 | + unsigned int offset; | |
| 37 | 37 | } shared; |
| 38 | 38 | struct { |
| 39 | + union { | |
| 40 | + struct mm_struct *mm; | |
| 41 | + u64 __tmp; | |
| 42 | + }; | |
| 39 | 43 | unsigned long address; |
| 40 | − struct mm_struct *mm; | |
| 41 | − int offset; | |
| 44 | + unsigned int offset; | |
| 42 | 45 | } private; |
| 43 | 46 | struct { |
| 47 | + u64 ptr; | |
| 44 | 48 | unsigned long word; |
| 45 | − void *ptr; | |
| 46 | − int offset; | |
| 49 | + unsigned int offset; | |
| 47 | 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 | 55 | #ifdef CONFIG_FUTEX |
| 53 | 56 | enum { |
| @@ -245,18 +245,6 @@ static inline bool disk_part_scan_enabled(struct gendisk *disk) · 244 unmodified lines | ||
| 245 | 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 | 248 | static inline dev_t disk_devt(struct gendisk *disk) |
| 261 | 249 | { |
| 262 | 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 | 287 | extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, |
| 300 | 288 | sector_t sector); |
| 289 | +bool disk_has_partitions(struct gendisk *disk); | |
| 301 | 290 | |
| 302 | 291 | /* |
| 303 | 292 | * Macros to operate on percpu disk statistics: |
| @@ -123,6 +123,8 @@ · 122 unmodified lines | ||
| 123 | 123 | |
| 124 | 124 | #define dmar_readq(a) readq(a) |
| 125 | 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 | 129 | #define DMAR_VER_MAJOR(v) (((v) & 0xf0) >> 4) |
| 128 | 130 | #define DMAR_VER_MINOR(v) ((v) & 0x0f) |
| @@ -333,6 +333,7 @@ struct mmc_host { · 332 unmodified lines | ||
| 333 | 333 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ |
| 334 | 334 | MMC_CAP_UHS_DDR50) |
| 335 | 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 | 337 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ |
| 337 | 338 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ |
| 338 | 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 | 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 | 131 | memcpy(extack->cookie, &__cookie, sizeof(__cookie)); |
| 119 | 132 | extack->cookie_len = sizeof(__cookie); |
| 120 | 133 | } |
| @@ -11,17 +11,17 @@ struct of_device_id; · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #if defined(CONFIG_COMMON_CLK) && defined(CONFIG_OF) |
| 13 | 13 | |
| 14 | −unsigned int of_clk_get_parent_count(struct device_node *np); | |
| 15 | −const char *of_clk_get_parent_name(struct device_node *np, int index); | |
| 14 | +unsigned int of_clk_get_parent_count(const struct device_node *np); | |
| 15 | +const char *of_clk_get_parent_name(const struct device_node *np, int index); | |
| 16 | 16 | void of_clk_init(const struct of_device_id *matches); |
| 17 | 17 | |
| 18 | 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 | 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 | 25 | int index) |
| 26 | 26 | { |
| 27 | 27 | return NULL; |
| @@ -311,7 +311,7 @@ static inline int TestClearPage##uname(struct page *page) { return 0; } · 310 unmodified lines | ||
| 311 | 311 | |
| 312 | 312 | __PAGEFLAG(Locked, locked, PF_NO_TAIL) |
| 313 | 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 | 315 | PAGEFLAG(Referenced, referenced, PF_HEAD) |
| 316 | 316 | TESTCLEARFLAG(Referenced, referenced, PF_HEAD) |
| 317 | 317 | __SETPAGEFLAG(Referenced, referenced, PF_HEAD) |
| @@ -645,8 +645,8 @@ typedef unsigned char *sk_buff_data_t; · 644 unmodified lines | ||
| 645 | 645 | * @offload_l3_fwd_mark: Packet was L3-forwarded in hardware |
| 646 | 646 | * @tc_skip_classify: do not classify packet. set by IFB device |
| 647 | 647 | * @tc_at_ingress: used within tc_classify to distinguish in/egress |
| 648 | − * @tc_redirected: packet was redirected by a tc action | |
| 649 | − * @tc_from_ingress: if tc_redirected, tc_at_ingress at time of redirect | |
| 648 | + * @redirected: packet was redirected by packet classifier | |
| 649 | + * @from_ingress: packet was redirected from the ingress path | |
| 650 | 650 | * @peeked: this packet has been seen already, so stats have been |
| 651 | 651 | * done for it, don't do them again |
| 652 | 652 | * @nf_trace: netfilter packet trace flag |
| @@ -848,8 +848,10 @@ struct sk_buff { · 195 unmodified lines | ||
| 848 | 848 | #ifdef CONFIG_NET_CLS_ACT |
| 849 | 849 | __u8 tc_skip_classify:1; |
| 850 | 850 | __u8 tc_at_ingress:1; |
| 851 | − __u8 tc_redirected:1; | |
| 852 | − __u8 tc_from_ingress:1; | |
| 851 | +#endif | |
| 852 | +#ifdef CONFIG_NET_REDIRECT | |
| 853 | + __u8 redirected:1; | |
| 854 | + __u8 from_ingress:1; | |
| 853 | 855 | #endif |
| 854 | 856 | #ifdef CONFIG_TLS_DEVICE |
| 855 | 857 | __u8 decrypted:1; |
| @@ -4571,5 +4573,31 @@ static inline __wsum lco_csum(struct sk_buff *skb) · 3715 unmodified lines | ||
| 4571 | 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 | 4602 | #endif /* __KERNEL__ */ |
| 4575 | 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 | 401 | int addr_len); |
| 402 | 402 | extern int __sys_accept4_file(struct file *file, unsigned file_flags, |
| 403 | 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 | 406 | extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, |
| 406 | 407 | int __user *upeer_addrlen, int flags); |
| 407 | 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 | 142 | extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, |
| 143 | 143 | unsigned long pgoff); |
| 144 | −void vmalloc_sync_all(void); | |
| 145 | − | |
| 144 | +void vmalloc_sync_mappings(void); | |
| 145 | +void vmalloc_sync_unmappings(void); | |
| 146 | + | |
| 146 | 147 | /* |
| 147 | 148 | * Lowlevel-APIs (not for driver use!) |
| 148 | 149 | */ |
| @@ -16,6 +16,12 @@ struct sock; · 15 unmodified lines | ||
| 16 | 16 | struct socket; |
| 17 | 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 | 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 | 47 | gfp_t, |
| 42 | 48 | rxrpc_notify_rx_t, |
| 43 | 49 | bool, |
| 44 | − bool, | |
| 50 | + enum rxrpc_interruptibility, | |
| 45 | 51 | unsigned int); |
| 46 | 52 | int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *, |
| 47 | 53 | struct msghdr *, size_t, |
| @@ -58,9 +64,7 @@ int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t, · 10 unmodified lines | ||
| 58 | 64 | rxrpc_user_attach_call_t, unsigned long, gfp_t, |
| 59 | 65 | unsigned int); |
| 60 | 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 *, | |
| 62 | − u32 *); | |
| 63 | −void rxrpc_kernel_probe_life(struct socket *, struct rxrpc_call *); | |
| 67 | +bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *); | |
| 64 | 68 | u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); |
| 65 | 69 | bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, |
| 66 | 70 | ktime_t *); |
| @@ -675,22 +675,6 @@ void __qdisc_calculate_pkt_len(struct sk_buff *skb, · 674 unmodified lines | ||
| 675 | 675 | const struct qdisc_size_table *stab); |
| 676 | 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 | 678 | static inline bool skb_at_tc_ingress(const struct sk_buff *skb) |
| 695 | 679 | { |
| 696 | 680 | #ifdef CONFIG_NET_CLS_ACT |
| @@ -233,7 +233,7 @@ enum afs_cb_break_reason { · 232 unmodified lines | ||
| 233 | 233 | EM(afs_call_trace_get, "GET ") \ |
| 234 | 234 | EM(afs_call_trace_put, "PUT ") \ |
| 235 | 235 | EM(afs_call_trace_wake, "WAKE ") \ |
| 236 | − E_(afs_call_trace_work, "WORK ") | |
| 236 | + E_(afs_call_trace_work, "QUEUE") | |
| 237 | 237 | |
| 238 | 238 | #define afs_server_traces \ |
| 239 | 239 | EM(afs_server_trace_alloc, "ALLOC ") \ |
| @@ -767,8 +767,7 @@ config ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH · 766 unmodified lines | ||
| 767 | 767 | bool |
| 768 | 768 | |
| 769 | 769 | config CC_HAS_INT128 |
| 770 | − def_bool y | |
| 771 | − depends on !$(cc-option,-D__SIZEOF_INT128__=0) | |
| 770 | + def_bool !$(cc-option,$(m64-flag) -D__SIZEOF_INT128__=0) && 64BIT | |
| 772 | 771 | |
| 773 | 772 | # |
| 774 | 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 | 490 | prev_state = cmpxchg(&st_map->kvalue.state, |
| 491 | 491 | BPF_STRUCT_OPS_STATE_INUSE, |
| 492 | 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 | 495 | st_map->st_ops->unreg(&st_map->kvalue.data); |
| 495 | 496 | if (refcount_dec_and_test(&st_map->kvalue.refcnt)) |
| 496 | 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 | 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 | 2419 | struct_size = struct_type->size; |
| 2420 | 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 | 2422 | btf_verifier_log_member(env, struct_type, member, |
| 2423 | 2423 | "Member exceeds struct_size"); |
| 2424 | 2424 | return -EINVAL; |
| @@ -227,6 +227,9 @@ cleanup: · 226 unmodified lines | ||
| 227 | 227 | for (i = 0; i < NR; i++) |
| 228 | 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 | 233 | percpu_ref_exit(&cgrp->bpf.refcnt); |
| 231 | 234 | |
| 232 | 235 | return -ENOMEM; |
| @@ -302,8 +305,8 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, · 69 unmodified lines | ||
| 302 | 305 | u32 saved_flags = (flags & (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)); |
| 303 | 306 | struct list_head *progs = &cgrp->bpf.progs[type]; |
| 304 | 307 | struct bpf_prog *old_prog = NULL; |
| 305 | − struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE], | |
| 306 | − *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {NULL}; | |
| 308 | + struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {}; | |
| 309 | + struct bpf_cgroup_storage *old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {}; | |
| 307 | 310 | struct bpf_prog_list *pl, *replace_pl = NULL; |
| 308 | 311 | enum bpf_cgroup_storage_type stype; |
| 309 | 312 | int err; |
| @@ -1514,6 +1514,11 @@ static int map_freeze(const union bpf_attr *attr) · 1513 unmodified lines | ||
| 1514 | 1514 | if (IS_ERR(map)) |
| 1515 | 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 | 1522 | mutex_lock(&map->freeze_mutex); |
| 1518 | 1523 | |
| 1519 | 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 | 386 | static struct futex_hash_bucket *hash_futex(union futex_key *key) |
| 387 | 387 | { |
| 388 | − u32 hash = jhash2((u32*)&key->both.word, | |
| 389 | − (sizeof(key->both.word)+sizeof(key->both.ptr))/4, | |
| 388 | + u32 hash = jhash2((u32 *)key, offsetof(typeof(*key), both.offset) / 4, | |
| 390 | 389 | key->both.offset); |
| 390 | + | |
| 391 | 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 | 430 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
| 431 | 431 | case FUT_OFF_INODE: |
| 432 | − ihold(key->shared.inode); /* implies smp_mb(); (B) */ | |
| 432 | + smp_mb(); /* explicit smp_mb(); (B) */ | |
| 433 | 433 | break; |
| 434 | 434 | case FUT_OFF_MMSHARED: |
| 435 | 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 | 464 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
| 465 | 465 | case FUT_OFF_INODE: |
| 466 | − iput(key->shared.inode); | |
| 467 | 466 | break; |
| 468 | 467 | case FUT_OFF_MMSHARED: |
| 469 | 468 | mmdrop(key->private.mm); |
| @@ -505,6 +504,46 @@ futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, · 35 unmodified lines | ||
| 505 | 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 | 548 | * get_futex_key() - Get parameters which are the keys for a futex |
| 510 | 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 | 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), | |
| 521 | − * offset_within_page). For private mappings, it's (uaddr, current->mm). | |
| 522 | − * We can usually work out the index without swapping in the page. | |
| 559 | + * For shared mappings (when @fshared), the key is: | |
| 560 | + * ( inode->i_sequence, page->index, offset_within_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 | 569 | * lock_page() might sleep, the caller should not hold a spinlock. |
| 525 | 570 | */ |
| @@ -659,8 +704,6 @@ again: · 133 unmodified lines | ||
| 659 | 704 | key->private.mm = mm; |
| 660 | 705 | key->private.address = address; |
| 661 | 706 | |
| 662 | − get_futex_key_refs(key); /* implies smp_mb(); (B) */ | |
| 663 | − | |
| 664 | 707 | } else { |
| 665 | 708 | struct inode *inode; |
| 666 | 709 | |
| @@ -692,40 +735,14 @@ again: · 25 unmodified lines | ||
| 692 | 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 | 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 | 740 | key->shared.pgoff = basepage_index(tail); |
| 726 | 741 | rcu_read_unlock(); |
| 727 | 742 | } |
| 728 | 743 | |
| 744 | + get_futex_key_refs(key); /* implies smp_mb(); (B) */ | |
| 745 | + | |
| 729 | 746 | out: |
| 730 | 747 | put_page(page); |
| 731 | 748 | return err; |
| @@ -519,7 +519,7 @@ NOKPROBE_SYMBOL(notify_die); · 518 unmodified lines | ||
| 519 | 519 | |
| 520 | 520 | int register_die_notifier(struct notifier_block *nb) |
| 521 | 521 | { |
| 522 | − vmalloc_sync_all(); | |
| 522 | + vmalloc_sync_mappings(); | |
| 523 | 523 | return atomic_notifier_chain_register(&die_chain, nb); |
| 524 | 524 | } |
| 525 | 525 | EXPORT_SYMBOL_GPL(register_die_notifier); |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #include <linux/syscalls.h> |
| 48 | 48 | #include <linux/kprobes.h> |
| 49 | 49 | #include <linux/user_namespace.h> |
| 50 | +#include <linux/time_namespace.h> | |
| 50 | 51 | #include <linux/binfmts.h> |
| 51 | 52 | |
| 52 | 53 | #include <linux/sched.h> |
| @@ -2546,6 +2547,7 @@ static int do_sysinfo(struct sysinfo *info) · 2493 unmodified lines | ||
| 2546 | 2547 | memset(info, 0, sizeof(struct sysinfo)); |
| 2547 | 2548 | |
| 2548 | 2549 | ktime_get_boottime_ts64(&tp); |
| 2550 | + timens_add_boottime(&tp); | |
| 2549 | 2551 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
| 2550 | 2552 | |
| 2551 | 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 | 730 | if (unlikely(!nmi_uaccess_okay())) |
| 731 | 731 | return -EPERM; |
| 732 | 732 | |
| 733 | − if (in_nmi()) { | |
| 733 | + if (irqs_disabled()) { | |
| 734 | 734 | /* Do an early check on signal validity. Otherwise, |
| 735 | 735 | * the error is lost in deferred irq_work. |
| 736 | 736 | */ |
| @@ -9028,10 +9028,15 @@ bool __init chacha20poly1305_selftest(void) · 9027 unmodified lines | ||
| 9028 | 9028 | && total_len <= 1 << 10; ++total_len) { |
| 9029 | 9029 | for (i = 0; i <= total_len; ++i) { |
| 9030 | 9030 | for (j = i; j <= total_len; ++j) { |
| 9031 | + k = 0; | |
| 9031 | 9032 | sg_init_table(sg_src, 3); |
| 9032 | − sg_set_buf(&sg_src[0], input, i); | |
| 9033 | − sg_set_buf(&sg_src[1], input + i, j - i); | |
| 9034 | − sg_set_buf(&sg_src[2], input + j, total_len - j); | |
| 9033 | + if (i) | |
| 9034 | + sg_set_buf(&sg_src[k++], input, i); | |
| 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 | 9040 | memset(computed_output, 0, total_len); |
| 9036 | 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 | 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 | 343 | if (next - addr != HPAGE_PMD_SIZE) { |
| 339 | 344 | int err; |
| 340 | 345 | |
| 341 | − if (page_mapcount(page) != 1) | |
| 342 | − goto huge_unlock; | |
| 343 | − | |
| 344 | 346 | get_page(page); |
| 345 | 347 | spin_unlock(ptl); |
| 346 | 348 | lock_page(page); |
| @@ -426,6 +428,10 @@ regular_page: · 79 unmodified lines | ||
| 426 | 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 | 435 | VM_BUG_ON_PAGE(PageTransCompound(page), page); |
| 430 | 436 | |
| 431 | 437 | if (pte_young(ptent)) { |
| @@ -2297,28 +2297,41 @@ static void high_work_func(struct work_struct *work) · 2296 unmodified lines | ||
| 2297 | 2297 | #define MEMCG_DELAY_SCALING_SHIFT 14 |
| 2298 | 2298 | |
| 2299 | 2299 | /* |
| 2300 | − * Scheduled by try_charge() to be executed from the userland return path | |
| 2301 | − * and reclaims memory over the high limit. | |
| 2300 | + * Get the number of jiffies that we should penalise a mischievous cgroup which | |
| 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 pflags; | |
| 2307 | − unsigned long penalty_jiffies, overage; | |
| 2308 | − unsigned int nr_pages = current->memcg_nr_pages_over_high; | |
| 2309 | − struct mem_cgroup *memcg; | |
| 2306 | + unsigned long penalty_jiffies; | |
| 2307 | + u64 max_overage = 0; | |
| 2310 | 2308 | |
| 2311 | − if (likely(!nr_pages)) | |
| 2312 | − return; | |
| 2309 | + do { | |
| 2310 | + unsigned long usage, high; | |
| 2311 | + u64 overage; | |
| 2313 | 2312 | |
| 2314 | − memcg = get_mem_cgroup_from_mm(current->mm); | |
| 2315 | − reclaim_high(memcg, nr_pages, GFP_KERNEL); | |
| 2316 | − current->memcg_nr_pages_over_high = 0; | |
| 2313 | + usage = page_counter_read(&memcg->memory); | |
| 2314 | + high = READ_ONCE(memcg->high); | |
| 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 | 2335 | * We use overage compared to memory.high to calculate the number of |
| 2323 | 2336 | * jiffies to sleep (penalty_jiffies). Ideally this value should be |
| 2324 | 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 | 2339 | * its crazy behaviour, so we exponentially increase the delay based on |
| 2327 | 2340 | * overage amount. |
| 2328 | 2341 | */ |
| 2329 | − | |
| 2330 | − usage = page_counter_read(&memcg->memory); | |
| 2331 | − high = READ_ONCE(memcg->high); | |
| 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); | |
| 2342 | + penalty_jiffies = max_overage * max_overage * HZ; | |
| 2343 | + penalty_jiffies >>= MEMCG_DELAY_PRECISION_SHIFT; | |
| 2344 | + penalty_jiffies >>= MEMCG_DELAY_SCALING_SHIFT; | |
| 2347 | 2345 | |
| 2348 | 2346 | /* |
| 2349 | 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 | 2358 | * application moving forwards and also permit diagnostics, albeit |
| 2361 | 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 | 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 | 4050 | struct mem_cgroup_thresholds *thresholds; |
| 4028 | 4051 | struct mem_cgroup_threshold_ary *new; |
| 4029 | 4052 | unsigned long usage; |
| 4030 | − int i, j, size; | |
| 4053 | + int i, j, size, entries; | |
| 4031 | 4054 | |
| 4032 | 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 | 4070 | __mem_cgroup_threshold(memcg, type == _MEMSWAP); |
| 4048 | 4071 | |
| 4049 | 4072 | /* Calculate new number of threshold */ |
| 4050 | − size = 0; | |
| 4073 | + size = entries = 0; | |
| 4051 | 4074 | for (i = 0; i < thresholds->primary->size; i++) { |
| 4052 | 4075 | if (thresholds->primary->entries[i].eventfd != eventfd) |
| 4053 | 4076 | size++; |
| 4077 | + else | |
| 4078 | + entries++; | |
| 4054 | 4079 | } |
| 4055 | 4080 | |
| 4056 | 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 | 4087 | /* Set thresholds array to NULL if we don't have thresholds */ |
| 4059 | 4088 | if (!size) { |
| 4060 | 4089 | kfree(new); |
| @@ -307,7 +307,8 @@ static void mn_hlist_release(struct mmu_notifier_subscriptions *subscriptions, · 306 unmodified lines | ||
| 307 | 307 | * ->release returns. |
| 308 | 308 | */ |
| 309 | 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 | 313 | * If ->release runs before mmu_notifier_unregister it must be |
| 313 | 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 | 372 | id = srcu_read_lock(&srcu); |
| 372 | 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 | 376 | if (subscription->ops->clear_flush_young) |
| 375 | 377 | young |= subscription->ops->clear_flush_young( |
| 376 | 378 | subscription, mm, start, end); |
| @@ -389,7 +391,8 @@ int __mmu_notifier_clear_young(struct mm_struct *mm, · 12 unmodified lines | ||
| 389 | 391 | |
| 390 | 392 | id = srcu_read_lock(&srcu); |
| 391 | 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 | 396 | if (subscription->ops->clear_young) |
| 394 | 397 | young |= subscription->ops->clear_young(subscription, |
| 395 | 398 | mm, start, end); |
| @@ -407,7 +410,8 @@ int __mmu_notifier_test_young(struct mm_struct *mm, · 11 unmodified lines | ||
| 407 | 410 | |
| 408 | 411 | id = srcu_read_lock(&srcu); |
| 409 | 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 | 415 | if (subscription->ops->test_young) { |
| 412 | 416 | young = subscription->ops->test_young(subscription, mm, |
| 413 | 417 | address); |
| @@ -428,7 +432,8 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, · 14 unmodified lines | ||
| 428 | 432 | |
| 429 | 433 | id = srcu_read_lock(&srcu); |
| 430 | 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 | 437 | if (subscription->ops->change_pte) |
| 433 | 438 | subscription->ops->change_pte(subscription, mm, address, |
| 434 | 439 | pte); |
| @@ -476,7 +481,8 @@ static int mn_hlist_invalidate_range_start( · 41 unmodified lines | ||
| 476 | 481 | int id; |
| 477 | 482 | |
| 478 | 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 | 486 | const struct mmu_notifier_ops *ops = subscription->ops; |
| 481 | 487 | |
| 482 | 488 | if (ops->invalidate_range_start) { |
| @@ -528,7 +534,8 @@ mn_hlist_invalidate_end(struct mmu_notifier_subscriptions *subscriptions, · 45 unmodified lines | ||
| 528 | 534 | int id; |
| 529 | 535 | |
| 530 | 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 | 540 | * Call invalidate_range here too to avoid the need for the |
| 534 | 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 | 590 | id = srcu_read_lock(&srcu); |
| 584 | 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 | 594 | if (subscription->ops->invalidate_range) |
| 587 | 595 | subscription->ops->invalidate_range(subscription, mm, |
| 588 | 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 | 723 | spin_lock(&mm->notifier_subscriptions->lock); |
| 716 | 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 | 727 | if (subscription->ops != ops) |
| 719 | 728 | continue; |
| 720 | 729 | |
| @@ -370,10 +370,14 @@ void vm_unmap_aliases(void) · 369 unmodified lines | ||
| 370 | 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 | |
| 374 | − * have one. | |
| 373 | + * Implement a stub for vmalloc_sync_[un]mapping() if the architecture | |
| 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 | 1974 | if (node == NUMA_NO_NODE) |
| 1975 | 1975 | searchnode = numa_mem_id(); |
| 1976 | − else if (!node_present_pages(node)) | |
| 1977 | − searchnode = node_to_mem_node(node); | |
| 1978 | 1976 | |
| 1979 | 1977 | object = get_partial_node(s, get_node(s, searchnode), c, flags); |
| 1980 | 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 | 2561 | struct page *page; |
| 2564 | 2562 | |
| 2565 | 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 | 2572 | goto new_slab; |
| 2573 | + } | |
| 2568 | 2574 | redo: |
| 2569 | 2575 | |
| 2570 | 2576 | if (unlikely(!node_match(page, node))) { |
| 2571 | − int searchnode = node; | |
| 2572 | − | |
| 2573 | − if (node != NUMA_NO_NODE && !node_present_pages(node)) | |
| 2574 | − searchnode = node_to_mem_node(node); | |
| 2575 | − | |
| 2576 | − if (unlikely(!node_match(page, searchnode))) { | |
| 2577 | + /* | |
| 2578 | + * same as above but node_match() being false already | |
| 2579 | + * implies node != NUMA_NO_NODE | |
| 2580 | + */ | |
| 2581 | + if (!node_state(node, N_NORMAL_MEMORY)) { | |
| 2582 | + node = NUMA_NO_NODE; | |
| 2583 | + goto redo; | |
| 2584 | + } else { | |
| 2577 | 2585 | stat(s, ALLOC_NODE_MISMATCH); |
| 2578 | 2586 | deactivate_slab(s, page, c->freelist, c); |
| 2579 | 2587 | goto new_slab; |
| @@ -2997,11 +3005,13 @@ redo: · 417 unmodified lines | ||
| 2997 | 3005 | barrier(); |
| 2998 | 3006 | |
| 2999 | 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 | 3012 | if (unlikely(!this_cpu_cmpxchg_double( |
| 3003 | 3013 | s->cpu_slab->freelist, s->cpu_slab->tid, |
| 3004 | − c->freelist, tid, | |
| 3014 | + freelist, tid, | |
| 3005 | 3015 | head, next_tid(tid)))) { |
| 3006 | 3016 | |
| 3007 | 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 | 3184 | void *object = c->freelist; |
| 3175 | 3185 | |
| 3176 | 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 | 3197 | * Invoking slow path likely have side-effect |
| 3179 | 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 | 734 | struct mem_section *ms = __pfn_to_section(pfn); |
| 735 | 735 | bool section_is_early = early_section(ms); |
| 736 | 736 | struct page *memmap = NULL; |
| 737 | + bool empty; | |
| 737 | 738 | unsigned long *subsection_map = ms->usage |
| 738 | 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 | 765 | * For 2/ and 3/ the SPARSEMEM_VMEMMAP={y,n} cases are unified |
| 765 | 766 | */ |
| 766 | 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 | 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 | 781 | ms->usage = NULL; |
| 780 | 782 | } |
| 781 | 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 | 786 | if (section_is_early && memmap) |
| 786 | 787 | free_map_bootmem(memmap); |
| 787 | 788 | else |
| 788 | 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 | 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 | 1295 | * First make sure the mappings are removed from all page-tables |
| 1296 | 1296 | * before they are freed. |
| 1297 | 1297 | */ |
| 1298 | − vmalloc_sync_all(); | |
| 1298 | + vmalloc_sync_unmappings(); | |
| 1299 | 1299 | |
| 1300 | 1300 | /* |
| 1301 | 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 | 3128 | EXPORT_SYMBOL(remap_vmalloc_range); |
| 3129 | 3129 | |
| 3130 | 3130 | /* |
| 3131 | − * Implement a stub for vmalloc_sync_all() if the architecture chose not to | |
| 3132 | − * have one. | |
| 3131 | + * Implement stubs for vmalloc_sync_[un]mappings () if the architecture chose | |
| 3132 | + * not to have one. | |
| 3133 | 3133 | * |
| 3134 | 3134 | * The purpose of this function is to make sure the vmalloc area |
| 3135 | 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 | 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 | 52 | config NET_EGRESS |
| 53 | 53 | bool |
| 54 | 54 | |
| 55 | +config NET_REDIRECT | |
| 56 | + bool | |
| 57 | + | |
| 55 | 58 | config SKB_EXTENSIONS |
| 56 | 59 | bool |
| 57 | 60 | |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/unistd.h> |
| 11 | 11 | #include "msgfmt.h" |
| 12 | 12 | |
| 13 | −int debug_fd; | |
| 13 | +FILE *debug_f; | |
| 14 | 14 | |
| 15 | 15 | static int handle_get_cmd(struct mbox_request *cmd) |
| 16 | 16 | { |
| @@ -35,9 +35,10 @@ static void loop(void) · 18 unmodified lines | ||
| 35 | 35 | struct mbox_reply reply; |
| 36 | 36 | int n; |
| 37 | 37 | |
| 38 | + fprintf(debug_f, "testing the buffer\n"); | |
| 38 | 39 | n = read(0, &req, sizeof(req)); |
| 39 | 40 | if (n != sizeof(req)) { |
| 40 | − dprintf(debug_fd, "invalid request %d\n", n); | |
| 41 | + fprintf(debug_f, "invalid request %d\n", n); | |
| 41 | 42 | return; |
| 42 | 43 | } |
| 43 | 44 | |
| @@ -47,7 +48,7 @@ static void loop(void) · 3 unmodified lines | ||
| 47 | 48 | |
| 48 | 49 | n = write(1, &reply, sizeof(reply)); |
| 49 | 50 | if (n != sizeof(reply)) { |
| 50 | − dprintf(debug_fd, "reply failed %d\n", n); | |
| 51 | + fprintf(debug_f, "reply failed %d\n", n); | |
| 51 | 52 | return; |
| 52 | 53 | } |
| 53 | 54 | } |
| @@ -55,9 +56,10 @@ static void loop(void) · 1 unmodified line | ||
| 55 | 56 | |
| 56 | 57 | int main(void) |
| 57 | 58 | { |
| 58 | − debug_fd = open("/dev/kmsg", 00000002); | |
| 59 | − dprintf(debug_fd, "Started bpfilter\n"); | |
| 59 | + debug_f = fopen("/dev/kmsg", "w"); | |
| 60 | + setvbuf(debug_f, 0, _IOLBF, 0); | |
| 61 | + fprintf(debug_f, "Started bpfilter\n"); | |
| 60 | 62 | loop(); |
| 61 | − close(debug_fd); | |
| 63 | + fclose(debug_f); | |
| 62 | 64 | return 0; |
| 63 | 65 | } |
| @@ -4516,7 +4516,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, · 4515 unmodified lines | ||
| 4516 | 4516 | /* Reinjected packets coming from act_mirred or similar should |
| 4517 | 4517 | * not get XDP generic processing. |
| 4518 | 4518 | */ |
| 4519 | − if (skb_is_tc_redirected(skb)) | |
| 4519 | + if (skb_is_redirected(skb)) | |
| 4520 | 4520 | return XDP_PASS; |
| 4521 | 4521 | |
| 4522 | 4522 | /* XDP packets must be linear and must have sufficient headroom |
| @@ -5063,7 +5063,7 @@ skip_taps: · 540 unmodified lines | ||
| 5063 | 5063 | goto out; |
| 5064 | 5064 | } |
| 5065 | 5065 | #endif |
| 5066 | − skb_reset_tc(skb); | |
| 5066 | + skb_reset_redirect(skb); | |
| 5067 | 5067 | skip_classify: |
| 5068 | 5068 | if (pfmemalloc && !skb_pfmemalloc_protocol(skb)) |
| 5069 | 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 | 5196 | * More direct receive version of netif_receive_skb(). It should |
| 5197 | 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 | 5200 | * This function may only be called from softirq context and interrupts |
| 5201 | 5201 | * should be enabled. |
| @@ -3362,7 +3362,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) · 3361 unmodified lines | ||
| 3362 | 3362 | /* skb was 'freed' by stack, so clean few |
| 3363 | 3363 | * bits and reuse it |
| 3364 | 3364 | */ |
| 3365 | − skb_reset_tc(skb); | |
| 3365 | + skb_reset_redirect(skb); | |
| 3366 | 3366 | } while (--burst > 0); |
| 3367 | 3367 | goto out; /* Skips xmit_mode M_START_XMIT */ |
| 3368 | 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 | 299 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); |
| 300 | 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 | 306 | synchronize_rcu(); |
| 303 | − raw_spin_lock_bh(&stab->lock); | |
| 304 | 307 | for (i = 0; i < stab->map.max_entries; i++) { |
| 305 | 308 | struct sock **psk = &stab->sks[i]; |
| 306 | 309 | struct sock *sk; |
| @@ -314,7 +317,6 @@ static void sock_map_free(struct bpf_map *map) · 7 unmodified lines | ||
| 314 | 317 | release_sock(sk); |
| 315 | 318 | } |
| 316 | 319 | } |
| 317 | − raw_spin_unlock_bh(&stab->lock); | |
| 318 | 320 | |
| 319 | 321 | /* wait for psock readers accessing its map link */ |
| 320 | 322 | synchronize_rcu(); |
| @@ -1008,10 +1010,13 @@ static void sock_hash_free(struct bpf_map *map) · 687 unmodified lines | ||
| 1008 | 1010 | struct hlist_node *node; |
| 1009 | 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 | 1017 | synchronize_rcu(); |
| 1012 | 1018 | for (i = 0; i < htab->buckets_num; i++) { |
| 1013 | 1019 | bucket = sock_hash_select_bucket(htab, i); |
| 1014 | − raw_spin_lock_bh(&bucket->lock); | |
| 1015 | 1020 | hlist_for_each_entry_safe(elem, node, &bucket->head, node) { |
| 1016 | 1021 | hlist_del_rcu(&elem->node); |
| 1017 | 1022 | lock_sock(elem->sk); |
| @@ -1020,7 +1025,6 @@ static void sock_hash_free(struct bpf_map *map) · 2 unmodified lines | ||
| 1020 | 1025 | rcu_read_unlock(); |
| 1021 | 1026 | release_sock(elem->sk); |
| 1022 | 1027 | } |
| 1023 | − raw_spin_unlock_bh(&bucket->lock); | |
| 1024 | 1028 | } |
| 1025 | 1029 | |
| 1026 | 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 | 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 | 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 | 140 | /* Remove Broadcom tag and update checksum */ |
| 141 | 141 | skb_pull_rcsum(skb, BRCM_TAG_LEN); |
| 142 | 142 | |
| 143 | + skb->offload_fwd_mark = 1; | |
| 144 | + | |
| 143 | 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 | 251 | struct sja1105_meta meta = {0}; |
| 252 | 252 | int source_port, switch_id; |
| 253 | − struct vlan_ethhdr *hdr; | |
| 253 | + struct ethhdr *hdr; | |
| 254 | 254 | u16 tpid, vid, tci; |
| 255 | 255 | bool is_link_local; |
| 256 | 256 | bool is_tagged; |
| 257 | 257 | bool is_meta; |
| 258 | 258 | |
| 259 | − hdr = vlan_eth_hdr(skb); | |
| 260 | − tpid = ntohs(hdr->h_vlan_proto); | |
| 259 | + hdr = eth_hdr(skb); | |
| 260 | + tpid = ntohs(hdr->h_proto); | |
| 261 | 261 | is_tagged = (tpid == ETH_P_SJA1105); |
| 262 | 262 | is_link_local = sja1105_is_link_local(skb); |
| 263 | 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 | 267 | if (is_tagged) { |
| 268 | 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 | 275 | vid = tci & VLAN_VID_MASK; |
| 271 | 276 | source_port = dsa_8021q_rx_source_port(vid); |
| 272 | 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 | 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 | 303 | return sja1105_rcv_meta_state_machine(skb, &meta, is_link_local, |
| 305 | 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 | 109 | if (ret < 0) |
| 110 | 110 | return ret; |
| 111 | 111 | dev = req_info.dev; |
| 112 | + ret = -EOPNOTSUPP; | |
| 112 | 113 | if (!dev->ethtool_ops->get_msglevel || !dev->ethtool_ops->set_msglevel) |
| 113 | − return -EOPNOTSUPP; | |
| 114 | + goto out_dev; | |
| 114 | 115 | |
| 115 | 116 | rtnl_lock(); |
| 116 | 117 | ret = ethnl_ops_begin(dev); |
| @@ -131,6 +132,7 @@ out_ops: · 14 unmodified lines | ||
| 131 | 132 | ethnl_ops_complete(dev); |
| 132 | 133 | out_rtnl: |
| 133 | 134 | rtnl_unlock(); |
| 135 | +out_dev: | |
| 134 | 136 | dev_put(dev); |
| 135 | 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 | 128 | if (ret < 0) |
| 129 | 129 | return ret; |
| 130 | 130 | dev = req_info.dev; |
| 131 | + ret = -EOPNOTSUPP; | |
| 131 | 132 | if (!dev->ethtool_ops->get_link_ksettings || |
| 132 | 133 | !dev->ethtool_ops->set_link_ksettings) |
| 133 | − return -EOPNOTSUPP; | |
| 134 | + goto out_dev; | |
| 134 | 135 | |
| 135 | 136 | rtnl_lock(); |
| 136 | 137 | ret = ethnl_ops_begin(dev); |
| @@ -164,6 +165,7 @@ out_ops: · 27 unmodified lines | ||
| 164 | 165 | ethnl_ops_complete(dev); |
| 165 | 166 | out_rtnl: |
| 166 | 167 | rtnl_unlock(); |
| 168 | +out_dev: | |
| 167 | 169 | dev_put(dev); |
| 168 | 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 | 341 | if (ret < 0) |
| 342 | 342 | return ret; |
| 343 | 343 | dev = req_info.dev; |
| 344 | + ret = -EOPNOTSUPP; | |
| 344 | 345 | if (!dev->ethtool_ops->get_link_ksettings || |
| 345 | 346 | !dev->ethtool_ops->set_link_ksettings) |
| 346 | − return -EOPNOTSUPP; | |
| 347 | + goto out_dev; | |
| 347 | 348 | |
| 348 | 349 | rtnl_lock(); |
| 349 | 350 | ret = ethnl_ops_begin(dev); |
| @@ -373,6 +374,7 @@ out_ops: · 23 unmodified lines | ||
| 373 | 374 | ethnl_ops_complete(dev); |
| 374 | 375 | out_rtnl: |
| 375 | 376 | rtnl_unlock(); |
| 377 | +out_dev: | |
| 376 | 378 | dev_put(dev); |
| 377 | 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 | 40 | struct nlattr *tb[ETHTOOL_A_HEADER_MAX + 1]; |
| 41 | 41 | const struct nlattr *devname_attr; |
| 42 | 42 | struct net_device *dev = NULL; |
| 43 | + u32 flags = 0; | |
| 43 | 44 | int ret; |
| 44 | 45 | |
| 45 | 46 | if (!header) { |
| @@ -50,8 +51,17 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info, · 4 unmodified lines | ||
| 50 | 51 | ethnl_header_policy, extack); |
| 51 | 52 | if (ret < 0) |
| 52 | 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 | 65 | if (tb[ETHTOOL_A_HEADER_DEV_INDEX]) { |
| 56 | 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 | 102 | req_info->dev = dev; |
| 93 | − if (tb[ETHTOOL_A_HEADER_FLAGS]) | |
| 94 | − req_info->flags = nla_get_u32(tb[ETHTOOL_A_HEADER_FLAGS]); | |
| 95 | − | |
| 103 | + req_info->flags = flags; | |
| 96 | 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 | 129 | if (ret < 0) |
| 130 | 130 | return ret; |
| 131 | 131 | dev = req_info.dev; |
| 132 | + ret = -EOPNOTSUPP; | |
| 132 | 133 | if (!dev->ethtool_ops->get_wol || !dev->ethtool_ops->set_wol) |
| 133 | − return -EOPNOTSUPP; | |
| 134 | + goto out_dev; | |
| 134 | 135 | |
| 135 | 136 | rtnl_lock(); |
| 136 | 137 | ret = ethnl_ops_begin(dev); |
| @@ -173,6 +174,7 @@ out_ops: · 36 unmodified lines | ||
| 173 | 174 | ethnl_ops_complete(dev); |
| 174 | 175 | out_rtnl: |
| 175 | 176 | rtnl_unlock(); |
| 177 | +out_dev: | |
| 176 | 178 | dev_put(dev); |
| 177 | 179 | return ret; |
| 178 | 180 | } |
| @@ -483,12 +483,9 @@ int hsr_get_node_data(struct hsr_priv *hsr, · 482 unmodified lines | ||
| 483 | 483 | struct hsr_port *port; |
| 484 | 484 | unsigned long tdiff; |
| 485 | 485 | |
| 486 | − rcu_read_lock(); | |
| 487 | 486 | node = find_node_by_addr_A(&hsr->node_db, addr); |
| 488 | − if (!node) { | |
| 489 | − rcu_read_unlock(); | |
| 490 | − return -ENOENT; /* No such entry */ | |
| 491 | − } | |
| 487 | + if (!node) | |
| 488 | + return -ENOENT; | |
| 492 | 489 | |
| 493 | 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 | 520 | *addr_b_ifindex = -1; |
| 524 | 521 | } |
| 525 | 522 | |
| 526 | − rcu_read_unlock(); | |
| 527 | − | |
| 528 | 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 | 250 | if (!na) |
| 251 | 251 | goto invalid; |
| 252 | 252 | |
| 253 | − hsr_dev = __dev_get_by_index(genl_info_net(info), | |
| 254 | − nla_get_u32(info->attrs[HSR_A_IFINDEX])); | |
| 253 | + rcu_read_lock(); | |
| 254 | + hsr_dev = dev_get_by_index_rcu(genl_info_net(info), | |
| 255 | + nla_get_u32(info->attrs[HSR_A_IFINDEX])); | |
| 255 | 256 | if (!hsr_dev) |
| 256 | − goto invalid; | |
| 257 | + goto rcu_unlock; | |
| 257 | 258 | if (!is_hsr_master(hsr_dev)) |
| 258 | − goto invalid; | |
| 259 | + goto rcu_unlock; | |
| 259 | 260 | |
| 260 | 261 | /* Send reply */ |
| 261 | − skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | |
| 262 | + skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); | |
| 262 | 263 | if (!skb_out) { |
| 263 | 264 | res = -ENOMEM; |
| 264 | 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 | 313 | res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq); |
| 313 | 314 | if (res < 0) |
| 314 | 315 | goto nla_put_failure; |
| 315 | − rcu_read_lock(); | |
| 316 | 316 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A); |
| 317 | 317 | if (port) |
| 318 | 318 | res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX, |
| 319 | 319 | port->dev->ifindex); |
| 320 | − rcu_read_unlock(); | |
| 321 | 320 | if (res < 0) |
| 322 | 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 | 326 | res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq); |
| 328 | 327 | if (res < 0) |
| 329 | 328 | goto nla_put_failure; |
| 330 | − rcu_read_lock(); | |
| 331 | 329 | port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B); |
| 332 | 330 | if (port) |
| 333 | 331 | res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX, |
| 334 | 332 | port->dev->ifindex); |
| 335 | − rcu_read_unlock(); | |
| 336 | 333 | if (res < 0) |
| 337 | 334 | goto nla_put_failure; |
| 338 | 335 | |
| 336 | + rcu_read_unlock(); | |
| 337 | + | |
| 339 | 338 | genlmsg_end(skb_out, msg_head); |
| 340 | 339 | genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid); |
| 341 | 340 | |
| 342 | 341 | return 0; |
| 343 | 342 | |
| 343 | +rcu_unlock: | |
| 344 | + rcu_read_unlock(); | |
| 344 | 345 | invalid: |
| 345 | 346 | netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL); |
| 346 | 347 | return 0; |
| @@ -350,6 +351,7 @@ nla_put_failure: · 3 unmodified lines | ||
| 350 | 351 | /* Fall through */ |
| 351 | 352 | |
| 352 | 353 | fail: |
| 354 | + rcu_read_unlock(); | |
| 353 | 355 | return res; |
| 354 | 356 | } |
| 355 | 357 | |
| @@ -357,16 +359,14 @@ fail: · 1 unmodified line | ||
| 357 | 359 | */ |
| 358 | 360 | static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) |
| 359 | 361 | { |
| 360 | − /* For receiving */ | |
| 361 | − struct nlattr *na; | |
| 362 | + unsigned char addr[ETH_ALEN]; | |
| 362 | 363 | struct net_device *hsr_dev; |
| 363 | − | |
| 364 | − /* For sending */ | |
| 365 | 364 | struct sk_buff *skb_out; |
| 366 | − void *msg_head; | |
| 367 | 365 | struct hsr_priv *hsr; |
| 368 | − void *pos; | |
| 369 | − unsigned char addr[ETH_ALEN]; | |
| 366 | + bool restart = false; | |
| 367 | + struct nlattr *na; | |
| 368 | + void *pos = NULL; | |
| 369 | + void *msg_head; | |
| 370 | 370 | int res; |
| 371 | 371 | |
| 372 | 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 | 376 | if (!na) |
| 377 | 377 | goto invalid; |
| 378 | 378 | |
| 379 | − hsr_dev = __dev_get_by_index(genl_info_net(info), | |
| 380 | − nla_get_u32(info->attrs[HSR_A_IFINDEX])); | |
| 379 | + rcu_read_lock(); | |
| 380 | + hsr_dev = dev_get_by_index_rcu(genl_info_net(info), | |
| 381 | + nla_get_u32(info->attrs[HSR_A_IFINDEX])); | |
| 381 | 382 | if (!hsr_dev) |
| 382 | − goto invalid; | |
| 383 | + goto rcu_unlock; | |
| 383 | 384 | if (!is_hsr_master(hsr_dev)) |
| 384 | − goto invalid; | |
| 385 | + goto rcu_unlock; | |
| 385 | 386 | |
| 387 | +restart: | |
| 386 | 388 | /* Send reply */ |
| 387 | − skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | |
| 389 | + skb_out = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); | |
| 388 | 390 | if (!skb_out) { |
| 389 | 391 | res = -ENOMEM; |
| 390 | 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 | 400 | goto nla_put_failure; |
| 399 | 401 | } |
| 400 | 402 | |
| 401 | − res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex); | |
| 402 | − if (res < 0) | |
| 403 | − goto nla_put_failure; | |
| 403 | + if (!restart) { | |
| 404 | + res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex); | |
| 405 | + if (res < 0) | |
| 406 | + goto nla_put_failure; | |
| 407 | + } | |
| 404 | 408 | |
| 405 | 409 | hsr = netdev_priv(hsr_dev); |
| 406 | 410 | |
| 407 | − rcu_read_lock(); | |
| 408 | − pos = hsr_get_next_node(hsr, NULL, addr); | |
| 411 | + if (!pos) | |
| 412 | + pos = hsr_get_next_node(hsr, NULL, addr); | |
| 409 | 413 | while (pos) { |
| 410 | 414 | res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr); |
| 411 | 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 | 423 | goto nla_put_failure; |
| 414 | 424 | } |
| 415 | 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 | 432 | return 0; |
| 423 | 433 | |
| 434 | +rcu_unlock: | |
| 435 | + rcu_read_unlock(); | |
| 424 | 436 | invalid: |
| 425 | 437 | netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL); |
| 426 | 438 | return 0; |
| 427 | 439 | |
| 428 | 440 | nla_put_failure: |
| 429 | − kfree_skb(skb_out); | |
| 441 | + nlmsg_free(skb_out); | |
| 430 | 442 | /* Fall through */ |
| 431 | 443 | |
| 432 | 444 | fail: |
| 445 | + rcu_read_unlock(); | |
| 433 | 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 | 469 | .version = 1, |
| 457 | 470 | .maxattr = HSR_A_MAX, |
| 458 | 471 | .policy = hsr_genl_policy, |
| 472 | + .netnsok = true, | |
| 459 | 473 | .module = THIS_MODULE, |
| 460 | 474 | .ops = hsr_ops, |
| 461 | 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 | 151 | if (!port) |
| 152 | 152 | return -ENOMEM; |
| 153 | 153 | |
| 154 | + port->hsr = hsr; | |
| 155 | + port->dev = dev; | |
| 156 | + port->type = type; | |
| 157 | + | |
| 154 | 158 | if (type != HSR_PT_MASTER) { |
| 155 | 159 | res = hsr_portdev_setup(hsr, dev, port, extack); |
| 156 | 160 | if (res) |
| 157 | 161 | goto fail_dev_setup; |
| 158 | 162 | } |
| 159 | 163 | |
| 160 | − port->hsr = hsr; | |
| 161 | − port->dev = dev; | |
| 162 | − port->type = type; | |
| 163 | − | |
| 164 | 164 | list_add_tail_rcu(&port->port_list, &hsr->ports); |
| 165 | 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 | 997 | return -ENOENT; |
| 998 | 998 | } |
| 999 | 999 | |
| 1000 | + rcu_read_lock(); | |
| 1000 | 1001 | err = fib_table_dump(tb, skb, cb, &filter); |
| 1002 | + rcu_read_unlock(); | |
| 1001 | 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 | 1153 | if (data[IFLA_GRE_FWMARK]) |
| 1154 | 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 | 1174 | if (data[IFLA_GRE_ERSPAN_VER]) { |
| 1157 | 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 | 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, | |
| 1280 | − struct nlattr *tb[], struct nlattr *data[], | |
| 1281 | − struct netlink_ext_ack *extack) | |
| 1297 | +static int | |
| 1298 | +ipgre_newlink_encap_setup(struct net_device *dev, struct nlattr *data[]) | |
| 1282 | 1299 | { |
| 1283 | − struct ip_tunnel_parm p; | |
| 1284 | 1300 | struct ip_tunnel_encap ipencap; |
| 1285 | − __u32 fwmark = 0; | |
| 1286 | − int err; | |
| 1287 | 1301 | |
| 1288 | 1302 | if (ipgre_netlink_encap_parms(data, &ipencap)) { |
| 1289 | 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 | 1306 | if (err < 0) |
| 1293 | 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 | 1325 | err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); |
| 1297 | 1326 | if (err < 0) |
| 1298 | 1327 | return err; |
| 1299 | 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 | 1349 | static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], |
| 1303 | 1350 | struct nlattr *data[], |
| 1304 | 1351 | struct netlink_ext_ack *extack) |
| 1305 | 1352 | { |
| 1306 | 1353 | struct ip_tunnel *t = netdev_priv(dev); |
| 1307 | − struct ip_tunnel_encap ipencap; | |
| 1308 | 1354 | __u32 fwmark = t->fwmark; |
| 1309 | 1355 | struct ip_tunnel_parm p; |
| 1310 | 1356 | int err; |
| 1311 | 1357 | |
| 1312 | − if (ipgre_netlink_encap_parms(data, &ipencap)) { | |
| 1313 | − err = ip_tunnel_encap_setup(t, &ipencap); | |
| 1314 | − | |
| 1315 | − if (err < 0) | |
| 1316 | − return err; | |
| 1317 | − } | |
| 1358 | + err = ipgre_newlink_encap_setup(dev, data); | |
| 1359 | + if (err) | |
| 1360 | + return err; | |
| 1318 | 1361 | |
| 1319 | 1362 | err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); |
| 1320 | 1363 | if (err < 0) |
| @@ -1327,8 +1370,34 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], · 6 unmodified lines | ||
| 1327 | 1370 | t->parms.i_flags = p.i_flags; |
| 1328 | 1371 | t->parms.o_flags = p.o_flags; |
| 1329 | 1372 | |
| 1330 | − if (strcmp(dev->rtnl_link_ops->kind, "erspan")) | |
| 1331 | − ipgre_link_update(dev, !tb[IFLA_MTU]); | |
| 1373 | + 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 | 1402 | return 0; |
| 1334 | 1403 | } |
| @@ -1519,8 +1588,8 @@ static struct rtnl_link_ops erspan_link_ops __read_mostly = { · 184 unmodified lines | ||
| 1519 | 1588 | .priv_size = sizeof(struct ip_tunnel), |
| 1520 | 1589 | .setup = erspan_setup, |
| 1521 | 1590 | .validate = erspan_validate, |
| 1522 | − .newlink = ipgre_newlink, | |
| 1523 | − .changelink = ipgre_changelink, | |
| 1591 | + .newlink = erspan_newlink, | |
| 1592 | + .changelink = erspan_changelink, | |
| 1524 | 1593 | .dellink = ip_tunnel_dellink, |
| 1525 | 1594 | .get_size = ipgre_get_size, |
| 1526 | 1595 | .fill_info = ipgre_fill_info, |
| @@ -2948,8 +2948,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, · 2947 unmodified lines | ||
| 2948 | 2948 | err = -EPERM; |
| 2949 | 2949 | else if (tp->repair_queue == TCP_SEND_QUEUE) |
| 2950 | 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 | 2952 | WRITE_ONCE(tp->rcv_nxt, val); |
| 2953 | + WRITE_ONCE(tp->copied_seq, val); | |
| 2954 | + } | |
| 2953 | 2955 | else |
| 2954 | 2956 | err = -EINVAL; |
| 2955 | 2957 | break; |
| @@ -1109,6 +1109,10 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, · 1108 unmodified lines | ||
| 1109 | 1109 | |
| 1110 | 1110 | if (unlikely(!skb)) |
| 1111 | 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 | 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 | 3042 | tcp_skb_tsorted_save(skb) { |
| 3039 | 3043 | nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC); |
| 3040 | − err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | |
| 3041 | − -ENOBUFS; | |
| 3044 | + if (nskb) { | |
| 3045 | + nskb->dev = NULL; | |
| 3046 | + err = tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC); | |
| 3047 | + } else { | |
| 3048 | + err = -ENOBUFS; | |
| 3049 | + } | |
| 3042 | 3050 | } tcp_skb_tsorted_restore(skb); |
| 3043 | 3051 | |
| 3044 | 3052 | if (!err) { |
| @@ -613,6 +613,9 @@ void nf_flow_table_free(struct nf_flowtable *flow_table) · 612 unmodified lines | ||
| 613 | 613 | nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); |
| 614 | 614 | nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table); |
| 615 | 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 | 619 | rhashtable_destroy(&flow_table->rhashtable); |
| 617 | 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 | 147 | if (test_bit(NF_FLOW_SNAT, &flow->flags) && |
| 148 | 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 | 150 | return -1; |
| 151 | + | |
| 152 | + iph = ip_hdr(skb); | |
| 151 | 153 | if (test_bit(NF_FLOW_DNAT, &flow->flags) && |
| 152 | 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 | 156 | return -1; |
| 155 | 157 | |
| 156 | 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 | 191 | if (!pskb_may_pull(skb, thoff + sizeof(*ports))) |
| 190 | 192 | return -1; |
| 191 | 193 | |
| 194 | + iph = ip_hdr(skb); | |
| 192 | 195 | ports = (struct flow_ports *)(skb_network_header(skb) + thoff); |
| 193 | 196 | |
| 194 | 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 | 421 | if (test_bit(NF_FLOW_SNAT, &flow->flags) && |
| 419 | 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 | 424 | return -1; |
| 425 | + | |
| 426 | + ip6h = ipv6_hdr(skb); | |
| 422 | 427 | if (test_bit(NF_FLOW_DNAT, &flow->flags) && |
| 423 | 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 | 430 | return -1; |
| 426 | 431 | |
| 427 | 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 | 455 | if (!pskb_may_pull(skb, thoff + sizeof(*ports))) |
| 451 | 456 | return -1; |
| 452 | 457 | |
| 458 | + ip6h = ipv6_hdr(skb); | |
| 453 | 459 | ports = (struct flow_ports *)(skb_network_header(skb) + thoff); |
| 454 | 460 | |
| 455 | 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 | 120 | default: |
| 121 | 121 | return -EOPNOTSUPP; |
| 122 | 122 | } |
| 123 | + mask->control.addr_type = 0xffff; | |
| 123 | 124 | match->dissector.used_keys |= BIT(key->control.addr_type); |
| 124 | 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 | 5106 | err = -EBUSY; |
| 5107 | 5107 | else if (!(nlmsg_flags & NLM_F_EXCL)) |
| 5108 | 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 | 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 | 28 | struct nft_fwd_netdev *priv = nft_expr_priv(expr); |
| 29 | 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 | 34 | nf_fwd_netdev_egress(pkt, oif); |
| 32 | 35 | regs->verdict.code = NF_STOLEN; |
| 33 | 36 | } |
| @@ -190,6 +193,13 @@ nla_put_failure: · 156 unmodified lines | ||
| 190 | 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 | 203 | static struct nft_expr_type nft_fwd_netdev_type; |
| 194 | 204 | static const struct nft_expr_ops nft_fwd_neigh_netdev_ops = { |
| 195 | 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 | 207 | .eval = nft_fwd_neigh_eval, |
| 198 | 208 | .init = nft_fwd_neigh_init, |
| 199 | 209 | .dump = nft_fwd_neigh_dump, |
| 210 | + .validate = nft_fwd_validate, | |
| 200 | 211 | }; |
| 201 | 212 | |
| 202 | 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 | 216 | .eval = nft_fwd_netdev_eval, |
| 206 | 217 | .init = nft_fwd_netdev_init, |
| 207 | 218 | .dump = nft_fwd_netdev_dump, |
| 219 | + .validate = nft_fwd_validate, | |
| 208 | 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 | 1164 | struct nft_pipapo_field *f; |
| 1165 | 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 | 1172 | dup = pipapo_get(net, set, start, genmask); |
| 1168 | − if (PTR_ERR(dup) == -ENOENT) { | |
| 1169 | − if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END)) { | |
| 1170 | − end = (const u8 *)nft_set_ext_key_end(ext)->data; | |
| 1171 | − dup = pipapo_get(net, set, end, nft_genmask_next(net)); | |
| 1172 | − } else { | |
| 1173 | − end = start; | |
| 1173 | + if (!IS_ERR(dup)) { | |
| 1174 | + /* Check if we already have the same exact entry */ | |
| 1175 | + const struct nft_data *dup_key, *dup_end; | |
| 1176 | + | |
| 1177 | + dup_key = nft_set_ext_key(&dup->ext); | |
| 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 | 1197 | if (PTR_ERR(dup) != -ENOENT) { |
| 1178 | 1198 | if (IS_ERR(dup)) |
| 1179 | 1199 | return PTR_ERR(dup); |
| 1180 | 1200 | *ext2 = &dup->ext; |
| 1181 | − return -EEXIST; | |
| 1201 | + return -ENOTEMPTY; | |
| 1182 | 1202 | } |
| 1183 | 1203 | |
| 1184 | 1204 | /* Validate */ |
| @@ -33,6 +33,11 @@ static bool nft_rbtree_interval_end(const struct nft_rbtree_elem *rbe) · 32 unmodified lines | ||
| 33 | 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 | 41 | static bool nft_rbtree_equal(const struct nft_set *set, const void *this, |
| 37 | 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 | 69 | if (interval && |
| 65 | 70 | nft_rbtree_equal(set, this, interval) && |
| 66 | 71 | nft_rbtree_interval_end(rbe) && |
| 67 | − !nft_rbtree_interval_end(interval)) | |
| 72 | + nft_rbtree_interval_start(interval)) | |
| 68 | 73 | continue; |
| 69 | 74 | interval = rbe; |
| 70 | 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 | 95 | if (set->flags & NFT_SET_INTERVAL && interval != NULL && |
| 91 | 96 | nft_set_elem_active(&interval->ext, genmask) && |
| 92 | − !nft_rbtree_interval_end(interval)) { | |
| 97 | + nft_rbtree_interval_start(interval)) { | |
| 93 | 98 | *ext = &interval->ext; |
| 94 | 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 | 213 | u8 genmask = nft_genmask_next(net); |
| 209 | 214 | struct nft_rbtree_elem *rbe; |
| 210 | 215 | struct rb_node *parent, **p; |
| 216 | + bool overlap = false; | |
| 211 | 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 | 253 | parent = NULL; |
| 214 | 254 | p = &priv->root.rb_node; |
| 215 | 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 | 258 | d = memcmp(nft_set_ext_key(&rbe->ext), |
| 219 | 259 | nft_set_ext_key(&new->ext), |
| 220 | 260 | set->klen); |
| 221 | − if (d < 0) | |
| 261 | + if (d < 0) { | |
| 222 | 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 | 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 | 285 | if (nft_rbtree_interval_end(rbe) && |
| 227 | − !nft_rbtree_interval_end(new)) { | |
| 286 | + nft_rbtree_interval_start(new)) { | |
| 228 | 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 | 292 | nft_rbtree_interval_end(new)) { |
| 231 | 293 | p = &parent->rb_right; |
| 294 | + | |
| 295 | + if (nft_set_elem_active(&rbe->ext, genmask)) | |
| 296 | + overlap = false; | |
| 232 | 297 | } else if (nft_set_elem_active(&rbe->ext, genmask)) { |
| 233 | 298 | *ext = &rbe->ext; |
| 234 | 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 | 309 | rb_link_node_rcu(&new->node, parent, p); |
| 241 | 310 | rb_insert_color(&new->node, &priv->root); |
| 242 | 311 | return 0; |
| @@ -317,10 +386,10 @@ static void *nft_rbtree_deactivate(const struct net *net, · 74 unmodified lines | ||
| 317 | 386 | parent = parent->rb_right; |
| 318 | 387 | else { |
| 319 | 388 | if (nft_rbtree_interval_end(rbe) && |
| 320 | − !nft_rbtree_interval_end(this)) { | |
| 389 | + nft_rbtree_interval_start(this)) { | |
| 321 | 390 | parent = parent->rb_left; |
| 322 | 391 | continue; |
| 323 | − } else if (!nft_rbtree_interval_end(rbe) && | |
| 392 | + } else if (nft_rbtree_interval_start(rbe) && | |
| 324 | 393 | nft_rbtree_interval_end(this)) { |
| 325 | 394 | parent = parent->rb_right; |
| 326 | 395 | continue; |
| @@ -2392,19 +2392,14 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, · 2391 unmodified lines | ||
| 2392 | 2392 | if (nlk_has_extack && extack && extack->_msg) |
| 2393 | 2393 | tlvlen += nla_total_size(strlen(extack->_msg) + 1); |
| 2394 | 2394 | |
| 2395 | − if (err) { | |
| 2396 | − if (!(nlk->flags & NETLINK_F_CAP_ACK)) | |
| 2397 | − payload += nlmsg_len(nlh); | |
| 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 { | |
| 2395 | + if (err && !(nlk->flags & NETLINK_F_CAP_ACK)) | |
| 2396 | + payload += nlmsg_len(nlh); | |
| 2397 | + else | |
| 2403 | 2398 | flags |= NLM_F_CAPPED; |
| 2404 | − | |
| 2405 | − if (nlk_has_extack && extack && extack->cookie_len) | |
| 2406 | − tlvlen += nla_total_size(extack->cookie_len); | |
| 2407 | − } | |
| 2399 | + if (err && nlk_has_extack && extack && extack->bad_attr) | |
| 2400 | + tlvlen += nla_total_size(sizeof(u32)); | |
| 2401 | + if (nlk_has_extack && extack && extack->cookie_len) | |
| 2402 | + tlvlen += nla_total_size(extack->cookie_len); | |
| 2408 | 2403 | |
| 2409 | 2404 | if (tlvlen) |
| 2410 | 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 | 2422 | WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, |
| 2428 | 2423 | extack->_msg)); |
| 2429 | 2424 | } |
| 2430 | − if (err) { | |
| 2431 | − if (extack->bad_attr && | |
| 2432 | − !WARN_ON((u8 *)extack->bad_attr < in_skb->data || | |
| 2433 | − (u8 *)extack->bad_attr >= in_skb->data + | |
| 2434 | − in_skb->len)) | |
| 2435 | − WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, | |
| 2436 | − (u8 *)extack->bad_attr - | |
| 2437 | − (u8 *)nlh)); | |
| 2438 | − } else { | |
| 2439 | − if (extack->cookie_len) | |
| 2440 | − WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, | |
| 2441 | − extack->cookie_len, | |
| 2442 | − extack->cookie)); | |
| 2443 | − } | |
| 2425 | + if (err && extack->bad_attr && | |
| 2426 | + !WARN_ON((u8 *)extack->bad_attr < in_skb->data || | |
| 2427 | + (u8 *)extack->bad_attr >= in_skb->data + | |
| 2428 | + in_skb->len)) | |
| 2429 | + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, | |
| 2430 | + (u8 *)extack->bad_attr - | |
| 2431 | + (u8 *)nlh)); | |
| 2432 | + if (extack->cookie_len) | |
| 2433 | + WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, | |
| 2434 | + extack->cookie_len, extack->cookie)); | |
| 2444 | 2435 | } |
| 2445 | 2436 | |
| 2446 | 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 | 2173 | struct timespec64 ts; |
| 2174 | 2174 | __u32 ts_status; |
| 2175 | 2175 | bool is_drop_n_account = false; |
| 2176 | + unsigned int slot_id = 0; | |
| 2176 | 2177 | bool do_vnet = false; |
| 2177 | 2178 | |
| 2178 | 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 | 2276 | if (!h.raw) |
| 2276 | 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 | 2286 | if (do_vnet && |
| 2279 | 2287 | virtio_net_hdr_from_skb(skb, h.raw + macoff - |
| 2280 | 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 | 2388 | #endif |
| 2381 | 2389 | |
| 2382 | 2390 | if (po->tp_version <= TPACKET_V2) { |
| 2391 | + spin_lock(&sk->sk_receive_queue.lock); | |
| 2383 | 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 | 2395 | sk->sk_data_ready(sk); |
| 2385 | 2396 | } else { |
| 2386 | 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 | 4289 | struct pgv *pg_vec = NULL; |
| 4279 | 4290 | struct packet_sock *po = pkt_sk(sk); |
| 4291 | + unsigned long *rx_owner_map = NULL; | |
| 4280 | 4292 | int was_running, order = 0; |
| 4281 | 4293 | struct packet_ring_buffer *rb; |
| 4282 | 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 | 4375 | break; |
| 4364 | 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 | 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 | 4409 | err = 0; |
| 4392 | 4410 | spin_lock_bh(&rb_queue->lock); |
| 4393 | 4411 | swap(rb->pg_vec, pg_vec); |
| 4412 | + if (po->tp_version <= TPACKET_V2) | |
| 4413 | + swap(rb->rx_owner_map, rx_owner_map); | |
| 4394 | 4414 | rb->frame_max = (req->tp_frame_nr - 1); |
| 4395 | 4415 | rb->head = 0; |
| 4396 | 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 | 4444 | out_free_pg_vec: |
| 4445 | + bitmap_free(rx_owner_map); | |
| 4425 | 4446 | if (pg_vec) |
| 4426 | 4447 | free_pg_vec(pg_vec, order, req->tp_block_nr); |
| 4427 | 4448 | out: |
| @@ -70,7 +70,10 @@ struct packet_ring_buffer { · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 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 | 79 | extern struct mutex fanout_mutex; |
| @@ -285,7 +285,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, · 284 unmodified lines | ||
| 285 | 285 | gfp_t gfp, |
| 286 | 286 | rxrpc_notify_rx_t notify_rx, |
| 287 | 287 | bool upgrade, |
| 288 | − bool intr, | |
| 288 | + enum rxrpc_interruptibility interruptibility, | |
| 289 | 289 | unsigned int debug_id) |
| 290 | 290 | { |
| 291 | 291 | struct rxrpc_conn_parameters cp; |
| @@ -310,7 +310,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, · 18 unmodified lines | ||
| 310 | 310 | memset(&p, 0, sizeof(p)); |
| 311 | 311 | p.user_call_ID = user_call_ID; |
| 312 | 312 | p.tx_total_len = tx_total_len; |
| 313 | − p.intr = intr; | |
| 313 | + p.interruptibility = interruptibility; | |
| 314 | 314 | |
| 315 | 315 | memset(&cp, 0, sizeof(cp)); |
| 316 | 316 | cp.local = rx->local; |
| @@ -371,44 +371,17 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call); · 54 unmodified lines | ||
| 371 | 371 | * rxrpc_kernel_check_life - Check to see whether a call is still alive |
| 372 | 372 | * @sock: The socket the call is on |
| 373 | 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 | |
| 377 | − * getting ACKs from the server. Passes back in *_life a number representing | |
| 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. | |
| 375 | + * Allow a kernel service to find out whether a call is still alive - | |
| 376 | + * ie. whether it has completed. | |
| 383 | 377 | */ |
| 384 | 378 | bool rxrpc_kernel_check_life(const struct socket *sock, |
| 385 | − const struct rxrpc_call *call, | |
| 386 | − u32 *_life) | |
| 379 | + const struct rxrpc_call *call) | |
| 387 | 380 | { |
| 388 | − *_life = call->acks_latest; | |
| 389 | 381 | return call->state != RXRPC_CALL_COMPLETE; |
| 390 | 382 | } |
| 391 | 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 | 386 | * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. |
| 414 | 387 | * @sock: The socket the call is on |
| @@ -489,7 +489,6 @@ enum rxrpc_call_flag { · 488 unmodified lines | ||
| 489 | 489 | RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */ |
| 490 | 490 | RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */ |
| 491 | 491 | RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */ |
| 492 | − RXRPC_CALL_IS_INTR, /* The call is interruptible */ | |
| 493 | 492 | RXRPC_CALL_DISCONNECTED, /* The call has been disconnected */ |
| 494 | 493 | }; |
| 495 | 494 | |
| @@ -598,6 +597,7 @@ struct rxrpc_call { · 102 unmodified lines | ||
| 598 | 597 | atomic_t usage; |
| 599 | 598 | u16 service_id; /* service ID */ |
| 600 | 599 | u8 security_ix; /* Security type */ |
| 600 | + enum rxrpc_interruptibility interruptibility; /* At what point call may be interrupted */ | |
| 601 | 601 | u32 call_id; /* call ID on connection */ |
| 602 | 602 | u32 cid; /* connection ID plus channel index */ |
| 603 | 603 | int debug_id; /* debug ID for printks */ |
| @@ -675,7 +675,6 @@ struct rxrpc_call { · 71 unmodified lines | ||
| 675 | 675 | |
| 676 | 676 | /* transmission-phase ACK management */ |
| 677 | 677 | ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ |
| 678 | − rxrpc_serial_t acks_latest; /* serial number of latest ACK received */ | |
| 679 | 678 | rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ |
| 680 | 679 | rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */ |
| 681 | 680 | rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */ |
| @@ -721,7 +720,7 @@ struct rxrpc_call_params { · 39 unmodified lines | ||
| 721 | 720 | u32 normal; /* Max time since last call packet (msec) */ |
| 722 | 721 | } timeouts; |
| 723 | 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 | 726 | struct rxrpc_send_params { |
| @@ -237,8 +237,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, · 236 unmodified lines | ||
| 237 | 237 | return call; |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | − if (p->intr) | |
| 241 | − __set_bit(RXRPC_CALL_IS_INTR, &call->flags); | |
| 240 | + call->interruptibility = p->interruptibility; | |
| 242 | 241 | call->tx_total_len = p->tx_total_len; |
| 243 | 242 | trace_rxrpc_call(call->debug_id, rxrpc_call_new_client, |
| 244 | 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 | 656 | add_wait_queue_exclusive(&call->waitq, &myself); |
| 657 | 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 | 661 | set_current_state(TASK_INTERRUPTIBLE); |
| 660 | − else | |
| 662 | + break; | |
| 663 | + case RXRPC_UNINTERRUPTIBLE: | |
| 664 | + default: | |
| 661 | 665 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 666 | + break; | |
| 667 | + } | |
| 662 | 668 | if (call->call_id) |
| 663 | 669 | break; |
| 664 | − if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) && | |
| 670 | + if ((call->interruptibility == RXRPC_INTERRUPTIBLE || | |
| 671 | + call->interruptibility == RXRPC_PREINTERRUPTIBLE) && | |
| 665 | 672 | signal_pending(current)) { |
| 666 | 673 | ret = -ERESTARTSYS; |
| 667 | 674 | break; |
| @@ -882,7 +882,6 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) · 881 unmodified lines | ||
| 882 | 882 | before(prev_pkt, call->ackr_prev_seq)) |
| 883 | 883 | goto out; |
| 884 | 884 | call->acks_latest_ts = skb->tstamp; |
| 885 | − call->acks_latest = sp->hdr.serial; | |
| 886 | 885 | |
| 887 | 886 | call->ackr_first_seq = first_soft_ack; |
| 888 | 887 | call->ackr_prev_seq = prev_pkt; |
| @@ -17,6 +17,21 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <net/af_rxrpc.h> |
| 18 | 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 | 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 | 42 | for (;;) { |
| 28 | 43 | set_current_state(TASK_INTERRUPTIBLE); |
| 29 | − if (call->tx_top - call->tx_hard_ack < | |
| 30 | − min_t(unsigned int, call->tx_winsize, | |
| 31 | − call->cong_cwnd + call->cong_extra)) | |
| 44 | + if (rxrpc_check_tx_space(call, NULL)) | |
| 32 | 45 | return 0; |
| 33 | 46 | |
| 34 | 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 | 62 | * Wait for space to appear in the Tx queue uninterruptibly, but with |
| 50 | 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 | 66 | struct rxrpc_call *call) |
| 54 | 67 | { |
| 55 | 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 | 72 | rtt = READ_ONCE(call->peer->rtt); |
| 60 | 73 | rtt2 = nsecs_to_jiffies64(rtt) * 2; |
| 61 | − if (rtt2 < 1) | |
| 62 | − rtt2 = 1; | |
| 74 | + if (rtt2 < 2) | |
| 75 | + rtt2 = 2; | |
| 63 | 76 | |
| 64 | 77 | timeout = rtt2; |
| 65 | 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 | 81 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 69 | 82 | |
| 70 | 83 | tx_win = READ_ONCE(call->tx_hard_ack); |
| 71 | − if (call->tx_top - tx_win < | |
| 72 | − min_t(unsigned int, call->tx_winsize, | |
| 73 | − call->cong_cwnd + call->cong_extra)) | |
| 84 | + if (rxrpc_check_tx_space(call, &tx_win)) | |
| 74 | 85 | return 0; |
| 75 | 86 | |
| 76 | 87 | if (call->state >= RXRPC_CALL_COMPLETE) |
| 77 | 88 | return call->error; |
| 78 | 89 | |
| 79 | − if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) && | |
| 80 | − timeout == 0 && | |
| 90 | + if (timeout == 0 && | |
| 81 | 91 | tx_win == tx_start && signal_pending(current)) |
| 82 | 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 | 125 | * wait for space to appear in the transmit/ACK window |
| 96 | 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 | 139 | add_wait_queue(&call->waitq, &myself); |
| 110 | 140 | |
| 111 | − if (waitall) | |
| 112 | − ret = rxrpc_wait_for_tx_window_nonintr(rx, call); | |
| 113 | − else | |
| 114 | − ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo); | |
| 141 | + switch (call->interruptibility) { | |
| 142 | + case RXRPC_INTERRUPTIBLE: | |
| 143 | + if (waitall) | |
| 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 | 155 | remove_wait_queue(&call->waitq, &myself); |
| 117 | 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 | 342 | _debug("alloc"); |
| 304 | 343 | |
| 305 | − if (call->tx_top - call->tx_hard_ack >= | |
| 306 | − min_t(unsigned int, call->tx_winsize, | |
| 307 | − call->cong_cwnd + call->cong_extra)) { | |
| 344 | + if (!rxrpc_check_tx_space(call, NULL)) { | |
| 308 | 345 | ret = -EAGAIN; |
| 309 | 346 | if (msg->msg_flags & MSG_DONTWAIT) |
| 310 | 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 | 656 | .call.tx_total_len = -1, |
| 620 | 657 | .call.user_call_ID = 0, |
| 621 | 658 | .call.nr_timeouts = 0, |
| 622 | − .call.intr = true, | |
| 659 | + .call.interruptibility = RXRPC_INTERRUPTIBLE, | |
| 623 | 660 | .abort_code = 0, |
| 624 | 661 | .command = RXRPC_CMD_SEND_DATA, |
| 625 | 662 | .exclusive = false, |
| @@ -1273,7 +1273,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, · 1272 unmodified lines | ||
| 1273 | 1273 | if (goto_ch) |
| 1274 | 1274 | tcf_chain_put_by_act(goto_ch); |
| 1275 | 1275 | if (params) |
| 1276 | − kfree_rcu(params, rcu); | |
| 1276 | + call_rcu(¶ms->rcu, tcf_ct_params_free); | |
| 1277 | 1277 | if (res == ACT_P_CREATED) |
| 1278 | 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 | 285 | /* mirror is always swallowed */ |
| 286 | 286 | if (is_redirect) { |
| 287 | − skb2->tc_redirected = 1; | |
| 288 | − skb2->tc_from_ingress = skb2->tc_at_ingress; | |
| 289 | − if (skb2->tc_from_ingress) | |
| 290 | − skb2->tstamp = 0; | |
| 287 | + skb_set_redirected(skb2, skb2->tc_at_ingress); | |
| 288 | + | |
| 291 | 289 | /* let's the caller reinsert the packet, if possible */ |
| 292 | 290 | if (use_reinsert) { |
| 293 | 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 | 534 | fp = &b->ht[h]; |
| 535 | 535 | for (pfp = rtnl_dereference(*fp); pfp; |
| 536 | 536 | fp = &pfp->next, pfp = rtnl_dereference(*fp)) { |
| 537 | − if (pfp == f) { | |
| 538 | − *fp = f->next; | |
| 537 | + if (pfp == fold) { | |
| 538 | + rcu_assign_pointer(*fp, fold->next); | |
| 539 | 539 | break; |
| 540 | 540 | } |
| 541 | 541 | } |
| @@ -261,8 +261,10 @@ static void tcindex_partial_destroy_work(struct work_struct *work) · 260 unmodified lines | ||
| 261 | 261 | struct tcindex_data, |
| 262 | 262 | rwork); |
| 263 | 263 | |
| 264 | + rtnl_lock(); | |
| 264 | 265 | kfree(p->perfect); |
| 265 | 266 | kfree(p); |
| 267 | + rtnl_unlock(); | |
| 266 | 268 | } |
| 267 | 269 | |
| 268 | 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 | 360 | if (tcindex_alloc_perfect_hash(net, cp) < 0) |
| 359 | 361 | goto errout; |
| 362 | + cp->alloc_hash = cp->hash; | |
| 360 | 363 | for (i = 0; i < min(cp->hash, p->hash); i++) |
| 361 | 364 | cp->perfect[i].res = p->perfect[i].res; |
| 362 | 365 | balloc = 1; |
| @@ -181,6 +181,11 @@ static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch) · 180 unmodified lines | ||
| 181 | 181 | s64 credits; |
| 182 | 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 | 189 | if (q->credits < 0) { |
| 185 | 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 | 217 | credits += q->credits; |
| 213 | 218 | |
| 214 | 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 | 227 | return skb; |
| 218 | 228 | } |
| @@ -1707,7 +1707,8 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) · 1706 unmodified lines | ||
| 1707 | 1707 | |
| 1708 | 1708 | int __sys_accept4_file(struct file *file, unsigned file_flags, |
| 1709 | 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 | 1713 | struct socket *sock, *newsock; |
| 1713 | 1714 | struct file *newfile; |
| @@ -1738,7 +1739,7 @@ int __sys_accept4_file(struct file *file, unsigned file_flags, · 24 unmodified lines | ||
| 1738 | 1739 | */ |
| 1739 | 1740 | __module_get(newsock->ops->owner); |
| 1740 | 1741 | |
| 1741 | − newfd = get_unused_fd_flags(flags); | |
| 1742 | + newfd = __get_unused_fd_flags(flags, nofile); | |
| 1742 | 1743 | if (unlikely(newfd < 0)) { |
| 1743 | 1744 | err = newfd; |
| 1744 | 1745 | sock_release(newsock); |
| @@ -1807,7 +1808,8 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, · 62 unmodified lines | ||
| 1807 | 1808 | f = fdget(fd); |
| 1808 | 1809 | if (f.file) { |
| 1809 | 1810 | ret = __sys_accept4_file(f.file, 0, upeer_sockaddr, |
| 1810 | − upeer_addrlen, flags); | |
| 1811 | + upeer_addrlen, flags, | |
| 1812 | + rlimit(RLIMIT_NOFILE)); | |
| 1811 | 1813 | if (f.flags) |
| 1812 | 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 | 45 | # gcc version including patch level |
| 46 | 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 | 48 | KBUILD_CFLAGS += -Wno-format |
| 49 | 49 | KBUILD_CFLAGS += -Wno-sign-compare |
| 50 | 50 | KBUILD_CFLAGS += -Wno-format-zero-length |
| 51 | +KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) | |
| 51 | 52 | endif |
| 52 | 53 | |
| 53 | 54 | endif |
| @@ -94,7 +94,7 @@ if (defined $opt{'o'}) { · 93 unmodified lines | ||
| 94 | 94 | # |
| 95 | 95 | while ( <$module_symvers> ) { |
| 96 | 96 | chomp; |
| 97 | − my (undef, $symbol, $namespace, $module, $gpl) = split('\t'); | |
| 97 | + my (undef, $symbol, $module, $gpl, $namespace) = split('\t'); | |
| 98 | 98 | $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; |
| 99 | 99 | } |
| 100 | 100 | close($module_symvers); |
| @@ -195,13 +195,13 @@ static struct sym_entry *read_symbol(FILE *in) · 194 unmodified lines | ||
| 195 | 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 | 198 | if (strcmp(name, "_text") == 0) |
| 203 | 199 | _text = addr; |
| 204 | 200 | |
| 201 | + /* Ignore most absolute/undefined (?) symbols. */ | |
| 202 | + if (is_ignored_symbol(name, type)) | |
| 203 | + return NULL; | |
| 204 | + | |
| 205 | 205 | check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges)); |
| 206 | 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 | 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 | 313 | unsigned long offset; |
| 313 | 314 | |
| 314 | 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 | 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 | 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 | 2441 | return; |
| 2441 | 2442 | |
| 2442 | 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 | 2445 | unsigned int crc; |
| 2445 | 2446 | struct module *mod; |
| 2446 | 2447 | struct symbol *s; |
| @@ -2448,16 +2449,16 @@ static void read_dump(const char *fname, unsigned int kernel) · 1 unmodified line | ||
| 2448 | 2449 | if (!(symname = strchr(line, '\t'))) |
| 2449 | 2450 | goto fail; |
| 2450 | 2451 | *symname++ = '\0'; |
| 2451 | − if (!(namespace = strchr(symname, '\t'))) | |
| 2452 | − goto fail; | |
| 2453 | − *namespace++ = '\0'; | |
| 2454 | − if (!(modname = strchr(namespace, '\t'))) | |
| 2452 | + if (!(modname = strchr(symname, '\t'))) | |
| 2455 | 2453 | goto fail; |
| 2456 | 2454 | *modname++ = '\0'; |
| 2457 | − if ((export = strchr(modname, '\t')) != NULL) | |
| 2458 | − *export++ = '\0'; | |
| 2459 | − if (export && ((end = strchr(export, '\t')) != NULL)) | |
| 2460 | − *end = '\0'; | |
| 2455 | + if (!(export = strchr(modname, '\t'))) | |
| 2456 | + goto fail; | |
| 2457 | + *export++ = '\0'; | |
| 2458 | + if (!(namespace = strchr(export, '\t'))) | |
| 2459 | + goto fail; | |
| 2460 | + *namespace++ = '\0'; | |
| 2461 | + | |
| 2461 | 2462 | crc = strtoul(line, &d, 16); |
| 2462 | 2463 | if (*symname == '\0' || *modname == '\0' || *d != '\0') |
| 2463 | 2464 | goto fail; |
| @@ -2508,9 +2509,9 @@ static void write_dump(const char *fname) · 44 unmodified lines | ||
| 2508 | 2509 | namespace = symbol->namespace; |
| 2509 | 2510 | buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", |
| 2510 | 2511 | symbol->crc, symbol->name, |
| 2511 | − namespace ? namespace : "", | |
| 2512 | 2512 | symbol->module->name, |
| 2513 | − export_str(symbol->export)); | |
| 2513 | + export_str(symbol->export), | |
| 2514 | + namespace ? namespace : ""); | |
| 2514 | 2515 | } |
| 2515 | 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 | 111 | while (plugin->next) { |
| 112 | 112 | if (plugin->dst_frames) |
| 113 | 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 | 115 | return -ENXIO; |
| 116 | 116 | plugin = plugin->next; |
| 117 | 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 | 123 | while (plugin->prev) { |
| 124 | 124 | if (plugin->src_frames) |
| 125 | 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 | 127 | return -ENXIO; |
| 128 | 128 | plugin = plugin->prev; |
| 129 | 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 | 209 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 210 | 210 | plugin = snd_pcm_plug_last(plug); |
| 211 | 211 | while (plugin && drv_frames > 0) { |
| 212 | + if (drv_frames > plugin->buf_frames) | |
| 213 | + drv_frames = plugin->buf_frames; | |
| 212 | 214 | plugin_prev = plugin->prev; |
| 213 | 215 | if (plugin->src_frames) |
| 214 | 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 | 222 | plugin_next = plugin->next; |
| 221 | 223 | if (plugin->dst_frames) |
| 222 | 224 | drv_frames = plugin->dst_frames(plugin, drv_frames); |
| 225 | + if (drv_frames > plugin->buf_frames) | |
| 226 | + drv_frames = plugin->buf_frames; | |
| 223 | 227 | plugin = plugin_next; |
| 224 | 228 | } |
| 225 | 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 | 252 | if (frames < 0) |
| 249 | 253 | return frames; |
| 250 | 254 | } |
| 255 | + if (frames > plugin->buf_frames) | |
| 256 | + frames = plugin->buf_frames; | |
| 251 | 257 | plugin = plugin_next; |
| 252 | 258 | } |
| 253 | 259 | } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { |
| 254 | 260 | plugin = snd_pcm_plug_last(plug); |
| 255 | 261 | while (plugin) { |
| 262 | + if (frames > plugin->buf_frames) | |
| 263 | + frames = plugin->buf_frames; | |
| 256 | 264 | plugin_prev = plugin->prev; |
| 257 | 265 | if (plugin->src_frames) { |
| 258 | 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 | 602 | len = snd_seq_oss_timer_start(dp->timer); |
| 603 | 603 | if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { |
| 604 | 604 | snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); |
| 605 | + snd_midi_event_reset_decode(mdev->coder); | |
| 605 | 606 | } else { |
| 606 | 607 | len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); |
| 607 | 608 | if (len > 0) |
| @@ -81,6 +81,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, · 80 unmodified lines | ||
| 81 | 81 | if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) |
| 82 | 82 | continue; |
| 83 | 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 | 85 | } else { |
| 85 | 86 | len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); |
| 86 | 87 | if (len > 0) |
| @@ -8051,6 +8051,8 @@ static int patch_alc269(struct hda_codec *codec) · 8050 unmodified lines | ||
| 8051 | 8051 | spec->gen.mixer_nid = 0; |
| 8052 | 8052 | break; |
| 8053 | 8053 | case 0x10ec0225: |
| 8054 | + codec->power_save_node = 1; | |
| 8055 | + /* fall through */ | |
| 8054 | 8056 | case 0x10ec0295: |
| 8055 | 8057 | case 0x10ec0299: |
| 8056 | 8058 | spec->codec_variant = ALC269_TYPE_ALC225; |
| @@ -8610,6 +8612,8 @@ enum { · 553 unmodified lines | ||
| 8610 | 8612 | ALC669_FIXUP_ACER_ASPIRE_ETHOS, |
| 8611 | 8613 | ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET, |
| 8612 | 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 | 8619 | static const struct hda_fixup alc662_fixups[] = { |
| @@ -8955,6 +8959,25 @@ static const struct hda_fixup alc662_fixups[] = { · 339 unmodified lines | ||
| 8955 | 8959 | .type = HDA_FIXUP_FUNC, |
| 8956 | 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 | 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 | 8989 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
| 8967 | 8990 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), |
| 8968 | 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 | 8994 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
| 8970 | 8995 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
| 8971 | 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 | 305 | line6_midibuf_read(mb, line6->buffer_message, |
| 306 | 306 | LINE6_MIDI_MESSAGE_MAXLEN); |
| 307 | 307 | |
| 308 | − if (done == 0) | |
| 308 | + if (done <= 0) | |
| 309 | 309 | break; |
| 310 | 310 | |
| 311 | 311 | line6->message_length = done; |
| @@ -159,7 +159,7 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data, · 158 unmodified lines | ||
| 159 | 159 | int midi_length_prev = |
| 160 | 160 | midibuf_message_length(this->command_prev); |
| 161 | 161 | |
| 162 | − if (midi_length_prev > 0) { | |
| 162 | + if (midi_length_prev > 1) { | |
| 163 | 163 | midi_length = midi_length_prev - 1; |
| 164 | 164 | repeat = 1; |
| 165 | 165 | } else |
| @@ -1,18 +1,18 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 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 | 4 | #elif defined(__powerpc__) |
| 5 | −#include "../../arch/powerpc/include/uapi/asm/errno.h" | |
| 5 | +#include "../../../arch/powerpc/include/uapi/asm/errno.h" | |
| 6 | 6 | #elif defined(__sparc__) |
| 7 | −#include "../../arch/sparc/include/uapi/asm/errno.h" | |
| 7 | +#include "../../../arch/sparc/include/uapi/asm/errno.h" | |
| 8 | 8 | #elif defined(__alpha__) |
| 9 | −#include "../../arch/alpha/include/uapi/asm/errno.h" | |
| 9 | +#include "../../../arch/alpha/include/uapi/asm/errno.h" | |
| 10 | 10 | #elif defined(__mips__) |
| 11 | −#include "../../arch/mips/include/uapi/asm/errno.h" | |
| 11 | +#include "../../../arch/mips/include/uapi/asm/errno.h" | |
| 12 | 12 | #elif defined(__ia64__) |
| 13 | −#include "../../arch/ia64/include/uapi/asm/errno.h" | |
| 13 | +#include "../../../arch/ia64/include/uapi/asm/errno.h" | |
| 14 | 14 | #elif defined(__xtensa__) |
| 15 | −#include "../../arch/xtensa/include/uapi/asm/errno.h" | |
| 15 | +#include "../../../arch/xtensa/include/uapi/asm/errno.h" | |
| 16 | 16 | #else |
| 17 | 17 | #include <asm-generic/errno.h> |
| 18 | 18 | #endif |
| @@ -74,6 +74,8 @@ enum { · 73 unmodified lines | ||
| 74 | 74 | #define IPPROTO_UDPLITE IPPROTO_UDPLITE |
| 75 | 75 | IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */ |
| 76 | 76 | #define IPPROTO_MPLS IPPROTO_MPLS |
| 77 | + IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation */ | |
| 78 | +#define IPPROTO_ETHERNET IPPROTO_ETHERNET | |
| 77 | 79 | IPPROTO_RAW = 255, /* Raw IP packets */ |
| 78 | 80 | #define IPPROTO_RAW IPPROTO_RAW |
| 79 | 81 | IPPROTO_MPTCP = 262, /* Multipath TCP connection */ |
| @@ -35,7 +35,7 @@ endif · 34 unmodified lines | ||
| 35 | 35 | # Only pass canonical directory names as the output directory: |
| 36 | 36 | # |
| 37 | 37 | ifneq ($(O),) |
| 38 | − FULL_O := $(shell readlink -f $(O) || echo $(O)) | |
| 38 | + FULL_O := $(shell cd $(PWD); readlink -f $(O) || echo $(O)) | |
| 39 | 39 | endif |
| 40 | 40 | |
| 41 | 41 | # |
| @@ -11,17 +11,17 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/zalloc.h> |
| 12 | 12 | #include <time.h> |
| 13 | 13 | |
| 14 | −#include "../../util/cpumap.h" | |
| 15 | −#include "../../util/event.h" | |
| 16 | −#include "../../util/evsel.h" | |
| 17 | −#include "../../util/evlist.h" | |
| 18 | −#include "../../util/session.h" | |
| 14 | +#include "../../../util/cpumap.h" | |
| 15 | +#include "../../../util/event.h" | |
| 16 | +#include "../../../util/evsel.h" | |
| 17 | +#include "../../../util/evlist.h" | |
| 18 | +#include "../../../util/session.h" | |
| 19 | 19 | #include <internal/lib.h> // page_size |
| 20 | −#include "../../util/pmu.h" | |
| 21 | −#include "../../util/debug.h" | |
| 22 | −#include "../../util/auxtrace.h" | |
| 23 | −#include "../../util/record.h" | |
| 24 | −#include "../../util/arm-spe.h" | |
| 20 | +#include "../../../util/pmu.h" | |
| 21 | +#include "../../../util/debug.h" | |
| 22 | +#include "../../../util/auxtrace.h" | |
| 23 | +#include "../../../util/record.h" | |
| 24 | +#include "../../../util/arm-spe.h" | |
| 25 | 25 | |
| 26 | 26 | #define KiB(x) ((x) * 1024) |
| 27 | 27 | #define MiB(x) ((x) * 1024 * 1024) |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | −#include "../../util/perf_regs.h" | |
| 2 | +#include "../../../util/perf_regs.h" | |
| 3 | 3 | |
| 4 | 4 | const struct sample_reg sample_reg_masks[] = { |
| 5 | 5 | SMPL_REG_END |
| @@ -4,8 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <regex.h> |
| 5 | 5 | #include <linux/zalloc.h> |
| 6 | 6 | |
| 7 | −#include "../../util/perf_regs.h" | |
| 8 | −#include "../../util/debug.h" | |
| 7 | +#include "../../../util/perf_regs.h" | |
| 8 | +#include "../../../util/debug.h" | |
| 9 | 9 | |
| 10 | 10 | #include <linux/kernel.h> |
| 11 | 11 | |
| @@ -7,13 +7,13 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <errno.h> |
| 8 | 8 | #include <stdbool.h> |
| 9 | 9 | |
| 10 | −#include "../../util/header.h" | |
| 11 | −#include "../../util/debug.h" | |
| 12 | −#include "../../util/pmu.h" | |
| 13 | −#include "../../util/auxtrace.h" | |
| 14 | −#include "../../util/intel-pt.h" | |
| 15 | −#include "../../util/intel-bts.h" | |
| 16 | −#include "../../util/evlist.h" | |
| 10 | +#include "../../../util/header.h" | |
| 11 | +#include "../../../util/debug.h" | |
| 12 | +#include "../../../util/pmu.h" | |
| 13 | +#include "../../../util/auxtrace.h" | |
| 14 | +#include "../../../util/intel-pt.h" | |
| 15 | +#include "../../../util/intel-bts.h" | |
| 16 | +#include "../../../util/evlist.h" | |
| 17 | 17 | |
| 18 | 18 | static |
| 19 | 19 | struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist, |
| @@ -3,12 +3,12 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/string.h> |
| 4 | 4 | #include <linux/zalloc.h> |
| 5 | 5 | |
| 6 | −#include "../../util/event.h" | |
| 7 | −#include "../../util/synthetic-events.h" | |
| 8 | −#include "../../util/machine.h" | |
| 9 | −#include "../../util/tool.h" | |
| 10 | −#include "../../util/map.h" | |
| 11 | −#include "../../util/debug.h" | |
| 6 | +#include "../../../util/event.h" | |
| 7 | +#include "../../../util/synthetic-events.h" | |
| 8 | +#include "../../../util/machine.h" | |
| 9 | +#include "../../../util/tool.h" | |
| 10 | +#include "../../../util/map.h" | |
| 11 | +#include "../../../util/debug.h" | |
| 12 | 12 | |
| 13 | 13 | #if defined(__x86_64__) |
| 14 | 14 | |
| @@ -7,8 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <string.h> |
| 8 | 8 | #include <regex.h> |
| 9 | 9 | |
| 10 | −#include "../../util/debug.h" | |
| 11 | −#include "../../util/header.h" | |
| 10 | +#include "../../../util/debug.h" | |
| 11 | +#include "../../../util/header.h" | |
| 12 | 12 | |
| 13 | 13 | static inline void |
| 14 | 14 | cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c, |
| @@ -11,18 +11,18 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/log2.h> |
| 12 | 12 | #include <linux/zalloc.h> |
| 13 | 13 | |
| 14 | −#include "../../util/cpumap.h" | |
| 15 | −#include "../../util/event.h" | |
| 16 | −#include "../../util/evsel.h" | |
| 17 | −#include "../../util/evlist.h" | |
| 18 | −#include "../../util/mmap.h" | |
| 19 | −#include "../../util/session.h" | |
| 20 | −#include "../../util/pmu.h" | |
| 21 | −#include "../../util/debug.h" | |
| 22 | −#include "../../util/record.h" | |
| 23 | −#include "../../util/tsc.h" | |
| 24 | −#include "../../util/auxtrace.h" | |
| 25 | −#include "../../util/intel-bts.h" | |
| 14 | +#include "../../../util/cpumap.h" | |
| 15 | +#include "../../../util/event.h" | |
| 16 | +#include "../../../util/evsel.h" | |
| 17 | +#include "../../../util/evlist.h" | |
| 18 | +#include "../../../util/mmap.h" | |
| 19 | +#include "../../../util/session.h" | |
| 20 | +#include "../../../util/pmu.h" | |
| 21 | +#include "../../../util/debug.h" | |
| 22 | +#include "../../../util/record.h" | |
| 23 | +#include "../../../util/tsc.h" | |
| 24 | +#include "../../../util/auxtrace.h" | |
| 25 | +#include "../../../util/intel-bts.h" | |
| 26 | 26 | #include <internal/lib.h> // page_size |
| 27 | 27 | |
| 28 | 28 | #define KiB(x) ((x) * 1024) |
| @@ -13,23 +13,23 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/zalloc.h> |
| 14 | 14 | #include <cpuid.h> |
| 15 | 15 | |
| 16 | −#include "../../util/session.h" | |
| 17 | −#include "../../util/event.h" | |
| 18 | −#include "../../util/evlist.h" | |
| 19 | −#include "../../util/evsel.h" | |
| 20 | −#include "../../util/evsel_config.h" | |
| 21 | −#include "../../util/cpumap.h" | |
| 22 | −#include "../../util/mmap.h" | |
| 16 | +#include "../../../util/session.h" | |
| 17 | +#include "../../../util/event.h" | |
| 18 | +#include "../../../util/evlist.h" | |
| 19 | +#include "../../../util/evsel.h" | |
| 20 | +#include "../../../util/evsel_config.h" | |
| 21 | +#include "../../../util/cpumap.h" | |
| 22 | +#include "../../../util/mmap.h" | |
| 23 | 23 | #include <subcmd/parse-options.h> |
| 24 | −#include "../../util/parse-events.h" | |
| 25 | −#include "../../util/pmu.h" | |
| 26 | −#include "../../util/debug.h" | |
| 27 | −#include "../../util/auxtrace.h" | |
| 28 | −#include "../../util/record.h" | |
| 29 | −#include "../../util/target.h" | |
| 30 | −#include "../../util/tsc.h" | |
| 24 | +#include "../../../util/parse-events.h" | |
| 25 | +#include "../../../util/pmu.h" | |
| 26 | +#include "../../../util/debug.h" | |
| 27 | +#include "../../../util/auxtrace.h" | |
| 28 | +#include "../../../util/record.h" | |
| 29 | +#include "../../../util/target.h" | |
| 30 | +#include "../../../util/tsc.h" | |
| 31 | 31 | #include <internal/lib.h> // page_size |
| 32 | −#include "../../util/intel-pt.h" | |
| 32 | +#include "../../../util/intel-pt.h" | |
| 33 | 33 | |
| 34 | 34 | #define KiB(x) ((x) * 1024) |
| 35 | 35 | #define MiB(x) ((x) * 1024 * 1024) |
| @@ -5,9 +5,9 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <stdlib.h> |
| 6 | 6 | |
| 7 | 7 | #include <internal/lib.h> // page_size |
| 8 | −#include "../../util/machine.h" | |
| 9 | −#include "../../util/map.h" | |
| 10 | −#include "../../util/symbol.h" | |
| 8 | +#include "../../../util/machine.h" | |
| 9 | +#include "../../../util/map.h" | |
| 10 | +#include "../../../util/symbol.h" | |
| 11 | 11 | #include <linux/ctype.h> |
| 12 | 12 | |
| 13 | 13 | #include <symbol/kallsyms.h> |
| @@ -5,10 +5,10 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/kernel.h> |
| 6 | 6 | #include <linux/zalloc.h> |
| 7 | 7 | |
| 8 | −#include "../../perf-sys.h" | |
| 9 | −#include "../../util/perf_regs.h" | |
| 10 | −#include "../../util/debug.h" | |
| 11 | −#include "../../util/event.h" | |
| 8 | +#include "../../../perf-sys.h" | |
| 9 | +#include "../../../util/perf_regs.h" | |
| 10 | +#include "../../../util/debug.h" | |
| 11 | +#include "../../../util/event.h" | |
| 12 | 12 | |
| 13 | 13 | const struct sample_reg sample_reg_masks[] = { |
| 14 | 14 | SMPL_REG(AX, PERF_REG_X86_AX), |
| @@ -4,9 +4,9 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/stddef.h> |
| 5 | 5 | #include <linux/perf_event.h> |
| 6 | 6 | |
| 7 | −#include "../../util/intel-pt.h" | |
| 8 | −#include "../../util/intel-bts.h" | |
| 9 | −#include "../../util/pmu.h" | |
| 7 | +#include "../../../util/intel-pt.h" | |
| 8 | +#include "../../../util/intel-bts.h" | |
| 9 | +#include "../../../util/pmu.h" | |
| 10 | 10 | |
| 11 | 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 | 2 | #ifndef BENCH_H |
| 3 | 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 | 10 | * The madvise transparent hugepage constants were added in glibc |
| 7 | 11 | * 2.13. For compatibility with older versions of glibc, define these |
| @@ -35,7 +35,6 @@ · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | static unsigned int nthreads = 0; |
| 37 | 37 | static unsigned int nsecs = 8; |
| 38 | −struct timeval start, end, runtime; | |
| 39 | 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 | 94 | /* inform all threads that we're done for the day */ |
| 96 | 95 | done = true; |
| 97 | − gettimeofday(&end, NULL); | |
| 98 | − timersub(&end, &start, &runtime); | |
| 96 | + gettimeofday(&bench__end, NULL); | |
| 97 | + timersub(&bench__end, &bench__start, &bench__runtime); | |
| 99 | 98 | } |
| 100 | 99 | |
| 101 | 100 | static void nest_epollfd(void) |
| @@ -313,6 +312,7 @@ int bench_epoll_ctl(int argc, const char **argv) · 211 unmodified lines | ||
| 313 | 312 | exit(EXIT_FAILURE); |
| 314 | 313 | } |
| 315 | 314 | |
| 315 | + memset(&act, 0, sizeof(act)); | |
| 316 | 316 | sigfillset(&act.sa_mask); |
| 317 | 317 | act.sa_sigaction = toggle_done; |
| 318 | 318 | sigaction(SIGINT, &act, NULL); |
| @@ -361,7 +361,7 @@ int bench_epoll_ctl(int argc, const char **argv) · 42 unmodified lines | ||
| 361 | 361 | |
| 362 | 362 | threads_starting = nthreads; |
| 363 | 363 | |
| 364 | − gettimeofday(&start, NULL); | |
| 364 | + gettimeofday(&bench__start, NULL); | |
| 365 | 365 | |
| 366 | 366 | do_threads(worker, cpu); |
| 367 | 367 | |
| @@ -90,7 +90,6 @@ · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | static unsigned int nthreads = 0; |
| 92 | 92 | static unsigned int nsecs = 8; |
| 93 | −struct timeval start, end, runtime; | |
| 94 | 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 | 276 | /* inform all threads that we're done for the day */ |
| 278 | 277 | done = true; |
| 279 | − gettimeofday(&end, NULL); | |
| 280 | − timersub(&end, &start, &runtime); | |
| 278 | + gettimeofday(&bench__end, NULL); | |
| 279 | + timersub(&bench__end, &bench__start, &bench__runtime); | |
| 281 | 280 | } |
| 282 | 281 | |
| 283 | 282 | static void print_summary(void) |
| @@ -287,7 +286,7 @@ static void print_summary(void) · 3 unmodified lines | ||
| 287 | 286 | |
| 288 | 287 | printf("\nAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", |
| 289 | 288 | avg, rel_stddev_stats(stddev, avg), |
| 290 | − (int) runtime.tv_sec); | |
| 289 | + (int)bench__runtime.tv_sec); | |
| 291 | 290 | } |
| 292 | 291 | |
| 293 | 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 | 426 | exit(EXIT_FAILURE); |
| 428 | 427 | } |
| 429 | 428 | |
| 429 | + memset(&act, 0, sizeof(act)); | |
| 430 | 430 | sigfillset(&act.sa_mask); |
| 431 | 431 | act.sa_sigaction = toggle_done; |
| 432 | 432 | sigaction(SIGINT, &act, NULL); |
| @@ -479,7 +479,7 @@ int bench_epoll_wait(int argc, const char **argv) · 46 unmodified lines | ||
| 479 | 479 | |
| 480 | 480 | threads_starting = nthreads; |
| 481 | 481 | |
| 482 | − gettimeofday(&start, NULL); | |
| 482 | + gettimeofday(&bench__start, NULL); | |
| 483 | 483 | |
| 484 | 484 | do_threads(worker, cpu); |
| 485 | 485 | |
| @@ -519,7 +519,7 @@ int bench_epoll_wait(int argc, const char **argv) · 33 unmodified lines | ||
| 519 | 519 | qsort(worker, nthreads, sizeof(struct worker), cmpworker); |
| 520 | 520 | |
| 521 | 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 | 524 | update_stats(&throughput_stats, t); |
| 525 | 525 | |
| @@ -37,7 +37,7 @@ static unsigned int nfutexes = 1024; · 36 unmodified lines | ||
| 37 | 37 | static bool fshared = false, done = false, silent = false; |
| 38 | 38 | static int futex_flag = 0; |
| 39 | 39 | |
| 40 | −struct timeval start, end, runtime; | |
| 40 | +struct timeval bench__start, bench__end, bench__runtime; | |
| 41 | 41 | static pthread_mutex_t thread_lock; |
| 42 | 42 | static unsigned int threads_starting; |
| 43 | 43 | static struct stats throughput_stats; |
| @@ -103,8 +103,8 @@ static void toggle_done(int sig __maybe_unused, · 59 unmodified lines | ||
| 103 | 103 | { |
| 104 | 104 | /* inform all threads that we're done for the day */ |
| 105 | 105 | done = true; |
| 106 | − gettimeofday(&end, NULL); | |
| 107 | − timersub(&end, &start, &runtime); | |
| 106 | + gettimeofday(&bench__end, NULL); | |
| 107 | + timersub(&bench__end, &bench__start, &bench__runtime); | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | static void print_summary(void) |
| @@ -114,7 +114,7 @@ static void print_summary(void) · 3 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", |
| 116 | 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 | 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 | 137 | if (!cpu) |
| 138 | 138 | goto errmem; |
| 139 | 139 | |
| 140 | + memset(&act, 0, sizeof(act)); | |
| 140 | 141 | sigfillset(&act.sa_mask); |
| 141 | 142 | act.sa_sigaction = toggle_done; |
| 142 | 143 | sigaction(SIGINT, &act, NULL); |
| @@ -161,7 +162,7 @@ int bench_futex_hash(int argc, const char **argv) · 18 unmodified lines | ||
| 161 | 162 | |
| 162 | 163 | threads_starting = nthreads; |
| 163 | 164 | pthread_attr_init(&thread_attr); |
| 164 | − gettimeofday(&start, NULL); | |
| 165 | + gettimeofday(&bench__start, NULL); | |
| 165 | 166 | for (i = 0; i < nthreads; i++) { |
| 166 | 167 | worker[i].tid = i; |
| 167 | 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 | 205 | pthread_mutex_destroy(&thread_lock); |
| 205 | 206 | |
| 206 | 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 | 209 | update_stats(&throughput_stats, t); |
| 209 | 210 | if (!silent) { |
| 210 | 211 | if (nfutexes == 1) |
| @@ -37,7 +37,6 @@ static bool silent = false, multi = false; · 36 unmodified lines | ||
| 37 | 37 | static bool done = false, fshared = false; |
| 38 | 38 | static unsigned int nthreads = 0; |
| 39 | 39 | static int futex_flag = 0; |
| 40 | −struct timeval start, end, runtime; | |
| 41 | 40 | static pthread_mutex_t thread_lock; |
| 42 | 41 | static unsigned int threads_starting; |
| 43 | 42 | static struct stats throughput_stats; |
| @@ -64,7 +63,7 @@ static void print_summary(void) · 20 unmodified lines | ||
| 64 | 63 | |
| 65 | 64 | printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", |
| 66 | 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 | 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 | 73 | /* inform all threads that we're done for the day */ |
| 75 | 74 | done = true; |
| 76 | − gettimeofday(&end, NULL); | |
| 77 | − timersub(&end, &start, &runtime); | |
| 75 | + gettimeofday(&bench__end, NULL); | |
| 76 | + timersub(&bench__end, &bench__start, &bench__runtime); | |
| 78 | 77 | } |
| 79 | 78 | |
| 80 | 79 | static void *workerfn(void *arg) |
| @@ -161,6 +160,7 @@ int bench_futex_lock_pi(int argc, const char **argv) · 80 unmodified lines | ||
| 161 | 160 | if (!cpu) |
| 162 | 161 | err(EXIT_FAILURE, "calloc"); |
| 163 | 162 | |
| 163 | + memset(&act, 0, sizeof(act)); | |
| 164 | 164 | sigfillset(&act.sa_mask); |
| 165 | 165 | act.sa_sigaction = toggle_done; |
| 166 | 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 | 186 | threads_starting = nthreads; |
| 187 | 187 | pthread_attr_init(&thread_attr); |
| 188 | − gettimeofday(&start, NULL); | |
| 188 | + gettimeofday(&bench__start, NULL); | |
| 189 | 189 | |
| 190 | 190 | create_threads(worker, thread_attr, cpu); |
| 191 | 191 | pthread_attr_destroy(&thread_attr); |
| @@ -211,7 +211,7 @@ int bench_futex_lock_pi(int argc, const char **argv) · 19 unmodified lines | ||
| 211 | 211 | pthread_mutex_destroy(&thread_lock); |
| 212 | 212 | |
| 213 | 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 | 216 | update_stats(&throughput_stats, t); |
| 217 | 217 | if (!silent) |
| @@ -128,6 +128,7 @@ int bench_futex_requeue(int argc, const char **argv) · 127 unmodified lines | ||
| 128 | 128 | if (!cpu) |
| 129 | 129 | err(EXIT_FAILURE, "cpu_map__new"); |
| 130 | 130 | |
| 131 | + memset(&act, 0, sizeof(act)); | |
| 131 | 132 | sigfillset(&act.sa_mask); |
| 132 | 133 | act.sa_sigaction = toggle_done; |
| 133 | 134 | sigaction(SIGINT, &act, NULL); |
| @@ -234,6 +234,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) · 233 unmodified lines | ||
| 234 | 234 | exit(EXIT_FAILURE); |
| 235 | 235 | } |
| 236 | 236 | |
| 237 | + memset(&act, 0, sizeof(act)); | |
| 237 | 238 | sigfillset(&act.sa_mask); |
| 238 | 239 | act.sa_sigaction = toggle_done; |
| 239 | 240 | sigaction(SIGINT, &act, NULL); |
| @@ -43,7 +43,7 @@ static bool done = false, silent = false, fshared = false; · 42 unmodified lines | ||
| 43 | 43 | static pthread_mutex_t thread_lock; |
| 44 | 44 | static pthread_cond_t thread_parent, thread_worker; |
| 45 | 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 | 47 | static int futex_flag = 0; |
| 48 | 48 | |
| 49 | 49 | static const struct option options[] = { |
| @@ -136,12 +136,13 @@ int bench_futex_wake(int argc, const char **argv) · 86 unmodified lines | ||
| 136 | 136 | if (!cpu) |
| 137 | 137 | err(EXIT_FAILURE, "calloc"); |
| 138 | 138 | |
| 139 | + memset(&act, 0, sizeof(act)); | |
| 139 | 140 | sigfillset(&act.sa_mask); |
| 140 | 141 | act.sa_sigaction = toggle_done; |
| 141 | 142 | sigaction(SIGINT, &act, NULL); |
| 142 | 143 | |
| 143 | 144 | if (!nthreads) |
| 144 | − nthreads = ncpus; | |
| 145 | + nthreads = cpu->nr; | |
| 145 | 146 | |
| 146 | 147 | worker = calloc(nthreads, sizeof(*worker)); |
| 147 | 148 | if (!worker) |
| @@ -1312,7 +1312,8 @@ static int cycles_printf(struct hist_entry *he, struct hist_entry *pair, · 1311 unmodified lines | ||
| 1312 | 1312 | end_line = map__srcline(he->ms.map, bi->sym->start + bi->end, |
| 1313 | 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 | 1317 | scnprintf(buf, sizeof(buf), "[%s -> %s] %4ld", |
| 1317 | 1318 | start_line, end_line, block_he->diff.cycles); |
| 1318 | 1319 | } else { |
| @@ -684,7 +684,9 @@ repeat: · 683 unmodified lines | ||
| 684 | 684 | delay_msecs = top->delay_secs * MSEC_PER_SEC; |
| 685 | 685 | set_term_quiet_input(&save); |
| 686 | 686 | /* trash return*/ |
| 687 | − getc(stdin); | |
| 687 | + clearerr(stdin); | |
| 688 | + if (poll(&stdin_poll, 1, 0) > 0) | |
| 689 | + getc(stdin); | |
| 688 | 690 | |
| 689 | 691 | while (!done) { |
| 690 | 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 | 1083 | int main(int argc, char *argv[]) |
| 1084 | 1084 | { |
| 1085 | − int rc; | |
| 1085 | + int rc, ret = 0; | |
| 1086 | 1086 | int maxfds; |
| 1087 | 1087 | char ldirname[PATH_MAX]; |
| 1088 | − | |
| 1089 | 1088 | const char *arch; |
| 1090 | 1089 | const char *output_file; |
| 1091 | 1090 | const char *start_dirname; |
| @@ -1156,7 +1155,8 @@ int main(int argc, char *argv[]) · 64 unmodified lines | ||
| 1156 | 1155 | /* Make build fail */ |
| 1157 | 1156 | fclose(eventsfp); |
| 1158 | 1157 | free_arch_std_events(); |
| 1159 | − return 1; | |
| 1158 | + ret = 1; | |
| 1159 | + goto out_free_mapfile; | |
| 1160 | 1160 | } else if (rc) { |
| 1161 | 1161 | goto empty_map; |
| 1162 | 1162 | } |
| @@ -1174,14 +1174,17 @@ int main(int argc, char *argv[]) · 11 unmodified lines | ||
| 1174 | 1174 | /* Make build fail */ |
| 1175 | 1175 | fclose(eventsfp); |
| 1176 | 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 | 1183 | empty_map: |
| 1183 | 1184 | fclose(eventsfp); |
| 1184 | 1185 | create_empty_mapping(output_file); |
| 1185 | 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 | 19 | #include "../perf-sys.h" |
| 20 | 20 | #include "cloexec.h" |
| 21 | 21 | |
| 22 | −volatile long the_var; | |
| 22 | +static volatile long the_var; | |
| 23 | 23 | |
| 24 | 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 | 295 | end_line = map__srcline(he->ms.map, bi->sym->start + bi->end, |
| 296 | 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 | 300 | scnprintf(buf, sizeof(buf), "[%s -> %s]", |
| 300 | 301 | start_line, end_line); |
| 301 | 302 | } else { |
| @@ -343,11 +343,11 @@ static const char *normalize_arch(char *arch) · 342 unmodified lines | ||
| 343 | 343 | |
| 344 | 344 | const char *perf_env__arch(struct perf_env *env) |
| 345 | 345 | { |
| 346 | − struct utsname uts; | |
| 347 | 346 | char *arch_name; |
| 348 | 347 | |
| 349 | 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 | 351 | return NULL; |
| 352 | 352 | arch_name = uts.machine; |
| 353 | 353 | } else |
| @@ -89,7 +89,7 @@ static inline bool replace_android_lib(const char *filename, char *newfilename) · 88 unmodified lines | ||
| 89 | 89 | return true; |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | − if (!strncmp(filename, "/system/lib/", 11)) { | |
| 92 | + if (!strncmp(filename, "/system/lib/", 12)) { | |
| 93 | 93 | char *ndk, *app; |
| 94 | 94 | const char *arch; |
| 95 | 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 | 432 | if (map && map->dso) { |
| 433 | 433 | char *srcline = map__srcline(map, addr, NULL); |
| 434 | − if (srcline != SRCLINE_UNKNOWN) | |
| 434 | + if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) | |
| 435 | 435 | ret = fprintf(fp, "%s%s", prefix, srcline); |
| 436 | 436 | free_srcline(srcline); |
| 437 | 437 | } |
| @@ -257,21 +257,15 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) · 256 unmodified lines | ||
| 257 | 257 | path = zalloc(sizeof(*path)); |
| 258 | 258 | if (!path) |
| 259 | 259 | return NULL; |
| 260 | − path->system = malloc(MAX_EVENT_LENGTH); | |
| 261 | − if (!path->system) { | |
| 260 | + if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { | |
| 262 | 261 | free(path); |
| 263 | 262 | return NULL; |
| 264 | 263 | } |
| 265 | − path->name = malloc(MAX_EVENT_LENGTH); | |
| 266 | − if (!path->name) { | |
| 264 | + if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { | |
| 267 | 265 | zfree(&path->system); |
| 268 | 266 | free(path); |
| 269 | 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 | 269 | return path; |
| 276 | 270 | } |
| 277 | 271 | } |
| @@ -1219,7 +1213,7 @@ static int config_attr(struct perf_event_attr *attr, · 941 unmodified lines | ||
| 1219 | 1213 | static int get_config_terms(struct list_head *head_config, |
| 1220 | 1214 | struct list_head *head_terms __maybe_unused) |
| 1221 | 1215 | { |
| 1222 | −#define ADD_CONFIG_TERM(__type) \ | |
| 1216 | +#define ADD_CONFIG_TERM(__type, __weak) \ | |
| 1223 | 1217 | struct perf_evsel_config_term *__t; \ |
| 1224 | 1218 | \ |
| 1225 | 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 | 1223 | INIT_LIST_HEAD(&__t->list); \ |
| 1230 | 1224 | __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ |
| 1231 | − __t->weak = term->weak; \ | |
| 1225 | + __t->weak = __weak; \ | |
| 1232 | 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 | 1229 | do { \ |
| 1236 | − ADD_CONFIG_TERM(__type); \ | |
| 1230 | + ADD_CONFIG_TERM(__type, __weak); \ | |
| 1237 | 1231 | __t->val.__name = __val; \ |
| 1238 | 1232 | } while (0) |
| 1239 | 1233 | |
| 1240 | −#define ADD_CONFIG_TERM_STR(__type, __val) \ | |
| 1234 | +#define ADD_CONFIG_TERM_STR(__type, __val, __weak) \ | |
| 1241 | 1235 | do { \ |
| 1242 | − ADD_CONFIG_TERM(__type); \ | |
| 1236 | + ADD_CONFIG_TERM(__type, __weak); \ | |
| 1243 | 1237 | __t->val.str = strdup(__val); \ |
| 1244 | 1238 | if (!__t->val.str) { \ |
| 1245 | 1239 | zfree(&__t); \ |
| @@ -1253,62 +1247,62 @@ do { \ · 7 unmodified lines | ||
| 1253 | 1247 | list_for_each_entry(term, head_config, list) { |
| 1254 | 1248 | switch (term->type_term) { |
| 1255 | 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 | 1251 | break; |
| 1258 | 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 | 1254 | break; |
| 1261 | 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 | 1257 | break; |
| 1264 | 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 | 1260 | break; |
| 1267 | 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 | 1263 | break; |
| 1270 | 1264 | case PARSE_EVENTS__TERM_TYPE_STACKSIZE: |
| 1271 | 1265 | ADD_CONFIG_TERM_VAL(STACK_USER, stack_user, |
| 1272 | − term->val.num); | |
| 1266 | + term->val.num, term->weak); | |
| 1273 | 1267 | break; |
| 1274 | 1268 | case PARSE_EVENTS__TERM_TYPE_INHERIT: |
| 1275 | 1269 | ADD_CONFIG_TERM_VAL(INHERIT, inherit, |
| 1276 | − term->val.num ? 1 : 0); | |
| 1270 | + term->val.num ? 1 : 0, term->weak); | |
| 1277 | 1271 | break; |
| 1278 | 1272 | case PARSE_EVENTS__TERM_TYPE_NOINHERIT: |
| 1279 | 1273 | ADD_CONFIG_TERM_VAL(INHERIT, inherit, |
| 1280 | − term->val.num ? 0 : 1); | |
| 1274 | + term->val.num ? 0 : 1, term->weak); | |
| 1281 | 1275 | break; |
| 1282 | 1276 | case PARSE_EVENTS__TERM_TYPE_MAX_STACK: |
| 1283 | 1277 | ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack, |
| 1284 | − term->val.num); | |
| 1278 | + term->val.num, term->weak); | |
| 1285 | 1279 | break; |
| 1286 | 1280 | case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: |
| 1287 | 1281 | ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events, |
| 1288 | − term->val.num); | |
| 1282 | + term->val.num, term->weak); | |
| 1289 | 1283 | break; |
| 1290 | 1284 | case PARSE_EVENTS__TERM_TYPE_OVERWRITE: |
| 1291 | 1285 | ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, |
| 1292 | − term->val.num ? 1 : 0); | |
| 1286 | + term->val.num ? 1 : 0, term->weak); | |
| 1293 | 1287 | break; |
| 1294 | 1288 | case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: |
| 1295 | 1289 | ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, |
| 1296 | − term->val.num ? 0 : 1); | |
| 1290 | + term->val.num ? 0 : 1, term->weak); | |
| 1297 | 1291 | break; |
| 1298 | 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 | 1294 | break; |
| 1301 | 1295 | case PARSE_EVENTS__TERM_TYPE_PERCORE: |
| 1302 | 1296 | ADD_CONFIG_TERM_VAL(PERCORE, percore, |
| 1303 | − term->val.num ? true : false); | |
| 1297 | + term->val.num ? true : false, term->weak); | |
| 1304 | 1298 | break; |
| 1305 | 1299 | case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: |
| 1306 | 1300 | ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output, |
| 1307 | − term->val.num ? 1 : 0); | |
| 1301 | + term->val.num ? 1 : 0, term->weak); | |
| 1308 | 1302 | break; |
| 1309 | 1303 | case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: |
| 1310 | 1304 | ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size, |
| 1311 | − term->val.num); | |
| 1305 | + term->val.num, term->weak); | |
| 1312 | 1306 | break; |
| 1313 | 1307 | default: |
| 1314 | 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 | 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 | 1344 | #undef ADD_CONFIG_TERM |
| 1351 | 1345 | return 0; |
| @@ -206,6 +206,9 @@ static struct strlist *__probe_file__get_namelist(int fd, bool include_group) · 205 unmodified lines | ||
| 206 | 206 | } else |
| 207 | 207 | ret = strlist__add(sl, tev.event); |
| 208 | 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 | 212 | if (ret < 0) |
| 210 | 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 | 637 | return -EINVAL; |
| 638 | 638 | } |
| 639 | 639 | |
| 640 | − /* Try to get actual symbol name from symtab */ | |
| 641 | − symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); | |
| 640 | + if (dwarf_entrypc(sp_die, &eaddr) == 0) { | |
| 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 | 648 | if (!symbol) { |
| 643 | 649 | pr_warning("Failed to find symbol at 0x%lx\n", |
| 644 | 650 | (unsigned long)paddr); |
| 645 | 651 | return -ENOENT; |
| 646 | 652 | } |
| 647 | − eaddr = sym.st_value; | |
| 648 | 653 | |
| 649 | 654 | tp->offset = (unsigned long)(paddr - eaddr); |
| 650 | 655 | tp->address = (unsigned long)paddr; |
| @@ -2,11 +2,13 @@ from os import getenv · 1 unmodified line | ||
| 2 | 2 | from subprocess import Popen, PIPE |
| 3 | 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 | 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") | |
| 9 | −if cc == "clang": | |
| 11 | +if cc_is_clang: | |
| 10 | 12 | from distutils.sysconfig import get_config_vars |
| 11 | 13 | vars = get_config_vars() |
| 12 | 14 | for var in ('CFLAGS', 'OPT'): |
| @@ -40,7 +42,7 @@ class install_lib(_install_lib): · 27 unmodified lines | ||
| 40 | 42 | cflags = getenv('CFLAGS', '').split() |
| 41 | 43 | # switch off several checks (need to be at the end of cflags list) |
| 42 | 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 | 46 | cflags += ['-Wno-cast-function-type' ] |
| 45 | 47 | |
| 46 | 48 | src_perf = getenv('srctree') + '/tools/perf' |
| @@ -1622,7 +1622,12 @@ int dso__load(struct dso *dso, struct map *map) · 1621 unmodified lines | ||
| 1622 | 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 | 1631 | if (dso->kernel == DSO_TYPE_KERNEL) |
| 1627 | 1632 | ret = dso__load_kernel_sym(dso, map); |
| 1628 | 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 | 1655 | if (!name) |
| 1651 | 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 | 1659 | * Read the build id if possible. This is required for |
| 1661 | 1660 | * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work |
| @@ -82,7 +82,7 @@ static struct pci_access *pci_acc; · 81 unmodified lines | ||
| 82 | 82 | static struct pci_dev *amd_fam14h_pci_dev; |
| 83 | 83 | static int nbp1_entered; |
| 84 | 84 | |
| 85 | −struct timespec start_time; | |
| 85 | +static struct timespec start_time; | |
| 86 | 86 | static unsigned long long timediff; |
| 87 | 87 | |
| 88 | 88 | #ifdef DEBUG |
| @@ -19,7 +19,7 @@ struct cpuidle_monitor cpuidle_sysfs_monitor; · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | static unsigned long long **previous_count; |
| 21 | 21 | static unsigned long long **current_count; |
| 22 | −struct timespec start_time; | |
| 22 | +static struct timespec start_time; | |
| 23 | 23 | static unsigned long long timediff; |
| 24 | 24 | |
| 25 | 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 | 27 | 0 |
| 28 | 28 | }; |
| 29 | 29 | |
| 30 | +int cpu_count; | |
| 31 | + | |
| 30 | 32 | static struct cpuidle_monitor *monitors[MONITORS_MAX]; |
| 31 | 33 | static unsigned int avail_monitors; |
| 32 | 34 | |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #endif |
| 26 | 26 | #define CSTATE_DESC_LEN 60 |
| 27 | 27 | |
| 28 | −int cpu_count; | |
| 28 | +extern int cpu_count; | |
| 29 | 29 | |
| 30 | 30 | /* Hard to define the right names ...: */ |
| 31 | 31 | enum power_range_e { |
| @@ -16,7 +16,7 @@ override CFLAGS += -D_FORTIFY_SOURCE=2 · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | %: %.c |
| 18 | 18 | @mkdir -p $(BUILD_OUTPUT) |
| 19 | − $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) | |
| 19 | + $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) -lcap | |
| 20 | 20 | |
| 21 | 21 | .PHONY : clean |
| 22 | 22 | clean : |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include <sched.h> |
| 31 | 31 | #include <time.h> |
| 32 | 32 | #include <cpuid.h> |
| 33 | −#include <linux/capability.h> | |
| 33 | +#include <sys/capability.h> | |
| 34 | 34 | #include <errno.h> |
| 35 | 35 | #include <math.h> |
| 36 | 36 | |
| @@ -304,6 +304,10 @@ int *irqs_per_cpu; /* indexed by cpu_num */ · 267 unmodified lines | ||
| 304 | 304 | |
| 305 | 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 | 311 | int cpu_is_not_present(int cpu) |
| 308 | 312 | { |
| 309 | 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 | 2921 | * record snapshot of |
| 2918 | 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 | 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 | 2944 | * snapshot_sys_lpi() |
| 2943 | 2945 | * |
| 2944 | − * record snapshot of | |
| 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 | |
| 2946 | + * record snapshot of sys_lpi_file | |
| 2948 | 2947 | */ |
| 2949 | 2948 | int snapshot_sys_lpi_us(void) |
| 2950 | 2949 | { |
| 2951 | 2950 | FILE *fp; |
| 2952 | 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 | 2955 | retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); |
| 2957 | 2956 | if (retval != 1) { |
| @@ -3151,28 +3150,42 @@ void check_dev_msr() · 193 unmodified lines | ||
| 3151 | 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; | |
| 3157 | − cap_user_header_t cap_header = &cap_header_data; | |
| 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]; | |
| 3160 | + cap_t caps; | |
| 3161 | + cap_flag_value_t cap_flag_value; | |
| 3163 | 3162 | |
| 3164 | − /* check for CAP_SYS_RAWIO */ | |
| 3165 | − cap_header->pid = getpid(); | |
| 3166 | − cap_header->version = _LINUX_CAPABILITY_VERSION; | |
| 3167 | − if (capget(cap_header, cap_data) < 0) | |
| 3168 | − err(-6, "capget(2) failed"); | |
| 3163 | + caps = cap_get_proc(); | |
| 3164 | + if (caps == NULL) | |
| 3165 | + err(-6, "cap_get_proc\n"); | |
| 3169 | 3166 | |
| 3170 | − if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { | |
| 3171 | − do_exit++; | |
| 3167 | + if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value)) | |
| 3168 | + err(-6, "cap_get\n"); | |
| 3169 | + | |
| 3170 | + if (cap_flag_value != CAP_SET) { | |
| 3172 | 3171 | warnx("capget(CAP_SYS_RAWIO) failed," |
| 3173 | 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 | 3189 | /* test file permissions */ |
| 3177 | 3190 | sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); |
| 3178 | 3191 | if (euidaccess(pathname, R_OK)) { |
| @@ -3265,6 +3278,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) · 86 unmodified lines | ||
| 3265 | 3278 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
| 3266 | 3279 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
| 3267 | 3280 | case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
| 3281 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | |
| 3268 | 3282 | pkg_cstate_limits = glm_pkg_cstate_limits; |
| 3269 | 3283 | break; |
| 3270 | 3284 | default: |
| @@ -3336,6 +3350,17 @@ int is_skx(unsigned int family, unsigned int model) · 65 unmodified lines | ||
| 3336 | 3350 | } |
| 3337 | 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 | 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 | 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 | 3523 | static void |
| 3482 | 3524 | dump_sysfs_cstate_config(void) |
| 3483 | 3525 | { |
| @@ -3491,6 +3533,15 @@ dump_sysfs_cstate_config(void) · 7 unmodified lines | ||
| 3491 | 3533 | if (!DO_BIC(BIC_sysfs)) |
| 3492 | 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 | 3545 | for (state = 0; state < 10; ++state) { |
| 3495 | 3546 | |
| 3496 | 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 | 3945 | else |
| 3895 | 3946 | BIC_PRESENT(BIC_PkgWatt); |
| 3896 | 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 | 3962 | case INTEL_FAM6_SKYLAKE_L: /* SKL */ |
| 3898 | 3963 | case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
| 3899 | 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 | 4360 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
| 4296 | 4361 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
| 4297 | 4362 | case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ |
| 4363 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | |
| 4298 | 4364 | return 1; |
| 4299 | 4365 | } |
| 4300 | 4366 | return 0; |
| @@ -4324,6 +4390,7 @@ int has_c8910_msrs(unsigned int family, unsigned int model) · 23 unmodified lines | ||
| 4324 | 4390 | case INTEL_FAM6_CANNONLAKE_L: /* CNL */ |
| 4325 | 4391 | case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ |
| 4326 | 4392 | case INTEL_FAM6_ATOM_GOLDMONT_PLUS: |
| 4393 | + case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | |
| 4327 | 4394 | return 1; |
| 4328 | 4395 | } |
| 4329 | 4396 | return 0; |
| @@ -4610,14 +4677,24 @@ unsigned int intel_model_duplicates(unsigned int model) · 280 unmodified lines | ||
| 4610 | 4677 | case INTEL_FAM6_SKYLAKE: |
| 4611 | 4678 | case INTEL_FAM6_KABYLAKE_L: |
| 4612 | 4679 | case INTEL_FAM6_KABYLAKE: |
| 4680 | + case INTEL_FAM6_COMETLAKE_L: | |
| 4681 | + case INTEL_FAM6_COMETLAKE: | |
| 4613 | 4682 | return INTEL_FAM6_SKYLAKE_L; |
| 4614 | 4683 | |
| 4615 | 4684 | case INTEL_FAM6_ICELAKE_L: |
| 4616 | 4685 | case INTEL_FAM6_ICELAKE_NNPI: |
| 4686 | + case INTEL_FAM6_TIGERLAKE_L: | |
| 4687 | + case INTEL_FAM6_TIGERLAKE: | |
| 4617 | 4688 | return INTEL_FAM6_CANNONLAKE_L; |
| 4618 | 4689 | |
| 4619 | 4690 | case INTEL_FAM6_ATOM_TREMONT_D: |
| 4620 | 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 | 4699 | return model; |
| 4623 | 4700 | } |
| @@ -4872,7 +4949,8 @@ void process_cpuid() · 248 unmodified lines | ||
| 4872 | 4949 | do_slm_cstates = is_slm(family, model); |
| 4873 | 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 | 4954 | BIC_NOT_PRESENT(BIC_CPU_c3); |
| 4877 | 4955 | |
| 4878 | 4956 | if (!quiet) |
| @@ -4907,10 +4985,16 @@ void process_cpuid() · 28 unmodified lines | ||
| 4907 | 4985 | else |
| 4908 | 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 | 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 | 4996 | BIC_NOT_PRESENT(BIC_SYS_LPI); |
| 4997 | + } | |
| 4914 | 4998 | |
| 4915 | 4999 | if (!quiet) |
| 4916 | 5000 | decode_misc_feature_control(); |
| @@ -5306,7 +5390,7 @@ int get_and_dump_counters(void) · 389 unmodified lines | ||
| 5306 | 5390 | } |
| 5307 | 5391 | |
| 5308 | 5392 | void print_version() { |
| 5309 | − fprintf(outf, "turbostat version 19.08.31" | |
| 5393 | + fprintf(outf, "turbostat version 20.03.20" | |
| 5310 | 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 | 5409 | msrp->msr_num = msr_num; |
| 5326 | − strncpy(msrp->name, name, NAME_BYTES); | |
| 5410 | + strncpy(msrp->name, name, NAME_BYTES - 1); | |
| 5327 | 5411 | if (path) |
| 5328 | − strncpy(msrp->path, path, PATH_BYTES); | |
| 5412 | + strncpy(msrp->path, path, PATH_BYTES - 1); | |
| 5329 | 5413 | msrp->width = width; |
| 5330 | 5414 | msrp->type = type; |
| 5331 | 5415 | msrp->format = format; |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | ifneq ($(O),) |
| 3 | 3 | ifeq ($(origin O), command line) |
| 4 | − dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) | |
| 5 | − ABSOLUTE_O := $(shell cd $(O) ; pwd) | |
| 4 | + dummy := $(if $(shell cd $(PWD); test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) | |
| 5 | + ABSOLUTE_O := $(shell cd $(PWD); cd $(O) ; pwd) | |
| 6 | 6 | OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) |
| 7 | 7 | COMMAND_O := O=$(ABSOLUTE_O) |
| 8 | 8 | ifeq ($(objtree),) |
| @@ -33,6 +33,7 @@ TARGETS += memory-hotplug · 32 unmodified lines | ||
| 33 | 33 | TARGETS += mount |
| 34 | 34 | TARGETS += mqueue |
| 35 | 35 | TARGETS += net |
| 36 | +TARGETS += net/forwarding | |
| 36 | 37 | TARGETS += net/mptcp |
| 37 | 38 | TARGETS += netfilter |
| 38 | 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 | 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 | 40 | SEC("perf_event") |
| 35 | 41 | int send_signal_perf(void *ctx) |
| 36 | 42 | { |
| @@ -1062,6 +1062,48 @@ static struct btf_raw_test raw_tests[] = { · 1061 unmodified lines | ||
| 1062 | 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 | 1107 | /* typedef const void * const_void_ptr; |
| 1066 | 1108 | * struct A { |
| 1067 | 1109 | * const_void_ptr m; |
| @@ -61,6 +61,21 @@ · 60 unmodified lines | ||
| 61 | 61 | }, |
| 62 | 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 | 80 | "jset32: min/max deduction", |
| 66 | 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 | 11 | TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh |
| 12 | 12 | TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh |
| 13 | 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 | 17 | TEST_PROGS += reuseaddr_ports_exhausted.sh |
| 16 | 18 | TEST_PROGS_EXTENDED := in_netns.sh |
| 17 | 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 | 21 | #include <sys/socket.h> |
| 22 | 22 | #include <unistd.h> |
| 23 | 23 | |
| 24 | +#ifndef SOL_DCCP | |
| 25 | +#define SOL_DCCP 269 | |
| 26 | +#endif | |
| 27 | + | |
| 24 | 28 | static const char *IP4_ADDR = "127.0.0.1"; |
| 25 | 29 | static const char *IP6_ADDR = "::1"; |
| 26 | 30 | static const char *IP4_MAPPED6 = "::ffff:127.0.0.1"; |
| @@ -3,6 +3,10 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh \ |
| 5 | 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 | 12 | include ../lib.mk |
| @@ -1,2 +1,8 @@ | ||
| 1 | 1 | CONFIG_NET_NS=y |
| 2 | 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 | 527 | n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75 |
| 528 | 528 | n0 wg set wg0 peer "$pub2" allowed-ips ::/0 |
| 529 | 529 | n0 wg set wg0 peer "$pub2" remove |
| 530 | −low_order_points=( AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38= ) | |
| 531 | −n0 wg set wg0 private-key /dev/null ${low_order_points[@]/#/peer } | |
| 532 | −[[ -z $(n0 wg show wg0 peers) ]] | |
| 533 | −n0 wg set wg0 private-key <(echo "$key1") ${low_order_points[@]/#/peer } | |
| 534 | −[[ -z $(n0 wg show wg0 peers) ]] | |
| 530 | +for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do | |
| 531 | + n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111 | |
| 532 | +done | |
| 533 | +[[ -n $(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 | 540 | ip0 link del wg0 |
| 536 | 541 | |
| 537 | 542 | declare -A objects |
| @@ -41,7 +41,7 @@ $(DISTFILES_PATH)/$(1): · 40 unmodified lines | ||
| 41 | 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 | 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 | 45 | $(eval $(call tar_download,IPERF,iperf,3.7,.tar.gz,https://downloads.es.net/pub/iperf/,d846040224317caf2f75c843d309a950a7db23f9b44b94688ccbe557d6d1710c)) |
| 46 | 46 | $(eval $(call tar_download,BASH,bash,5.0,.tar.gz,https://ftp.gnu.org/gnu/bash/,b4a80f2ac66170b2913efbfb9f2594f1f76c7b1afd11f799e22035d63077fb4d)) |
| 47 | 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 | 13 | #include <fcntl.h> |
| 14 | 14 | #include <sys/wait.h> |
| 15 | 15 | #include <sys/mount.h> |
| 16 | −#include <sys/types.h> | |
| 17 | 16 | #include <sys/stat.h> |
| 18 | 17 | #include <sys/types.h> |
| 19 | 18 | #include <sys/io.h> |
| @@ -56,7 +56,6 @@ CONFIG_NO_HZ_IDLE=y · 55 unmodified lines | ||
| 56 | 56 | CONFIG_NO_HZ_FULL=n |
| 57 | 57 | CONFIG_HZ_PERIODIC=n |
| 58 | 58 | CONFIG_HIGH_RES_TIMERS=y |
| 59 | −CONFIG_COMPAT_32BIT_TIME=y | |
| 60 | 59 | CONFIG_ARCH_RANDOM=y |
| 61 | 60 | CONFIG_FILE_LOCKING=y |
| 62 | 61 | CONFIG_POSIX_TIMERS=y |
| @@ -124,17 +124,6 @@ choice · 123 unmodified lines | ||
| 124 | 124 | |
| 125 | 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 | 127 | config INITRAMFS_COMPRESSION_GZIP |
| 139 | 128 | bool "Gzip" |
| 140 | 129 | depends on RD_GZIP |
| @@ -207,4 +196,15 @@ config INITRAMFS_COMPRESSION_LZ4 · 66 unmodified lines | ||
| 207 | 196 | If you choose this, keep in mind that most distros don't provide lz4 |
| 208 | 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 | 210 | endchoice |